libaacs | branch: master | Janusz Dziemidowicz <rrapt...@nails.eu.org> | Fri 
Sep  6 23:47:52 2013 +0200| [e3ae3eecf0b61072906b84acaa400d348ffe2ab2] | 
committer: npzacs

Function for reading data keys from drive

Bus encryption uses data keys (separate one for reads and writes) that
can be retrieved from drive after sucessful AACS-Auth. Add function to
retrieve those keys.

It seems that it requires a new AACS-Auth every time keys are being
read (at least reading the keys right after reading VID fails on my
drive).

> http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=e3ae3eecf0b61072906b84acaa400d348ffe2ab2
---

 src/libaacs/mmc.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libaacs/mmc.h |    2 ++
 2 files changed, 62 insertions(+)

diff --git a/src/libaacs/mmc.c b/src/libaacs/mmc.c
index 86b0183..a51f685 100644
--- a/src/libaacs/mmc.c
+++ b/src/libaacs/mmc.c
@@ -601,6 +601,19 @@ static int _mmc_read_pmsn(MMC *mmc, uint8_t agid, uint8_t 
*pmsn,
     return 0;
 }
 
+static int _mmc_read_data_keys(MMC *mmc, uint8_t agid, uint8_t *read_data_key, 
uint8_t *write_data_key)
+{
+    uint8_t buf[36];
+
+    if (_mmc_report_disc_structure(mmc, agid, 0x84, 0, 0, buf, 36)) {
+        memcpy(read_data_key, buf + 4, 16);
+        memcpy(write_data_key, buf + 20, 16);
+        return 1;
+    }
+
+    return 0;
+}
+
 #ifdef USE_IOKIT
 static int get_mounted_device_from_path (MMC *mmc, const char *path) {
   struct statfs stat_info;
@@ -1158,6 +1171,53 @@ int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, 
const uint8_t *host_cer
     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)
+{
+    uint8_t agid = 0, bus_key[16], 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");
+
+    _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, host_priv_key, host_cert, bus_key);
+    if (error_code) {
+        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;
+    }
+
+    DEBUG(DBG_MMC | DBG_CRIT, "Unable to read data keys from drive!\n");
+
+    _mmc_invalidate_agid(mmc, agid);
+
+    return MMC_ERROR;
+}
+
 uint8_t *mmc_read_mkb(MMC *mmc, int address, int *size)
 {
     uint8_t agid = 0;
diff --git a/src/libaacs/mmc.h b/src/libaacs/mmc.h
index 2c05250..57419dc 100644
--- a/src/libaacs/mmc.h
+++ b/src/libaacs/mmc.h
@@ -35,6 +35,8 @@ 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, 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);
 
 /* read partial MKB */
 AACS_PRIVATE uint8_t *mmc_read_mkb(MMC *mmc, int address, int *size);

_______________________________________________
libaacs-devel mailing list
libaacs-devel@videolan.org
https://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to