]> git.sesse.net Git - vlc/commitdiff
Leverage libgcrypt CounTeR mode implementation to simplify our code
authorRémi Denis-Courmont <rem@videolan.org>
Sun, 11 Mar 2007 14:58:40 +0000 (14:58 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Sun, 11 Mar 2007 14:58:40 +0000 (14:58 +0000)
libs/srtp/srtp.c
libs/srtp/test-aes.c

index 9978ff44d5e1f08e1cc872d3018723a1b0171f0b..a3accb5698a4a0b15babbbbde8d30925ab7e500e 100644 (file)
@@ -229,6 +229,37 @@ srtp_create (int encr, int auth, unsigned tag_len, int prf, unsigned flags)
 }
 
 
+/**
+ * Counter Mode encryption/decryption (ctr length = 16 bytes)
+ * with non-padded (truncated) text
+ */
+static int
+ctr_crypt (gcry_cipher_hd_t hd, const void *ctr, uint8_t *data, size_t len)
+{
+    const size_t ctrlen = 16;
+    div_t d = div (len, ctrlen);
+
+    if (gcry_cipher_setctr (hd, ctr, ctrlen)
+     || gcry_cipher_encrypt (hd, data, d.quot * ctrlen, NULL, 0))
+        return -1;
+
+    if (d.rem)
+    {
+        /* Truncated last block */
+        uint8_t dummy[ctrlen];
+        data += d.quot * ctrlen;
+        memcpy (dummy, data, d.rem);
+        memset (dummy + d.rem, 0, ctrlen - d.rem);
+
+        if (gcry_cipher_encrypt (hd, dummy, ctrlen, data, ctrlen))
+            return -1;
+        memcpy (data, dummy, d.rem);
+    }
+
+    return 0;
+}
+
+
 /**
  * AES-CM key derivation (saltlen = 14 bytes)
  */
@@ -247,29 +278,8 @@ derive (gcry_cipher_hd_t prf, const void *salt,
     for (size_t i = 0; i < rlen; i++)
         iv[sizeof (iv) - rlen + i] ^= r[i];
 
-    /* TODO: retry with CTR mode */
-    while (outlen >= sizeof (iv))
-    {
-        /* AES */
-        if (gcry_cipher_encrypt (prf, out, sizeof (iv), iv, sizeof (iv)))
-            return EINVAL;
-        outlen -= sizeof (iv);
-        out = ((uint8_t *)out) + sizeof (iv);
-
-        /* Increment IV in network byte order */
-        if (++iv[sizeof (iv) - 1] == 0)
-            ++iv[sizeof (iv) -2];
-    }
-
-    if (outlen > 0)
-    {
-        /* Truncated last AES output block */
-        if (gcry_cipher_encrypt (prf, iv, sizeof (iv), NULL, 0))
-            return -1;
-        memcpy (out, iv, outlen);
-    }
-
-    return 0;
+    memset (out, 0, outlen);
+    return ctr_crypt (prf, iv, out, outlen);
 }
 
 
@@ -305,8 +315,7 @@ srtp_derive (srtp_session_t *s, const void *key, size_t keylen,
     gcry_cipher_hd_t prf;
     uint8_t r[6];
 
-    /* TODO: retry with CTR mode */
-    if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)
+    if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, 0)
      || gcry_cipher_setkey (prf, key, keylen))
         return -1;
 
@@ -383,39 +392,6 @@ void srtp_setrcc_rate (srtp_session_t *s, uint16_t rate)
 }
 
 
-/** AES-CM encryption/decryption (ctr length = 16 bytes) */
-static int
-ctr_crypt (gcry_cipher_hd_t hd, uint32_t *ctr, uint8_t *data, size_t len)
-{
-    const size_t ctrlen = 16;
-    while (len >= ctrlen)
-    {
-        if (gcry_cipher_setctr (hd, ctr, ctrlen)
-         || gcry_cipher_encrypt (hd, data, ctrlen, NULL, 0))
-            return -1;
-
-        data += ctrlen;
-        len -= ctrlen;
-        ctr[3] = htonl (ntohl (ctr[3]) + 1);
-    }
-
-    if (len > 0)
-    {
-        /* Truncated last block */
-        uint8_t dummy[ctrlen];
-        memcpy (dummy, data, len);
-        memset (dummy + len, 0, ctrlen - len);
-
-        if (gcry_cipher_setctr (hd, ctr, ctrlen)
-         || gcry_cipher_encrypt (hd, dummy, ctrlen, data, ctrlen))
-            return -1;
-        memcpy (data, dummy, len);
-    }
-
-    return 0;
-}
-
-
 /** AES-CM for RTP (salt = 14 bytes + 2 nul bytes) */
 static int
 rtp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq,
index b06b1e39b4670e484bacc4fa5263cdb5e6304c8b..4892ba2351fcd1b45113014bda38d356f47ba796 100644 (file)
@@ -63,7 +63,7 @@ static void test_derivation (void)
     printf (" master salt: ");
     printhex (salt, sizeof (salt));
 
-    if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)
+    if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, 0)
      || gcry_cipher_setkey (prf, key, sizeof (key)))
         fatal ("Internal PRF error");