libaacs | branch: master | npzacs <npz...@gmail.com> | Fri Sep 13 10:45:18 2013 +0300| [53fd3ed22d05bbe5736ee0303f6f5d470cd64f25] | committer: npzacs
mmc: cache drive certificate All drives do not support REPORT_KEY with format 0x38, so we need to cache the certificate from aacs authentication procedure. > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=53fd3ed22d05bbe5736ee0303f6f5d470cd64f25 --- src/libaacs/mmc.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/libaacs/mmc.c b/src/libaacs/mmc.c index 5afbdae..d6da2f4 100644 --- a/src/libaacs/mmc.c +++ b/src/libaacs/mmc.c @@ -147,7 +147,10 @@ struct mmc { uint8_t host_key[20]; uint8_t host_key_point[40]; + uint8_t drive_cert[92]; + uint8_t bus_encryption; + uint8_t read_drive_cert; }; static int _mmc_send_cmd(MMC *mmc, const uint8_t *cmd, uint8_t *buf, size_t tx, @@ -512,9 +515,11 @@ static int _mmc_check_aacs(MMC *mmc) DEBUG(DBG_MMC, " Binding Nonce generation support: %d\n", buf[4+8] & 1); DEBUG(DBG_MMC, " Binding Nonce block count: %d\n", buf[5+8]); DEBUG(DBG_MMC, " Bus encryption support: %d\n", buf[4+8] & 2); + DEBUG(DBG_MMC, " Read drive certificate: %d\n", buf[4+8] & 0x10); DEBUG(DBG_MMC, " AGID count: %d\n", buf[6+8] & 0xf); mmc->bus_encryption = !!(buf[4+8] & 2); + mmc->read_drive_cert = !!(buf[4+8] & 0x10); return buf[2+8] & 1; } @@ -1027,7 +1032,7 @@ static int _verify_signature(const uint8_t *cert, const uint8_t *signature, static int _mmc_aacs_auth(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *bus_key) { - uint8_t agid = 0, hks[40], dn[20], dc[92], dkp[40], dks[40]; + uint8_t agid = 0, hks[40], dn[20], dkp[40], dks[40]; char str[512]; memset(hks, 0, sizeof(hks)); @@ -1044,19 +1049,19 @@ 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_challenge(mmc, agid, dn, dc)) { + if (!_mmc_read_drive_cert_challenge(mmc, agid, dn, mmc->drive_cert)) { DEBUG(DBG_MMC | DBG_CRIT, "Drive doesn't give its certificate\n"); return MMC_ERROR; } if (DEBUG_KEYS) { - DEBUG(DBG_MMC, "Drive certificate : %s\n", print_hex(str, dc, 92)); + DEBUG(DBG_MMC, "Drive certificate : %s\n", print_hex(str, mmc->drive_cert, 92)); DEBUG(DBG_MMC, "Drive nonce : %s\n", print_hex(str, dn, 20)); } // verify drive certificate - if (!crypto_aacs_verify_drive_cert(dc)) { + if (!crypto_aacs_verify_drive_cert(mmc->drive_cert)) { DEBUG(DBG_MMC | DBG_CRIT, "Drive certificate is invalid\n"); return MMC_ERROR; } @@ -1073,7 +1078,7 @@ static int _mmc_aacs_auth(MMC *mmc, const uint8_t *host_priv_key, const uint8_t } // verify drive signature - if (!_verify_signature(dc, dks, mmc->host_nonce, dkp)) { + if (!_verify_signature(mmc->drive_cert, dks, mmc->host_nonce, dkp)) { DEBUG(DBG_MMC | DBG_CRIT, "Drive signature is invalid\n"); return MMC_ERROR; } @@ -1227,6 +1232,15 @@ int mmc_read_drive_cert(MMC *mmc, uint8_t *drive_cert) { uint8_t buf[116]; + if (mmc->drive_cert[0] == 0x01) { + memcpy(drive_cert, mmc->drive_cert, 92); + return MMC_SUCCESS; + } + + if (!mmc->read_drive_cert) { + DEBUG(DBG_MMC | DBG_CRIT, "Drive does not support reading drive certificate\n"); + } + if (_mmc_report_key(mmc, 0, 0, 0, 0x38, buf, 116)) { memcpy(drive_cert, buf + 4, 92); return MMC_SUCCESS; _______________________________________________ libaacs-devel mailing list libaacs-devel@videolan.org https://mailman.videolan.org/listinfo/libaacs-devel