Commit 9c7f833f authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Leverage libgcrypt CounTeR mode implementation to simplify our code

parent 263b77a3
...@@ -229,6 +229,37 @@ srtp_create (int encr, int auth, unsigned tag_len, int prf, unsigned flags) ...@@ -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) * AES-CM key derivation (saltlen = 14 bytes)
*/ */
...@@ -247,29 +278,8 @@ derive (gcry_cipher_hd_t prf, const void *salt, ...@@ -247,29 +278,8 @@ derive (gcry_cipher_hd_t prf, const void *salt,
for (size_t i = 0; i < rlen; i++) for (size_t i = 0; i < rlen; i++)
iv[sizeof (iv) - rlen + i] ^= r[i]; iv[sizeof (iv) - rlen + i] ^= r[i];
/* TODO: retry with CTR mode */ memset (out, 0, outlen);
while (outlen >= sizeof (iv)) return ctr_crypt (prf, iv, out, outlen);
{
/* 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;
} }
...@@ -305,8 +315,7 @@ srtp_derive (srtp_session_t *s, const void *key, size_t keylen, ...@@ -305,8 +315,7 @@ srtp_derive (srtp_session_t *s, const void *key, size_t keylen,
gcry_cipher_hd_t prf; gcry_cipher_hd_t prf;
uint8_t r[6]; uint8_t r[6];
/* TODO: retry with CTR mode */ if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, 0)
if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0)
|| gcry_cipher_setkey (prf, key, keylen)) || gcry_cipher_setkey (prf, key, keylen))
return -1; return -1;
...@@ -383,39 +392,6 @@ void srtp_setrcc_rate (srtp_session_t *s, uint16_t rate) ...@@ -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) */ /** AES-CM for RTP (salt = 14 bytes + 2 nul bytes) */
static int static int
rtp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq, rtp_crypt (gcry_cipher_hd_t hd, uint32_t ssrc, uint32_t roc, uint16_t seq,
......
...@@ -63,7 +63,7 @@ static void test_derivation (void) ...@@ -63,7 +63,7 @@ static void test_derivation (void)
printf (" master salt: "); printf (" master salt: ");
printhex (salt, sizeof (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))) || gcry_cipher_setkey (prf, key, sizeof (key)))
fatal ("Internal PRF error"); fatal ("Internal PRF error");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment