libaacs | branch: master | npzacs <npz...@gmail.com> | Wed Jan 13 14:33:15 2016 +0200| [5a0ae3c6a4a45d71a1466d1a48353f410005fe3d] | committer: npzacs
Use CCI data to detect unencrypted content > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=5a0ae3c6a4a45d71a1466d1a48353f410005fe3d --- src/libaacs/aacs.c | 28 +++++++++++++++++++++++++++- src/libaacs/cci.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/libaacs/cci.h | 2 ++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c index 0ce4b26..7241960 100644 --- a/src/libaacs/aacs.c +++ b/src/libaacs/aacs.c @@ -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); diff --git a/src/libaacs/cci.c b/src/libaacs/cci.c index 61b23e3..083407c 100644 --- a/src/libaacs/cci.c +++ b/src/libaacs/cci.c @@ -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; diff --git a/src/libaacs/cci.h b/src/libaacs/cci.h index 778c85b..703e919 100644 --- a/src/libaacs/cci.h +++ b/src/libaacs/cci.h @@ -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_ */ _______________________________________________ libaacs-devel mailing list libaacs-devel@videolan.org https://mailman.videolan.org/listinfo/libaacs-devel