libaacs | branch: master | npzacs <[email protected]> | Fri Jan 4 12:22:14 2013 +0200| [5cb7a50fc986c291f7936af46f33b784318cd10b] | committer: npzacs
Added reading of PMSN (Pre-recorded Media Serial Number) > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=5cb7a50fc986c291f7936af46f33b784318cd10b --- ChangeLog | 3 +++ configure.ac | 8 ++++---- src/libaacs/aacs.c | 17 ++++++++++++++++- src/libaacs/aacs.h | 3 ++- src/libaacs/mmc.c | 28 +++++++++++++++++++++++++++- src/libaacs/mmc.h | 2 +- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33bf609..eb0a68e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +????-??-??: Version 0.6.0 + - Added reading of PMSN (Pre-recorded Media Serial Number) + 2012-08-17: Version 0.5.0 - Support for Mac OS X using IOKit - Fix AACS detection failure in some Win32 systems diff --git a/configure.ac b/configure.ac index a32f403..1b3cfbc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # library version number m4_define([aacs_major], 0) -m4_define([aacs_minor], 5) +m4_define([aacs_minor], 6) m4_define([aacs_micro], 0) m4_define([aacs_version],[aacs_major.aacs_minor.aacs_micro]) @@ -14,9 +14,9 @@ m4_define([aacs_version],[aacs_major.aacs_minor.aacs_micro]) # # Library file name will be libaacs.(current-age).age.revision # -m4_define([lt_current], 2) -m4_define([lt_age], 2) -m4_define([lt_revision], 1) +m4_define([lt_current], 3) +m4_define([lt_age], 3) +m4_define([lt_revision], 0) # initilization AC_INIT([libaacs], aacs_version, [http://www.videolan.org/developers/libaacs.html]) diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c index f702fec..964bac1 100644 --- a/src/libaacs/aacs.c +++ b/src/libaacs/aacs.c @@ -52,6 +52,8 @@ struct aacs { /* VID is cached for BD-J */ uint8_t vid[16]; + /* PMSN is cached for BD-J */ + uint8_t pmsn[16]; /* unit key for each CPS unit */ uint32_t num_uks; @@ -299,7 +301,7 @@ static int _read_vid(AACS *aacs, cert_list *hcl) DEBUG(DBG_AACS, "Trying host certificate (id 0x%s)...\n", print_hex(tmp_str, cert + 4, 6)); - int mmc_result = mmc_read_vid(mmc, priv_key, cert, aacs->vid); + int mmc_result = mmc_read_vid(mmc, priv_key, cert, aacs->vid, aacs->pmsn); switch (mmc_result) { case MMC_SUCCESS: mkb_close(hrl_mkb); @@ -827,6 +829,19 @@ const uint8_t *aacs_get_vid(AACS *aacs) return aacs->vid; } +const uint8_t *aacs_get_pmsn(AACS *aacs) +{ + if (!memcmp(aacs->vid, empty_key, 16)) { + config_file *cf = keydbcfg_config_load(NULL); + if (cf) { + _read_vid(aacs, cf->host_cert_list); + + keydbcfg_config_file_close(cf); + } + } + return aacs->pmsn; +} + static AACS_RL_ENTRY *_get_rl(const char *type, int *num_records, int *mkb_version) { uint32_t len, version; diff --git a/src/libaacs/aacs.h b/src/libaacs/aacs.h index 1aa5a2d..fbd934b 100644 --- a/src/libaacs/aacs.h +++ b/src/libaacs/aacs.h @@ -49,7 +49,8 @@ AACS_PUBLIC int aacs_decrypt_unit(AACS *aacs, uint8_t *buf); /* Disc information */ AACS_PUBLIC int aacs_get_mkb_version(AACS *aacs); AACS_PUBLIC const uint8_t *aacs_get_disc_id(AACS *aacs); -AACS_PUBLIC const uint8_t *aacs_get_vid(AACS *aacs); /* may fail even if disc can be decrypted */ +AACS_PUBLIC const uint8_t *aacs_get_vid(AACS *aacs); /* may fail even if disc can be decrypted */ +AACS_PUBLIC const uint8_t *aacs_get_pmsn(AACS *aacs); /* may fail even if disc can be decrypted */ /* revocation lists */ typedef struct { diff --git a/src/libaacs/mmc.c b/src/libaacs/mmc.c index 45d72a8..8d2b0b3 100644 --- a/src/libaacs/mmc.c +++ b/src/libaacs/mmc.c @@ -585,6 +585,21 @@ static int _mmc_read_vid(MMC *mmc, uint8_t agid, uint8_t *volume_id, return 0; } +static int _mmc_read_pmsn(MMC *mmc, uint8_t agid, uint8_t *pmsn, + uint8_t *mac) +{ + uint8_t buf[36]; + memset(buf, 0, sizeof(buf)); + + if (_mmc_report_disc_structure(mmc, agid, 0x81, 0, 0, buf, 36)) { + memcpy(pmsn, buf + 4, 16); + memcpy(mac, 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; @@ -992,7 +1007,7 @@ static int _verify_signature(const uint8_t *cert, const uint8_t *signature, return crypto_aacs_verify(cert, signature, data, 60); } -int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *vid) +int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cert, uint8_t *vid, uint8_t *pmsn) { uint8_t agid = 0, hks[40], dn[20], dc[92], dkp[40], dks[40], mac[16]; char str[512]; @@ -1086,6 +1101,17 @@ int mmc_read_vid(MMC *mmc, const uint8_t *host_priv_key, const uint8_t *host_cer if (_mmc_read_vid(mmc, agid, vid, mac)) { DEBUG(DBG_MMC, "VID: %s (%p)\n", print_hex(str, vid, 16), mmc); DEBUG(DBG_MMC, "MAC: %s (%p)\n", print_hex(str, mac, 16), mmc); + /* TODO: verify MAC */ + + /* read pmsn */ + if (_mmc_read_pmsn(mmc, agid, pmsn, mac)) { + DEBUG(DBG_MMC, "PMSN: %s (%p)\n", print_hex(str, pmsn, 16), mmc); + DEBUG(DBG_MMC, "MAC: %s (%p)\n", print_hex(str, mac, 16), mmc); + /* TODO: verify MAC */ + } else { + memset(pmsn, 0, 16); + DEBUG(DBG_MMC | DBG_CRIT, "Unable to read PMSN from drive! (%p)\n", mmc); + } _mmc_invalidate_agid(mmc, agid); diff --git a/src/libaacs/mmc.h b/src/libaacs/mmc.h index 87c0f57..2c05250 100644 --- a/src/libaacs/mmc.h +++ b/src/libaacs/mmc.h @@ -34,7 +34,7 @@ typedef struct mmc MMC; 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 *vid, uint8_t *pmsn); /* read partial MKB */ AACS_PRIVATE uint8_t *mmc_read_mkb(MMC *mmc, int address, int *size); _______________________________________________ libaacs-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libaacs-devel
