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 crypto_aacs_decrypt(const uint8_t *key, uint8_t *out, size_t out_size,
const uint8_t *in, size_t in_size)
+int crypto_aacs_decrypt(const uint8_t *key, uint8_t *out, size_t out_size,
const uint8_t *in, size_t in_size)
{
static const uint8_t aacs_iv[16] = { 0x0b, 0xa0, 0xf8, 0xdd, 0xfe, 0xa6,
0x1f, 0xb3,
0xd8, 0xdf, 0x9f, 0x56, 0x6a, 0x05,
0x0f, 0x78 };
gcry_cipher_hd_t gcry_h;
+ gcry_error_t err;
+
+ err = gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ return err;
- gcry_cipher_open(&gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
- gcry_cipher_setkey(gcry_h, key, 16);
- gcry_cipher_setiv(gcry_h, aacs_iv, 16);
- gcry_cipher_decrypt(gcry_h, out, out_size, in, in_size);
+ err = gcry_cipher_setkey(gcry_h, key, 16);
+ if (err)
+ goto error;
+ err = gcry_cipher_setiv(gcry_h, aacs_iv, 16);
+ if (err)
+ goto error;
+ err = gcry_cipher_decrypt(gcry_h, out, out_size, in, in_size);
+
+ error:
gcry_cipher_close(gcry_h);
+ return err;
+}
+
+/*
+ *
+ */
+
+void crypto_strerror(int err, char *buf, size_t buf_size)
+{
+#if defined(HAVE_STRERROR_R) && defined(HAVE_LIBGPG_ERROR)
+ buf[0] = 0;
+ gpg_strerror_r(err, buf, buf_size);
+#else
+ const char *msg = gcry_strerror(err);
+ buf[0] = 0;
+ if (str) {
+ strncpy(buf, str, buf_size);
+ str[buf_size - 1] = 0;
+ }
+#endif
}
/*
=====================================
src/libaacs/crypto.h
=====================================
@@ -25,14 +25,21 @@
#include <stdlib.h>
#include <stdint.h>
+BD_PRIVATE void crypto_strerror(int err, char *buf, size_t buf_size);
+#define LOG_CRYPTO_ERROR(flags, str, err) do { \
+ char s[64]; \
+ crypto_strerror((err), s, sizeof(s)); \
+ BD_DEBUG(DBG_CRIT | (flags), "crypto error: %s: %s (%u)\n", (str), s,
(unsigned)(err)); \
+ } while (0)
+
BD_PRIVATE int crypto_init(void);
-BD_PRIVATE void crypto_aes128e(const uint8_t *key, const uint8_t *data,
uint8_t *dst);
-BD_PRIVATE void crypto_aes128d(const uint8_t *key, const uint8_t *data,
uint8_t *dst);
-BD_PRIVATE void crypto_aesg3(const uint8_t *D, uint8_t *lsubk, uint8_t* rsubk,
+BD_PRIVATE int crypto_aes128e(const uint8_t *key, const uint8_t *data,
uint8_t *dst);
+BD_PRIVATE int crypto_aes128d(const uint8_t *key, const uint8_t *data,
uint8_t *dst);
+BD_PRIVATE int crypto_aesg3(const uint8_t *D, uint8_t *lsubk, uint8_t* rsubk,
uint8_t *pk); // returns left, centre, right
keys
-BD_PRIVATE void crypto_aes_cmac_16(const unsigned char *data, const unsigned
char *aes_key, unsigned char *cmac);
+BD_PRIVATE int crypto_aes_cmac_16(const unsigned char *data, const unsigned
char *aes_key, unsigned char *cmac);
-BD_PRIVATE void crypto_aacs_decrypt(const uint8_t *key, uint8_t *out, size_t
out_size, const uint8_t *in, size_t in_size);
+BD_PRIVATE int crypto_aacs_decrypt(const uint8_t *key, uint8_t *out, size_t
out_size, const uint8_t *in, size_t in_size);
BD_PRIVATE void crypto_aacs_sign(const uint8_t *cert, const uint8_t *priv_key,
uint8_t *signature,
=====================================
src/libaacs/mkb.c
=====================================
@@ -41,10 +41,6 @@ static const uint8_t *_record(MKB *mkb, uint8_t type, size_t
*rec_len)
while (pos + 4 <= mkb->size) {
len = MKINT_BE24(mkb->buf + pos + 1);
- if (rec_len) {
- *rec_len = len;
- }
-
if (mkb->buf[pos] == type) {
BD_DEBUG(DBG_MKB, "Retrieved MKB record 0x%02x (%p)\n", type,
(void*)(mkb->buf + pos));
@@ -55,6 +51,10 @@ static const uint8_t *_record(MKB *mkb, uint8_t type, size_t
*rec_len)
return NULL;
}
+ if (rec_len) {
+ *rec_len = len;
+ }
+
return mkb->buf + pos;
}
=====================================
src/libaacs/mmc.c
=====================================
@@ -539,6 +539,7 @@ static int _read_vid(MMC *mmc, uint8_t agid, const uint8_t
*bus_key, uint8_t *vi
{
uint8_t mac[16], calc_mac[16];
char str[512];
+ int err;
BD_DEBUG(DBG_MMC, "Reading VID from drive...\n");
@@ -549,7 +550,10 @@ static int _read_vid(MMC *mmc, uint8_t agid, const uint8_t
*bus_key, uint8_t *vi
}
/* verify MAC */
- crypto_aes_cmac_16(vid, bus_key, calc_mac);
+ err = crypto_aes_cmac_16(vid, bus_key, calc_mac);
+ if (err) {
+ LOG_CRYPTO_ERROR(DBG_MMC, "VID MAC calculation failed", err);
+ }
if (memcmp(calc_mac, mac, 16)) {
BD_DEBUG(DBG_MMC | DBG_CRIT, "VID MAC is incorrect. This means
this Volume ID is not correct.\n");
}
@@ -566,6 +570,7 @@ static int _read_pmsn(MMC *mmc, uint8_t agid, const uint8_t
*bus_key, uint8_t *p
{
uint8_t mac[16], calc_mac[16];
char str[512];
+ int err;
BD_DEBUG(DBG_MMC, "Reading PMSN from drive...\n");
@@ -576,7 +581,10 @@ static int _read_pmsn(MMC *mmc, uint8_t agid, const
uint8_t *bus_key, uint8_t *p
}
/* verify MAC */
- crypto_aes_cmac_16(pmsn, bus_key, calc_mac);
+ err = crypto_aes_cmac_16(pmsn, bus_key, calc_mac);
+ if (err) {
+ LOG_CRYPTO_ERROR(DBG_MMC, "PMSN MAC calculation failed", err);
+ }
if (memcmp(calc_mac, mac, 16)) {
BD_DEBUG(DBG_MMC | DBG_CRIT, "PMSN MAC is incorrect. This means
this Pre-recorded Medial Serial Number is not correct.\n");
}
@@ -599,13 +607,19 @@ static int _read_data_keys(MMC *mmc, uint8_t agid, const
uint8_t *bus_key,
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);
+ int err = crypto_aes128d(bus_key, encrypted_read_data_key,
read_data_key);
+ if (err) {
+ LOG_CRYPTO_ERROR(DBG_MMC, "decrypting read data key failed",
err);
+ }
if (DEBUG_KEYS) {
BD_DEBUG(DBG_MMC, "READ DATA KEY : %s\n",
str_print_hex(str, read_data_key, 16));
}
}
if (write_data_key) {
- crypto_aes128d(bus_key, encrypted_write_data_key, write_data_key);
+ int err = crypto_aes128d(bus_key, encrypted_write_data_key,
write_data_key);
+ if (err) {
+ LOG_CRYPTO_ERROR(DBG_MMC, "decrypting write data key failed",
err);
+ }
if (DEBUG_KEYS) {
BD_DEBUG(DBG_MMC, "WRITE DATA KEY : %s\n",
str_print_hex(str, write_data_key, 16));
}
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/compare/7cee1c2ac1b0326f4bab3d756b53c5a0ab900002...de0f0c84a41d9e3e12e3e3a49c4e11cb6a0d7dcc
--
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/compare/7cee1c2ac1b0326f4bab3d756b53c5a0ab900002...de0f0c84a41d9e3e12e3e3a49c4e11cb6a0d7dcc
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