From 9c7f833f2441b85d2d959b423f7de30ee59743ff Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 11 Mar 2007 14:58:40 +0000 Subject: [PATCH] Leverage libgcrypt CounTeR mode implementation to simplify our code --- libs/srtp/srtp.c | 92 ++++++++++++++++---------------------------- libs/srtp/test-aes.c | 2 +- 2 files changed, 35 insertions(+), 59 deletions(-) diff --git a/libs/srtp/srtp.c b/libs/srtp/srtp.c index 9978ff44d5..a3accb5698 100644 --- a/libs/srtp/srtp.c +++ b/libs/srtp/srtp.c @@ -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, diff --git a/libs/srtp/test-aes.c b/libs/srtp/test-aes.c index b06b1e39b4..4892ba2351 100644 --- a/libs/srtp/test-aes.c +++ b/libs/srtp/test-aes.c @@ -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"); -- 2.39.2