Petri Hintukainen pushed to branch master at VideoLAN / libaacs
Commits:
33c95654 by John Doe at 2020-06-21T02:26:15+03:00
Fix unit key parsing for AACS 2.x discs (when there are multiple unit keys)
- - - - -
3 changed files:
- src/libaacs/aacs.c
- src/libaacs/unit_key.c
- src/libaacs/unit_key.h
Changes:
=====================================
src/libaacs/aacs.c
=====================================
@@ -982,10 +982,11 @@ static int _calc_title_hash(AACS *aacs)
size_t size;
char str[48];
int result = AACS_SUCCESS;
+ int aacs2 = aacs->cc ? aacs->cc->aacs2 : 0;
size = _read_file(aacs, "AACS" DIR_SEP "Unit_Key_RO.inf", &data);
if (size > 2048) {
- aacs->uk = uk_parse(data, size);
+ aacs->uk = uk_parse(data, size, aacs2);
}
/* failed, try backup */
@@ -993,7 +994,7 @@ static int _calc_title_hash(AACS *aacs)
X_FREE(data);
size = _read_file(aacs, "AACS" DIR_SEP "DUPLICATE" DIR_SEP
"Unit_Key_RO.inf", &data);
if (size > 2048) {
- aacs->uk = uk_parse(data, size);
+ aacs->uk = uk_parse(data, size, aacs2);
}
}
@@ -1233,6 +1234,8 @@ int aacs_open_device(AACS *aacs, const char *path, const
char *configfile_path)
aacs->path = path ? str_dup(path) : NULL;
+ aacs->cc = _read_cc_any(aacs);
+
error_code = _calc_title_hash(aacs);
if (error_code != AACS_SUCCESS) {
return error_code;
@@ -1246,8 +1249,6 @@ int aacs_open_device(AACS *aacs, const char *path, const
char *configfile_path)
BD_DEBUG(DBG_AACS, "Failed to initialize AACS!\n");
}
- aacs->cc = _read_cc_any(aacs);
-
aacs->bee = _get_bus_encryption_enabled(aacs);
aacs->bec = _get_bus_encryption_capable(aacs, path);
=====================================
src/libaacs/unit_key.c
=====================================
@@ -143,8 +143,9 @@ static int _assign_titles(AACS_UK *uk, const uint8_t *p,
size_t size)
return 0;
}
-static int _parse_uks(AACS_UK *uk, const uint8_t *p, size_t size)
+static int _parse_uks(AACS_UK *uk, const uint8_t *p, size_t size, int aacs2)
{
+ const uint8_t empty_key[16] = {0};
uint32_t uk_pos;
unsigned int i;
@@ -173,6 +174,17 @@ static int _parse_uks(AACS_UK *uk, const uint8_t *p,
size_t size)
return -1;
}
+ if (aacs2 && uk->num_uk > 1) {
+ /* do some sanity checks ... */
+ if (!memcmp(empty_key, p + 48 + 48 + 16, 16)) {
+ BD_DEBUG(DBG_UK | DBG_CRIT, "AACS2 unit key not found from
expected location ?\n");
+ aacs2 = 0;
+ } else if (size < uk_pos + 64 * uk->num_uk + 16) {
+ BD_DEBUG(DBG_UK | DBG_CRIT, "Unexpected EOF (AACS2 unit key data
truncated)\n");
+ return -1;
+ }
+ }
+
/* alloc storage for keys */
uk->enc_uk = calloc(uk->num_uk, sizeof(AACS_UK));
@@ -181,19 +193,29 @@ static int _parse_uks(AACS_UK *uk, const uint8_t *p,
size_t size)
return -1;
}
- BD_DEBUG(DBG_UK, "%d CPS unit keys\n", uk->num_uk);
+ BD_DEBUG(DBG_UK, "%d CPS unit keys (AACS%d)\n", uk->num_uk, aacs2 ? 2 : 1);
/* get encrypted keys */
for (i = 0; i < uk->num_uk; i++) {
uk_pos += 48;
memcpy(uk->enc_uk[i].key, p + uk_pos, 16);
+
+ if (!memcmp(empty_key, uk->enc_uk[i].key, 16)) {
+ BD_DEBUG(DBG_UK | DBG_CRIT, "WARNING: Unit key %d is empty!\n",
i+1);
+ }
+
+ /* XXX there seems to be nothing in this file that could be used to
detect this ... */
+ if (aacs2) {
+ /* skip unknown */
+ uk_pos += 16;
+ }
}
return 0;
}
-static int _parse(AACS_UK *uk, const uint8_t *data, size_t len)
+static int _parse(AACS_UK *uk, const uint8_t *data, size_t len, int aacs2)
{
int result;
@@ -201,7 +223,7 @@ static int _parse(AACS_UK *uk, const uint8_t *data, size_t
len)
return -1;
}
- result = _parse_uks(uk, data, len);
+ result = _parse_uks(uk, data, len, aacs2);
/* not fatal, just speeds up things ... */
_assign_titles(uk, data, len);
@@ -209,7 +231,7 @@ static int _parse(AACS_UK *uk, const uint8_t *data, size_t
len)
return result;
}
-AACS_UK *uk_parse(const void *data, size_t len)
+AACS_UK *uk_parse(const void *data, size_t len, int aacs2)
{
AACS_UK *uk = calloc(1, sizeof(*uk));
@@ -217,7 +239,7 @@ AACS_UK *uk_parse(const void *data, size_t len)
return NULL;
}
- if (_parse(uk, data, len) < 0) {
+ if (_parse(uk, data, len, aacs2) < 0) {
BD_DEBUG(DBG_UK | DBG_CRIT, "Corrupt unit key file
(AACS/Unit_Key_RO.inf)\n");
X_FREE(uk);
}
=====================================
src/libaacs/unit_key.h
=====================================
@@ -50,7 +50,7 @@ struct aacs_uk {
uint16_t *title_cps_unit; /* map title to CPS unit (key index) */
};
-BD_PRIVATE AACS_UK *uk_parse(const void *data, size_t len);
+BD_PRIVATE AACS_UK *uk_parse(const void *data, size_t len, int aacs2);
BD_PRIVATE void uk_free(AACS_UK **);
#endif /* AACS_UK_H_ */
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/commit/33c95654d6147d6de6d97fb57d8b0ea2f3d47b43
--
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/commit/33c95654d6147d6de6d97fb57d8b0ea2f3d47b43
You're receiving this email because of your account on code.videolan.org.
_______________________________________________
libaacs-devel mailing list
[email protected]
https://mailman.videolan.org/listinfo/libaacs-devel