Commit 7c8c7b43 authored by Janusz Dziemidowicz's avatar Janusz Dziemidowicz Committed by npzacs
Browse files

Retrieve bus encryption flags from drive and content certificate

For bus encryption to be active it must be enabled both by the drive
and the disc.
Drive certificate contains Bus Encryption Capable (BEC) flag in the
least significant bit in the second byte of the certificate.
Content certificate contains Bus Encryption Enabled (BEE) flag in the
most significant bit in the second byte of the certificate.
Retrieve both bits so it is now possible to check if bus encryption is
active (it will not be active if the disc does not enable it, even on
bus encryption drive; most discs currently do not enable it).
parent af331cf3
......@@ -65,6 +65,10 @@ struct aacs {
/* title -> CPS unit mappings */
uint32_t num_titles;
uint16_t *cps_units; /* [0] = first play ; [1] = top menu ; [2] = title 1 ... */
/* bus encryption */
int bee; /* bus encryption enabled flag in content certificate */
int bec; /* bus encryption capable flag in drive certificate */
};
static const uint8_t empty_key[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
......@@ -441,6 +445,22 @@ static AACS_FILE_H *_open_unit_key_file(const char *path)
return fp;
}
static AACS_FILE_H *_open_content_certificate_file(const char *path)
{
AACS_FILE_H *fp;
char *f_name;
f_name = str_printf("%s/AACS/Content000.cer", path);
fp = file_open(f_name, "rb");
if (!fp) {
DEBUG(DBG_AACS | DBG_CRIT, "Error opening content certificate file %s\n", f_name);
}
X_FREE(f_name);
return fp;
}
/* Function that collects keys from keydb config entry */
static void _find_config_entry(AACS *aacs, title_entry_list *ce,
uint8_t *mk, uint8_t *vuk)
......@@ -639,6 +659,50 @@ static int _calc_title_hash(const char *path, uint8_t *title_hash)
return result;
}
static int _get_bus_encryption_enabled(const char *path)
{
AACS_FILE_H *fp = NULL;
uint8_t buf[2];
int bee = 0;
fp = _open_content_certificate_file(path);
if (!fp) {
DEBUG(DBG_AACS | DBG_CRIT, "Unable to open content certificate\n");
return 0;
}
if (file_read(fp, buf, 2) == 2) {
bee = (buf[1] & 0x80) >> 7;
DEBUG(DBG_AACS, "Bus Encryption Enabled flag in content certificate: %d\n", bee);
} else {
DEBUG(DBG_AACS | DBG_CRIT, "Failed to read Bus Encryption Enabled flag from content certificate file\n");
}
file_close(fp);
return bee;
}
static int _get_bus_encryption_capable(const char *path)
{
MMC* mmc = NULL;
uint8_t drive_cert[92];
int bec = 0;
if (!(mmc = mmc_open(path))) {
return 0;
}
if (mmc_read_drive_cert(mmc, drive_cert) == MMC_SUCCESS) {
bec = drive_cert[1] & 1;
DEBUG(DBG_AACS, "Bus Encryption Capable flag in drive certificate: %d\n", bec);
} else {
DEBUG(DBG_AACS | DBG_CRIT, "Unable to read drive certificate\n");
}
mmc_close(mmc);
return bec;
}
static int _verify_ts(uint8_t *buf, size_t size)
{
uint8_t *ptr;
......@@ -751,6 +815,9 @@ AACS *aacs_open2(const char *path, const char *configfile_path, int *error_code)
DEBUG(DBG_AACS, "Starting AACS waterfall...\n");
*error_code = _calc_uks(aacs, configfile_path);
aacs->bee = _get_bus_encryption_enabled(path);
aacs->bec = _get_bus_encryption_capable(path);
if (*error_code == AACS_SUCCESS) {
DEBUG(DBG_AACS, "AACS initialized!\n");
} else {
......
......@@ -469,8 +469,8 @@ static int _mmc_send_host_cert(MMC *mmc, uint8_t agid,
return _mmc_send_key(mmc, agid, 0x01, buf, 116);
}
static int _mmc_read_drive_cert(MMC *mmc, uint8_t agid, uint8_t *drive_nonce,
uint8_t *drive_cert)
static int _mmc_read_drive_cert_challenge(MMC *mmc, uint8_t agid, uint8_t *drive_nonce,
uint8_t *drive_cert)
{
uint8_t buf[116];
memset(buf, 0, sizeof(buf));
......@@ -1044,7 +1044,7 @@ static int _mmc_aacs_auth(MMC *mmc, const uint8_t *host_priv_key, const uint8_t
}
// receive mmc cert + nonce
if (!_mmc_read_drive_cert(mmc, agid, dn, dc)) {
if (!_mmc_read_drive_cert_challenge(mmc, agid, dn, dc)) {
DEBUG(DBG_MMC | DBG_CRIT,
"Drive doesn't give its certificate\n");
return MMC_ERROR;
......@@ -1223,6 +1223,17 @@ int mmc_read_data_keys(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *ho
return MMC_ERROR;
}
int mmc_read_drive_cert(MMC *mmc, uint8_t *drive_cert)
{
uint8_t buf[116];
if (_mmc_report_key(mmc, 0, 0, 0, 0x38, buf, 116)) {
memcpy(drive_cert, buf + 4, 92);
return MMC_SUCCESS;
}
return MMC_ERROR;
}
uint8_t *mmc_read_mkb(MMC *mmc, int address, int *size)
{
uint8_t agid = 0;
......
......@@ -37,6 +37,7 @@ AACS_PRIVATE int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uin
uint8_t *vid, 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_drive_cert(MMC *mmc, uint8_t *drive_cert);
/* read partial MKB */
AACS_PRIVATE uint8_t *mmc_read_mkb(MMC *mmc, int address, int *size);
......
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