Commit 5a0ae3c6 authored by npzacs's avatar npzacs
Browse files

Use CCI data to detect unencrypted content

parent ca48204a
......@@ -826,6 +826,19 @@ static AACS_CCI *_read_cci(AACS *aacs, int cps_unit)
return cci;
}
static int _check_cci_unencrypted(AACS *aacs, int cps_unit)
{
int result = -1;
AACS_CCI *cci = _read_cci(aacs, cps_unit);
if (cci) {
result = cci_is_unencrypted(cci);
cci_free(&cci);
}
return result;
}
static int _calc_uks(AACS *aacs, config_file *cf)
{
AACS_FILE_H *fp = NULL;
......@@ -833,6 +846,7 @@ static int _calc_uks(AACS *aacs, config_file *cf)
uint64_t f_pos;
unsigned int i;
int error_code;
int vuk_tried = 0, vuk_error_code = AACS_SUCCESS;
uint8_t mk[16] = {0}, vuk[16] = {0};
......@@ -881,8 +895,20 @@ static int _calc_uks(AACS *aacs, config_file *cf)
// Read keys
for (i = 0; i < aacs->num_uks; i++) {
f_pos += 48;
int plain = _check_cci_unencrypted(aacs, i + 1);
if (!vuk_tried) {
/* Make sure we have VUK */
vuk_error_code = _calc_vuk(aacs, mk, vuk, cf);
vuk_tried = 1;
}
/* error out if VUK calculation fails and encrypted CPS unit is found */
if (!plain && vuk_error_code != AACS_SUCCESS) {
return vuk_error_code;
}
f_pos += 48;
file_seek(fp, f_pos, SEEK_SET);
if ((file_read(fp, buf, 16)) != 16) {
BD_DEBUG(DBG_AACS | DBG_CRIT, "Unit key %d: read error\n", i);
......
......@@ -163,6 +163,47 @@ void cci_free(AACS_CCI **pp)
}
}
int cci_is_unencrypted(AACS_CCI *cci)
{
unsigned int ii;
for (ii = 0; ii < cci->num_entry; ii++) {
AACS_CCI_ENTRY *e = &cci->entry[ii];
if (e->type == cci_AACS_ENHANCED_TITLE_USAGE) {
BD_DEBUG(DBG_CCI, "Enhanced title usage CCI found\n");
return 0;
}
if (e->type == cci_AACS_BASIC_CCI) {
BD_DEBUG(DBG_CCI, "AACS basic CCI found\n");
/* Blu-ray Disc Pre-recorded Book, chapters 3.9.4.2 and 7.2 */
if (e->version == 0x0100 && e->data_length == 0x84 &&
e->u.basic_cci.cci == 0 && e->u.basic_cci.epn == 1 && /* copy freely, EPN unasserted */
e->u.basic_cci.image_constraint && /* High Definition Analog Output in High Definition Analog Form */
!e->u.basic_cci.digital_only && /* Output of decrypted content is allowed for Analog/Digital Outputs */
!e->u.basic_cci.apstb /* APS off */ ) {
/* check all titles are basic titles */
int jj;
for (jj = 0; jj < (e->u.basic_cci.num_titles + 7) / 8; jj++) {
if (e->u.basic_cci.title_type[jj]) {
BD_DEBUG(DBG_CCI, "CCI: Enhanced title found\n");
return 0;
}
}
return 1;
}
return 0;
}
}
return 0;
}
AACS_BASIC_CCI *cci_get_basic_cci(AACS_CCI *cci)
{
unsigned int ii;
......
......@@ -29,6 +29,8 @@ typedef struct aacs_cci AACS_CCI;
BD_PRIVATE AACS_CCI *cci_parse(const void *data, size_t len);
BD_PRIVATE void cci_free(AACS_CCI **);
BD_PRIVATE int cci_is_unencrypted(AACS_CCI *cci);
BD_PRIVATE struct aacs_basic_cci *cci_get_basic_cci(AACS_CCI *cci);
#endif /* AACS_CCI_H_ */
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