[libaacs-devel] [Git][videolan/libaacs][master] 3 commits: crypto: check for gcrypt AES errors
Petri Hintukainen pushed to branch master at VideoLAN / libaacs Commits: 7c804ad3 by Petri Hintukainen at 2021-05-01T19:41:46+03:00 crypto: check for gcrypt AES errors - - - - - 554601de by Petri Hintukainen at 2021-05-01T20:09:06+03:00 mmc: log gcrypt AES errors - - - - - de0f0c84 by Petri Hintukainen at 2021-05-01T20:13:40+03:00 mkb: Return record length only when valid record was found. - - - - - 4 changed files: - src/libaacs/crypto.c - src/libaacs/crypto.h - src/libaacs/mkb.c - src/libaacs/mmc.c Changes: = src/libaacs/crypto.c = @@ -106,18 +106,22 @@ static void _curve_free(elliptic_curve_t *c) point_free(&c->G); } -static void _aesg3(const uint8_t *src_key, uint8_t *dst_key, uint8_t inc) +BD_USED static int _aesg3(const uint8_t *src_key, uint8_t *dst_key, uint8_t inc) { -int a; +int a, err; uint8_t seed[16] = { 0x7B, 0x10, 0x3C, 0x5D, 0xCB, 0x08, 0xC4, 0xE5, 0x1A, 0x27, 0xB0, 0x17, 0x99, 0x05, 0x3B, 0xD9 }; seed[15] += inc; -crypto_aes128d(src_key, seed, dst_key); +err = crypto_aes128d(src_key, seed, dst_key); +if (err) +return err; for (a = 0; a < 16; a++) { dst_key[a] ^= seed[a]; } + +return err; } /* Initializes libgcrypt */ @@ -143,39 +147,61 @@ int crypto_init() return crypto_init_check; } -void crypto_aes128e(const uint8_t *key, const uint8_t *data, uint8_t *dst) +int crypto_aes128e(const uint8_t *key, const uint8_t *data, uint8_t *dst) { gcry_cipher_hd_t gcry_h; +gcry_error_t err; + +err = gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); +if (err) +return err; + +err = gcry_cipher_setkey(gcry_h, key, 16); +if (err) +goto error; +err = gcry_cipher_encrypt(gcry_h, dst, 16, data, data ? 16 : 0); -gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); -gcry_cipher_setkey(gcry_h, key, 16); -gcry_cipher_encrypt(gcry_h, dst, 16, data, data ? 16 : 0); + error: gcry_cipher_close(gcry_h); +return err; } -void crypto_aes128d(const uint8_t *key, const uint8_t *data, uint8_t *dst) +int crypto_aes128d(const uint8_t *key, const uint8_t *data, uint8_t *dst) { gcry_cipher_hd_t gcry_h; +gcry_error_t err; + +err = gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); +if (err) +return err; -gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); -gcry_cipher_setkey(gcry_h, key, 16); -gcry_cipher_decrypt(gcry_h, dst, 16, data, 16); +err = gcry_cipher_setkey(gcry_h, key, 16); +if (err) +goto error; +err = gcry_cipher_decrypt(gcry_h, dst, 16, data, 16); + + error: gcry_cipher_close(gcry_h); +return err; } -void crypto_aesg3(const uint8_t *D, uint8_t *lsubk, uint8_t* rsubk, uint8_t *pk) +int crypto_aesg3(const uint8_t *D, uint8_t *lsubk, uint8_t* rsubk, uint8_t *pk) { +int err1 = 0, err2 = 0, err3 = 0; + if (lsubk) { -_aesg3(D, lsubk, 0); +err1 = _aesg3(D, lsubk, 0); } if (pk) { -_aesg3(D, pk, 1); +err2 = _aesg3(D, pk, 1); } if (rsubk) { -_aesg3(D, rsubk, 2); +err3 = _aesg3(D, rsubk, 2); } + +return err1 ? err1 : err2 ? err2 : err3; } /* @@ -189,15 +215,18 @@ static void _shl_128(unsigned char *dst, const unsigned char *src) for (i = 15; i >= 0; i--) { dst[i] = (src[i] << 1) | overflow; - overflow = src[i] >> 7; +overflow = src[i] >> 7; } } -static void _cmac_key(const unsigned char *aes_key, unsigned char *k1, unsigned char *k2) +BD_USED static int _cmac_key(const unsigned char *aes_key, unsigned char *k1, unsigned char *k2) { uint8_t key[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +int err; -crypto_aes128e(aes_key, NULL, key); +err = crypto_aes128e(aes_key, NULL, key); +if (err) +return err; _shl_128(k1, key); if (key[0] & 0x80) { @@ -208,42 +237,81 @@ static void _cmac_key(const unsigned char *aes_key, unsigned char *k1, unsigned if (k1[0] & 0x80) { k2[15] ^= 0x87; } + +return err; } -void crypto_aes_cmac_16(const unsigned char *data, const unsigned char *aes_key, unsigned char *cmac) +int crypto_aes_cmac_16(const unsigned char *data, const unsigned char *aes_key, unsigned char *cmac) { uint8_t k1[16], k2[16]; unsigned ii; +int err; /* * Simplified version of AES CMAC. Spports only 16-byte input data. */ /* generate CMAC keys */ -_cmac_key(aes_key, k1, k2); + +err = _cmac_key(aes_key, k1, k2); +if (err) +return err; + memcpy(cmac, data, 16); for (ii = 0; ii < 16; ii++) { cmac[ii] ^= k1[ii]; } -crypto_aes128e(aes_key, NULL, cmac); +err = crypto_aes128e(aes_key, NULL, cmac); + +return err; } /* * */ -void cry
[libaacs-devel] [Git][videolan/libaacs][master] Fix crypto_strerror
Petri Hintukainen pushed to branch master at VideoLAN / libaacs Commits: 3959c8f4 by npzacs at 2021-05-01T20:34:16+03:00 Fix crypto_strerror - - - - - 1 changed file: - src/libaacs/crypto.c Changes: = src/libaacs/crypto.c = @@ -307,9 +307,9 @@ void crypto_strerror(int err, char *buf, size_t buf_size) #else const char *msg = gcry_strerror(err); buf[0] = 0; - if (str) { -strncpy(buf, str, buf_size); -str[buf_size - 1] = 0; + if (msg) { +strncpy(buf, msg, buf_size); +buf[buf_size - 1] = 0; } #endif } View it on GitLab: https://code.videolan.org/videolan/libaacs/-/commit/3959c8f4ce736af0fe51f344a402cfa8751b8623 -- View it on GitLab: https://code.videolan.org/videolan/libaacs/-/commit/3959c8f4ce736af0fe51f344a402cfa8751b8623 You're receiving this email because of your account on code.videolan.org. ___ libaacs-devel mailing list libaacs-devel@videolan.org https://mailman.videolan.org/listinfo/libaacs-devel
[libaacs-devel] [Git][videolan/libaacs][master] aacs: log gcrypt AES errors
Petri Hintukainen pushed to branch master at VideoLAN / libaacs Commits: bd0fa5d2 by Petri Hintukainen at 2021-05-01T20:50:09+03:00 aacs: log gcrypt AES errors - - - - - 1 changed file: - src/libaacs/aacs.c Changes: = src/libaacs/aacs.c = @@ -99,7 +99,7 @@ static int _validate_pk(const uint8_t *pk, const uint8_t *cvalue, const uint8_t *uv, const uint8_t *vd, uint8_t *mk) { -int a; +int a, crypto_err; uint8_t dec_vd[16]; char str[40]; @@ -109,14 +109,19 @@ static int _validate_pk(const uint8_t *pk, BD_DEBUG(DBG_AACS, " cvalue: %s\n", str_print_hex(str, cvalue, 16)); BD_DEBUG(DBG_AACS, " Verification data: %s\n", str_print_hex(str, vd, 16)); -crypto_aes128d(pk, cvalue, mk); +crypto_err = crypto_aes128d(pk, cvalue, mk); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "decrypting media key failed", crypto_err); +} for (a = 0; a < 4; a++) { mk[a + 12] ^= uv[a]; } -crypto_aes128d(mk, vd, dec_vd); - +crypto_err = crypto_aes128d(mk, vd, dec_vd); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "decrypting media key verification data failed", crypto_err); +} if (!memcmp(dec_vd, "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8)) { BD_DEBUG(DBG_AACS, "Processing key %s is valid!\n", str_print_hex(str, pk, 16)); return AACS_SUCCESS; @@ -217,8 +222,12 @@ static uint32_t _calc_v_mask(uint32_t uv) static void _calc_pk(const uint8_t *dk, uint8_t *pk, uint32_t uv, uint32_t v_mask, uint32_t dev_key_v_mask) { unsigned char left_child[16], right_child[16]; +int crypto_err; -crypto_aesg3(dk, left_child, right_child, pk); +crypto_err = crypto_aesg3(dk, left_child, right_child, pk); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "PK derivation failed", crypto_err); +} while (dev_key_v_mask != v_mask) { @@ -236,7 +245,10 @@ static void _calc_pk(const uint8_t *dk, uint8_t *pk, uint32_t uv, uint32_t v_mas memcpy(curr_key, right_child, 16); } -crypto_aesg3(curr_key, left_child, right_child, pk); +crypto_err = crypto_aesg3(curr_key, left_child, right_child, pk); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "PK derivation failed", crypto_err); +} dev_key_v_mask = ((int) dev_key_v_mask) >> 1; } @@ -765,7 +777,7 @@ static int _read_pmsn(AACS *aacs, cert_list *hcl) static int _calc_vuk(AACS *aacs, uint8_t *mk, uint8_t *vuk, config_file *cf) { -int error_code; +int error_code, crypto_err; /* Skip if retrieved from config file */ if (memcmp(vuk, empty_key, 16)) { @@ -797,7 +809,10 @@ static int _calc_vuk(AACS *aacs, uint8_t *mk, uint8_t *vuk, config_file *cf) /* calculate VUK */ -crypto_aes128d(mk, aacs->vid, vuk); +crypto_err = crypto_aes128d(mk, aacs->vid, vuk); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "decrypting VUK failed", crypto_err); +} int a; for (a = 0; a < 16; a++) { @@ -1016,6 +1031,7 @@ static int _calc_uks(AACS *aacs, config_file *cf) /* decrypt unit keys */ for (i = 0; i < aacs->uk->num_uk; i++) { +int crypto_err; /* error out if VUK calculation fails and encrypted CPS unit is found */ if (vuk_error_code != AACS_SUCCESS) { @@ -1026,7 +1042,10 @@ static int _calc_uks(AACS *aacs, config_file *cf) BD_DEBUG(DBG_AACS | DBG_CRIT, "WARNING: VUK calculation failed but disc seems to be unencrypted.\n"); } -crypto_aes128d(vuk, aacs->uk->enc_uk[i].key, aacs->uk->uk[i].key); +crypto_err = crypto_aes128d(vuk, aacs->uk->enc_uk[i].key, aacs->uk->uk[i].key); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "decrypting unit key failed", crypto_err); +} char str[40]; BD_DEBUG(DBG_AACS, "Unit key %d: %s\n", i, @@ -1157,23 +1176,29 @@ static int _decrypt_unit(AACS *aacs, uint8_t *out_buf, const uint8_t *in_buf, ui { /* inbuf == NULL means in-place decryption */ -int a; +int a, crypto_err; uint8_t key[16]; if (BD_UNLIKELY(in_buf != NULL)) { memcpy(out_buf, in_buf, 16); /* first 16 bytes are plain */ } -crypto_aes128e(aacs->uk->uk[curr_uk].key, out_buf, key); +crypto_err = crypto_aes128e(aacs->uk->uk[curr_uk].key, out_buf, key); +if (crypto_err) { +LOG_CRYPTO_ERROR(DBG_AACS, "unit key derivation failed", crypto_err); +} for (a = 0; a < 16; a++) { key[a] ^= out_buf[a]; /* here out_buf is plain data fron in_buf */ } if (BD_UNLIKELY(in_buf != NULL)) { -crypto_aacs_decrypt(key, out_buf + 16, ALIGNED_UNIT_LEN - 16, in_buf + 16, ALIGNED_UNIT_LEN - 16); +crypto_err = crypto_aacs_decrypt(key, out_buf + 16, ALIGNED_UNIT_LEN - 16, in_buf + 16, ALIGNED_UNIT_LEN