Commit 923c8861 authored by npzacs's avatar npzacs
Browse files

Factorize common code

parent 07e540c9
......@@ -273,13 +273,8 @@ static MKB *_get_hrl_mkb(MMC *mmc)
return mkb;
}
static int _read_vid(AACS *aacs, cert_list *hcl)
static int _mmc_read_auth(AACS *aacs, cert_list *hcl, int type, uint8_t *p1, uint8_t *p2)
{
/* Use VID given in config file if available */
if (memcmp(aacs->vid, empty_key, 16)) {
return AACS_SUCCESS;
}
MMC* mmc = NULL;
if (!(mmc = mmc_open(aacs->path))) {
return AACS_ERROR_MMC_OPEN;
......@@ -319,13 +314,11 @@ static int _read_vid(AACS *aacs, cert_list *hcl)
DEBUG(DBG_AACS, "Trying host certificate (id 0x%s)...\n",
print_hex(tmp_str, cert + 4, 6));
int mmc_result = mmc_read_vid(mmc, priv_key, cert, aacs->vid);
int mmc_result = mmc_read_auth(mmc, priv_key, cert, type, p1, p2);
switch (mmc_result) {
case MMC_SUCCESS:
mkb_close(hrl_mkb);
mmc_close(mmc);
/* cache vid */
keycache_save("vid", aacs->disc_id, aacs->vid, 16);
return AACS_SUCCESS;
case MMC_ERROR_CERT_REVOKED:
error_code = AACS_ERROR_CERT_REVOKED;
......@@ -340,107 +333,42 @@ static int _read_vid(AACS *aacs, cert_list *hcl)
mkb_close(hrl_mkb);
mmc_close(mmc);
DEBUG(DBG_AACS, "Error reading VID!\n");
return error_code;
}
static int _read_read_data_key(AACS *aacs, cert_list *hcl)
static int _read_vid(AACS *aacs, cert_list *hcl)
{
MMC* mmc = NULL;
if (!(mmc = mmc_open(aacs->path))) {
return AACS_ERROR_MMC_OPEN;
/* Use VID given in config file if available */
if (memcmp(aacs->vid, empty_key, 16)) {
return AACS_SUCCESS;
}
int error_code = AACS_ERROR_NO_CERT;
for (;hcl && hcl->host_priv_key && hcl->host_cert; hcl = hcl->next) {
char tmp_str[2*92+1];
uint8_t priv_key[20], cert[92];
hexstring_to_hex_array(priv_key, sizeof(priv_key), hcl->host_priv_key);
hexstring_to_hex_array(cert, sizeof(cert), hcl->host_cert);
if (!crypto_aacs_verify_host_cert(cert)) {
DEBUG(DBG_AACS, "Not using invalid host certificate %s.\n",
print_hex(tmp_str, cert, 92));
continue;
}
DEBUG(DBG_AACS, "Trying host certificate (id 0x%s)...\n",
print_hex(tmp_str, cert + 4, 6));
int mmc_result = mmc_read_data_keys(mmc, priv_key, cert, aacs->read_data_key, NULL);
switch (mmc_result) {
case MMC_SUCCESS:
mmc_close(mmc);
return AACS_SUCCESS;
case MMC_ERROR_CERT_REVOKED:
error_code = AACS_ERROR_CERT_REVOKED;
break;
case MMC_ERROR:
default:
error_code = AACS_ERROR_MMC_FAILURE;
break;
}
int error_code = _mmc_read_auth(aacs, hcl, MMC_READ_VID, aacs->vid, NULL);
if (error_code != AACS_SUCCESS) {
DEBUG(DBG_AACS, "Error reading VID!\n");
} else {
/* cache vid */
keycache_save("vid", aacs->disc_id, aacs->vid, 16);
}
mmc_close(mmc);
DEBUG(DBG_AACS, "Error reading read data key!\n");
return error_code;
}
static int _read_pmsn(AACS *aacs, cert_list *hcl)
static int _read_read_data_key(AACS *aacs, cert_list *hcl)
{
MMC* mmc = NULL;
if (!(mmc = mmc_open(aacs->path))) {
return AACS_ERROR_MMC_OPEN;
int error_code = _mmc_read_auth(aacs, hcl, MMC_READ_DATA_KEYS, aacs->read_data_key, NULL);
if (error_code != AACS_SUCCESS) {
DEBUG(DBG_AACS, "Error reading data keys!\n");
}
return error_code;
}
int error_code = AACS_ERROR_NO_CERT;
const uint8_t *drive_cert = mmc_get_drive_cert(mmc);
for (;hcl && hcl->host_priv_key && hcl->host_cert; hcl = hcl->next) {
char tmp_str[2*92+1];
uint8_t priv_key[20], cert[92];
hexstring_to_hex_array(priv_key, sizeof(priv_key), hcl->host_priv_key);
hexstring_to_hex_array(cert, sizeof(cert), hcl->host_cert);
if (!crypto_aacs_verify_host_cert(cert)) {
DEBUG(DBG_AACS, "Not using invalid host certificate %s.\n",
print_hex(tmp_str, cert, 92));
continue;
}
if (drive_cert && (drive_cert[1] & 0x01) && !(cert[1] & 0x01)) {
DEBUG(DBG_AACS, "Certificate (id 0x%s) does not support bus encryption\n",
print_hex(tmp_str, cert + 4, 6));
//continue;
}
DEBUG(DBG_AACS, "Trying host certificate (id 0x%s)...\n",
print_hex(tmp_str, cert + 4, 6));
int mmc_result = mmc_read_pmsn(mmc, priv_key, cert, aacs->pmsn);
switch (mmc_result) {
case MMC_SUCCESS:
mmc_close(mmc);
return AACS_SUCCESS;
case MMC_ERROR_CERT_REVOKED:
error_code = AACS_ERROR_CERT_REVOKED;
break;
case MMC_ERROR:
default:
error_code = AACS_ERROR_MMC_FAILURE;
break;
}
static int _read_pmsn(AACS *aacs, cert_list *hcl)
{
int error_code = _mmc_read_auth(aacs, hcl, MMC_READ_PMSN, aacs->pmsn, NULL);
fprintf(stderr,"pmsn read 2\n");
if (error_code != AACS_SUCCESS) {
DEBUG(DBG_AACS, "Error reading PMSN!\n");
}
mmc_close(mmc);
DEBUG(DBG_AACS, "Error reading PMSN!\n");
return error_code;
}
......
......@@ -1015,6 +1015,10 @@ void mmc_close(MMC *mmc)
}
}
/*
*
*/
static int _verify_signature(const uint8_t *cert, const uint8_t *signature,
const uint8_t *nonce, const uint8_t *point)
{
......@@ -1113,27 +1117,17 @@ static int _mmc_aacs_auth(MMC *mmc, uint8_t agid, const uint8_t *host_priv_key,
return MMC_SUCCESS;
}
int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *vid)
/*
*
*/
static int _read_vid(MMC *mmc, uint8_t agid, const uint8_t *bus_key, uint8_t *vid)
{
uint8_t agid = 0, mac[16], calc_mac[16], bus_key[16];
uint8_t mac[16], calc_mac[16];
char str[512];
int error_code;
DEBUG(DBG_MMC, "Reading VID from drive...\n");
_mmc_invalidate_agids(mmc);
if (!_mmc_report_agid(mmc, &agid)) {
DEBUG(DBG_MMC | DBG_CRIT, "Didn't get AGID from drive\n");
return MMC_ERROR;
}
DEBUG(DBG_MMC, "Got AGID from drive: %d\n", agid);
error_code = _mmc_aacs_auth(mmc, agid, host_priv_key, host_cert, bus_key);
if (error_code) {
return error_code;
}
if (_mmc_read_vid(mmc, agid, vid, mac)) {
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "VID : %s\n", print_hex(str, vid, 16));
......@@ -1146,39 +1140,21 @@ int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cer
DEBUG(DBG_MMC | DBG_CRIT, "VID MAC is incorrect. This means this Volume ID is not correct.\n");
}
_mmc_invalidate_agid(mmc, agid);
return MMC_SUCCESS;
}
DEBUG(DBG_MMC | DBG_CRIT, "Unable to read VID from drive!\n");
_mmc_invalidate_agid(mmc, agid);
return MMC_ERROR;
}
int mmc_read_pmsn(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *pmsn)
static int _read_pmsn(MMC *mmc, uint8_t agid, const uint8_t *bus_key, uint8_t *pmsn)
{
uint8_t agid = 0, mac[16], calc_mac[16], bus_key[16];
uint8_t mac[16], calc_mac[16];
char str[512];
int error_code;
DEBUG(DBG_MMC, "Reading PMSN from drive...\n");
_mmc_invalidate_agids(mmc);
if (!_mmc_report_agid(mmc, &agid)) {
DEBUG(DBG_MMC | DBG_CRIT, "Didn't get AGID from drive\n");
return MMC_ERROR;
}
DEBUG(DBG_MMC, "Got AGID from drive: %d\n", agid);
error_code = _mmc_aacs_auth(mmc, agid, host_priv_key, host_cert, bus_key);
if (error_code) {
return error_code;
}
if (_mmc_read_pmsn(mmc, agid, pmsn, mac)) {
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "PMSN : %s\n", print_hex(str, pmsn, 16));
......@@ -1191,26 +1167,50 @@ int mmc_read_pmsn(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_ce
DEBUG(DBG_MMC | DBG_CRIT, "PMSN MAC is incorrect. This means this Pre-recorded Medial Serial Number is not correct.\n");
}
_mmc_invalidate_agid(mmc, agid);
return MMC_SUCCESS;
}
DEBUG(DBG_MMC | DBG_CRIT, "Unable to read PMSN from drive!\n");
_mmc_invalidate_agid(mmc, agid);
return MMC_ERROR;
}
int mmc_read_data_keys(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *read_data_key, uint8_t *write_data_key)
static int _read_data_keys(MMC *mmc, uint8_t agid, const uint8_t *bus_key,
uint8_t *read_data_key, uint8_t *write_data_key)
{
uint8_t agid = 0, bus_key[16], encrypted_read_data_key[16], encrypted_write_data_key[16];
uint8_t encrypted_read_data_key[16], encrypted_write_data_key[16];
char str[512];
int error_code;
DEBUG(DBG_MMC, "Reading data keys from drive...\n");
if (_mmc_read_data_keys(mmc, agid, encrypted_read_data_key, encrypted_write_data_key)) {
if (read_data_key) {
crypto_aes128d(bus_key, encrypted_read_data_key, read_data_key);
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "READ DATA KEY : %s\n", print_hex(str, read_data_key, 16));
}
}
if (write_data_key) {
crypto_aes128d(bus_key, encrypted_write_data_key, write_data_key);
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "WRITE DATA KEY : %s\n", print_hex(str, write_data_key, 16));
}
}
return MMC_SUCCESS;
}
DEBUG(DBG_MMC | DBG_CRIT, "Unable to read data keys from drive!\n");
return MMC_ERROR;
}
int mmc_read_auth(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert,
int request, uint8_t *p1, uint8_t *p2)
{
uint8_t agid = 0, bus_key[16];
int error_code;
_mmc_invalidate_agids(mmc);
if (!_mmc_report_agid(mmc, &agid)) {
......@@ -1226,35 +1226,35 @@ int mmc_read_data_keys(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *ho
error_code = _mmc_aacs_auth(mmc, agid, host_priv_key, host_cert, bus_key);
if (error_code) {
_mmc_invalidate_agid(mmc, agid);
return error_code;
}
if (_mmc_read_data_keys(mmc, agid, encrypted_read_data_key, encrypted_write_data_key)) {
if (read_data_key) {
crypto_aes128d(bus_key, encrypted_read_data_key, read_data_key);
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "READ DATA KEY : %s\n", print_hex(str, read_data_key, 16));
}
}
if (write_data_key) {
crypto_aes128d(bus_key, encrypted_write_data_key, write_data_key);
if (DEBUG_KEYS) {
DEBUG(DBG_MMC, "WRITE DATA KEY : %s\n", print_hex(str, write_data_key, 16));
}
}
_mmc_invalidate_agid(mmc, agid);
return MMC_SUCCESS;
switch (request) {
case MMC_READ_VID:
error_code = _read_vid(mmc, agid, bus_key, p1);
break;
case MMC_READ_PMSN:
error_code = _read_pmsn(mmc, agid, bus_key, p1);
break;
case MMC_READ_DATA_KEYS:
error_code = _read_data_keys(mmc, agid, bus_key, p1, p2);
break;
default:
DEBUG(DBG_MMC | DBG_CRIT, "unknown mmc_read_auth() request %d\n", request);
error_code = MMC_ERROR;
break;
}
DEBUG(DBG_MMC | DBG_CRIT, "Unable to read data keys from drive!\n");
_mmc_invalidate_agid(mmc, agid);
return MMC_ERROR;
return error_code;
}
/*
*
*/
int mmc_read_drive_cert(MMC *mmc, uint8_t *drive_cert)
{
uint8_t buf[116];
......
......@@ -31,14 +31,14 @@ typedef struct mmc MMC;
#define MMC_ERROR -1 /* MMC failed */
#define MMC_ERROR_CERT_REVOKED -2 /* revoked certificate */
#define MMC_READ_VID 0
#define MMC_READ_PMSN 1
#define MMC_READ_DATA_KEYS 2
AACS_PRIVATE MMC *mmc_open(const char *path);
AACS_PRIVATE void mmc_close(MMC *mmc);
AACS_PRIVATE int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert,
uint8_t *vid);
AACS_PRIVATE int mmc_read_pmsn(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert,
uint8_t *pmsn);
AACS_PRIVATE int mmc_read_data_keys(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert,
uint8_t *read_data_key, uint8_t *write_data_key);
AACS_PRIVATE int mmc_read_auth(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert,
int request, uint8_t *p1, uint8_t *p2);
AACS_PRIVATE int mmc_read_drive_cert(MMC *mmc, uint8_t *drive_cert);
AACS_PRIVATE const uint8_t *mmc_get_drive_cert(MMC *mmc);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment