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
libaacs-devel@videolan.org
https://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to