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

Reply via email to