summaryrefslogtreecommitdiff
path: root/third_party/srtp/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/srtp/crypto')
-rw-r--r--third_party/srtp/crypto/Makefile130
-rw-r--r--third_party/srtp/crypto/Makefile.in75
-rw-r--r--third_party/srtp/crypto/ae_xfm/xfm.c573
-rw-r--r--third_party/srtp/crypto/cipher/aes.c393
-rw-r--r--third_party/srtp/crypto/cipher/aes_cbc.c177
-rw-r--r--third_party/srtp/crypto/cipher/aes_gcm_ossl.c570
-rw-r--r--third_party/srtp/crypto/cipher/aes_icm.c155
-rw-r--r--third_party/srtp/crypto/cipher/aes_icm_ossl.c563
-rw-r--r--third_party/srtp/crypto/cipher/cipher.c147
-rw-r--r--third_party/srtp/crypto/cipher/null_cipher.c19
-rw-r--r--third_party/srtp/crypto/hash/auth.c22
-rw-r--r--third_party/srtp/crypto/hash/hmac.c7
-rw-r--r--third_party/srtp/crypto/hash/hmac_ossl.c302
-rw-r--r--third_party/srtp/crypto/hash/null_auth.c7
-rw-r--r--third_party/srtp/crypto/hash/sha1.c16
-rw-r--r--third_party/srtp/crypto/include/aes.h26
-rw-r--r--third_party/srtp/crypto/include/aes_cbc.h42
-rw-r--r--third_party/srtp/crypto/include/aes_gcm_ossl.h63
-rw-r--r--third_party/srtp/crypto/include/aes_icm.h46
-rw-r--r--third_party/srtp/crypto/include/aes_icm_ossl.h85
-rw-r--r--third_party/srtp/crypto/include/auth.h12
-rw-r--r--third_party/srtp/crypto/include/cipher.h68
-rw-r--r--third_party/srtp/crypto/include/crypto.h36
-rw-r--r--third_party/srtp/crypto/include/crypto_kernel.h25
-rw-r--r--third_party/srtp/crypto/include/crypto_math.h34
-rw-r--r--third_party/srtp/crypto/include/crypto_types.h62
-rw-r--r--third_party/srtp/crypto/include/datatypes.h95
-rw-r--r--third_party/srtp/crypto/include/err.h11
-rw-r--r--third_party/srtp/crypto/include/hmac.h6
-rw-r--r--third_party/srtp/crypto/include/integers.h6
-rw-r--r--third_party/srtp/crypto/include/null_cipher.h4
-rw-r--r--third_party/srtp/crypto/include/prng.h41
-rw-r--r--third_party/srtp/crypto/include/rdb.h40
-rw-r--r--third_party/srtp/crypto/include/rdbx.h86
-rw-r--r--third_party/srtp/crypto/include/sha1.h44
-rw-r--r--third_party/srtp/crypto/include/xfm.h36
-rw-r--r--third_party/srtp/crypto/kernel/alloc.c12
-rw-r--r--third_party/srtp/crypto/kernel/crypto_kernel.c131
-rw-r--r--third_party/srtp/crypto/kernel/err.c10
-rw-r--r--third_party/srtp/crypto/kernel/key.c4
-rw-r--r--third_party/srtp/crypto/math/datatypes.c372
-rw-r--r--third_party/srtp/crypto/math/gf2_8.c6
-rw-r--r--third_party/srtp/crypto/math/math.c174
-rw-r--r--third_party/srtp/crypto/math/stat.c40
-rw-r--r--third_party/srtp/crypto/replay/rdb.c20
-rw-r--r--third_party/srtp/crypto/replay/rdbx.c107
-rw-r--r--third_party/srtp/crypto/replay/ut_sim.c4
-rw-r--r--third_party/srtp/crypto/rng/ctr_prng.c14
-rw-r--r--third_party/srtp/crypto/rng/prng.c18
-rw-r--r--third_party/srtp/crypto/rng/rand_source.c75
-rw-r--r--third_party/srtp/crypto/rng/rand_source_ossl.c70
-rw-r--r--third_party/srtp/crypto/test/aes_calc.c78
-rw-r--r--third_party/srtp/crypto/test/cipher_driver.c199
-rw-r--r--third_party/srtp/crypto/test/datatypes_driver.c6
-rw-r--r--third_party/srtp/crypto/test/env.c4
-rw-r--r--third_party/srtp/crypto/test/kernel_driver.c13
-rw-r--r--third_party/srtp/crypto/test/rand_gen.c15
-rw-r--r--third_party/srtp/crypto/test/rand_gen_soak.c116
-rw-r--r--third_party/srtp/crypto/test/sha1_driver.c33
-rw-r--r--third_party/srtp/crypto/test/stat_driver.c157
60 files changed, 4097 insertions, 1605 deletions
diff --git a/third_party/srtp/crypto/Makefile b/third_party/srtp/crypto/Makefile
deleted file mode 100644
index d7ac61fb..00000000
--- a/third_party/srtp/crypto/Makefile
+++ /dev/null
@@ -1,130 +0,0 @@
-# Makefile for libcryptomodule.a
-#
-# David A. McGrew
-# Cisco Systems, Inc.
-
-srcdir = .
-top_srcdir = ..
-top_builddir = ../
-
-
-CC = gcc
-INCDIR = -Iinclude -I$(srcdir)/include
-DEFS = -DHAVE_CONFIG_H
-CPPFLAGS=
-CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops
-LIBS =
-LDFLAGS = -L.
-COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
-CRYPTOLIB = -lcryptomodule
-
-RANLIB = ranlib
-
-# EXE defines the suffix on executables - it's .exe for cygwin, and
-# null on linux, bsd, and OS X and other OSes. we define this so that
-# `make clean` will work on the cygwin platform
-EXE =
-# Random source.
-RNG_OBJS = rand_source.o
-
-ifdef ARCH
- DEFS += -D$(ARCH)=1
-endif
-
-ifdef sysname
- DEFS += -D$(sysname)=1
-endif
-
-.PHONY: dummy all runtest clean superclean
-
-dummy : all runtest
-
-# test applications
-
-testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
- test/stat_driver$(EXE) test/sha1_driver$(EXE) \
- test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \
- test/env$(EXE)
-
-# data values used to test the aes_calc application
-
-k=000102030405060708090a0b0c0d0e0f
-p=00112233445566778899aabbccddeeff
-c=69c4e0d86a7b0430d8cdb78070b4c55a
-
-runtest: libcryptomodule.a $(testapp)
- test/env$(EXE) # print out information on the build environment
- @echo "running libcryptomodule test applications..."
- test `test/aes_calc $k $p` = $c
- test/cipher_driver$(EXE) -v >/dev/null
- test/datatypes_driver$(EXE) -v >/dev/null
- test/stat_driver$(EXE) >/dev/null
- test/sha1_driver$(EXE) -v >/dev/null
- test/kernel_driver$(EXE) -v >/dev/null
- test/rand_gen$(EXE) -n 256 >/dev/null
- @echo "libcryptomodule test applications passed."
-
-# libcryptomodule.a (the crypto engine)
-
-ciphers = cipher/cipher.o cipher/null_cipher.o \
- cipher/aes.o cipher/aes_icm.o \
- cipher/aes_cbc.o
-
-hashes = hash/null_auth.o hash/sha1.o \
- hash/hmac.o hash/auth.o
-
-math = math/datatypes.o math/stat.o
-
-rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o
-
-err = kernel/err.o
-
-kernel = kernel/crypto_kernel.o kernel/alloc.o \
- kernel/key.o $(rng) $(err)
-
-xfm = ae_xfm/xfm.o
-
-cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)
-
-# the rule for making object files and test apps
-
-%.o: %.c
- $(COMPILE) -c $< -o $@
-
-%$(EXE): %.c libcryptomodule.a
- $(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)
-
-ifndef AR
- AR=ar
-endif
-
-# and the crypto module library itself
-
-libcryptomodule.a: $(cryptobj)
- $(AR) cr libcryptomodule.a $(cryptobj)
- $(RANLIB) libcryptomodule.a
-
-all: libcryptomodule.a $(testapp)
-
-# housekeeping functions
-
-clean:
- rm -f libcryptomodule.a
- rm -f $(testapp) *.o */*.o
- for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
- rm -f `find . -name "*.[ch]~*~"`
- rm -rf latex
-
-superclean: clean
- rm -f *core TAGS ktrace.out
-
-
-# the target 'package' builds a compressed tar archive of the source code
-
-distname = crypto-$(shell cat VERSION)
-
-package: superclean
- cd ..; tar cvzf $(distname).tgz crypto/
-
-
-# EOF
diff --git a/third_party/srtp/crypto/Makefile.in b/third_party/srtp/crypto/Makefile.in
index c14dba50..49384376 100644
--- a/third_party/srtp/crypto/Makefile.in
+++ b/third_party/srtp/crypto/Makefile.in
@@ -9,14 +9,14 @@ top_builddir = @top_builddir@
VPATH = @srcdir@
CC = @CC@
-INCDIR = -Iinclude -I$(srcdir)/include
+INCDIR = -Iinclude -I$(srcdir)/include -I$(top_srcdir)/include
DEFS = @DEFS@
CPPFLAGS= @CPPFLAGS@
CFLAGS = @CFLAGS@
LIBS = @LIBS@
-LDFLAGS = @LDFLAGS@ -L.
+LDFLAGS = @LDFLAGS@ -L. -L..
COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
-CRYPTOLIB = -lcryptomodule
+CRYPTOLIB = -lsrtp
RANLIB = @RANLIB@
@@ -25,7 +25,7 @@ RANLIB = @RANLIB@
# `make clean` will work on the cygwin platform
EXE = @EXE@
# Random source.
-RNG_OBJS = @RNG_OBJS@
+USE_OPENSSL = @USE_OPENSSL@
ifdef ARCH
DEFS += -D$(ARCH)=1
@@ -40,71 +40,52 @@ endif
dummy : all runtest
# test applications
+ifneq (1, $(USE_OPENSSL))
+AES_CALC = test/aes_calc$(EXE)
+endif
testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
test/stat_driver$(EXE) test/sha1_driver$(EXE) \
- test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \
+ test/kernel_driver$(EXE) $(AES_CALC) test/rand_gen$(EXE) \
test/env$(EXE)
-# data values used to test the aes_calc application
+# data values used to test the aes_calc application for AES-128
+k128=000102030405060708090a0b0c0d0e0f
+p128=00112233445566778899aabbccddeeff
+c128=69c4e0d86a7b0430d8cdb78070b4c55a
+
-k=000102030405060708090a0b0c0d0e0f
-p=00112233445566778899aabbccddeeff
-c=69c4e0d86a7b0430d8cdb78070b4c55a
+# data values used to test the aes_calc application for AES-256
+k256=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+p256=00112233445566778899aabbccddeeff
+c256=8ea2b7ca516745bfeafc49904b496089
-runtest: libcryptomodule.a $(testapp)
+
+runtest: $(testapp)
test/env$(EXE) # print out information on the build environment
- @echo "running libcryptomodule test applications..."
- test `test/aes_calc $k $p` = $c
+ @echo "running crypto test applications..."
+ifneq (1, $(USE_OPENSSL))
+ test `test/aes_calc $(k128) $(p128)` = $(c128)
+ test `test/aes_calc $(k256) $(p256)` = $(c256)
+endif
test/cipher_driver$(EXE) -v >/dev/null
test/datatypes_driver$(EXE) -v >/dev/null
test/stat_driver$(EXE) >/dev/null
test/sha1_driver$(EXE) -v >/dev/null
test/kernel_driver$(EXE) -v >/dev/null
test/rand_gen$(EXE) -n 256 >/dev/null
- @echo "libcryptomodule test applications passed."
-
-# libcryptomodule.a (the crypto engine)
-
-ciphers = cipher/cipher.o cipher/null_cipher.o \
- cipher/aes.o cipher/aes_icm.o \
- cipher/aes_cbc.o
-
-hashes = hash/null_auth.o hash/sha1.o \
- hash/hmac.o hash/auth.o
-
-math = math/datatypes.o math/stat.o
+ @echo "crypto test applications passed."
-rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o
-
-err = kernel/err.o
-
-kernel = kernel/crypto_kernel.o kernel/alloc.o \
- kernel/key.o $(rng) $(err)
-
-xfm = ae_xfm/xfm.o
-
-cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)
# the rule for making object files and test apps
%.o: %.c
$(COMPILE) -c $< -o $@
-%$(EXE): %.c libcryptomodule.a
- $(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)
-
-ifndef AR
- AR=ar
-endif
-
-# and the crypto module library itself
-
-libcryptomodule.a: $(cryptobj)
- $(AR) cr libcryptomodule.a $(cryptobj)
- $(RANLIB) libcryptomodule.a
+%$(EXE): %.c ../test/getopt_s.c
+ $(COMPILE) $(LDFLAGS) $< ../test/getopt_s.c -o $@ $(CRYPTOLIB) $(LIBS)
-all: libcryptomodule.a $(testapp)
+all: $(testapp)
# housekeeping functions
diff --git a/third_party/srtp/crypto/ae_xfm/xfm.c b/third_party/srtp/crypto/ae_xfm/xfm.c
deleted file mode 100644
index 0655aca4..00000000
--- a/third_party/srtp/crypto/ae_xfm/xfm.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * xfm.c
- *
- * Crypto transform implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-#include "cryptoalg.h"
-#include "aes_cbc.h"
-#include "hmac.h"
-#include "crypto_kernel.h" /* for crypto_get_random() */
-
-#define KEY_LEN 16
-#define ENC_KEY_LEN 16
-#define MAC_KEY_LEN 16
-#define IV_LEN 16
-#define TAG_LEN 12
-#define MAX_EXPAND 27
-
-err_status_t
-aes_128_cbc_hmac_sha1_96_func(void *key,
- void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len,
- void *auth_tag) {
- aes_cbc_ctx_t aes_ctx;
- hmac_ctx_t hmac_ctx;
- unsigned char enc_key[ENC_KEY_LEN];
- unsigned char mac_key[MAC_KEY_LEN];
- err_status_t status;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-
- /* derive encryption and authentication keys from the input key */
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
- if (status) return status;
-
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
- if (status) return status;
-
-
- /* perform encryption and authentication */
-
- /* set aes key */
- status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
- if (status) return status;
-
- /* set iv */
- status = crypto_get_random(iv, IV_LEN);
- if (status) return status;
- status = aes_cbc_set_iv(&aes_ctx, iv);
-
- /* encrypt the opaque data */
- status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
- if (status) return status;
-
- /* authenticate clear and opaque data */
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
- if (status) return status;
-
- status = hmac_start(&hmac_ctx);
- if (status) return status;
-
- status = hmac_update(&hmac_ctx, clear, clear_len);
- if (status) return status;
-
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
- if (status) return status;
-
- }
-
- return err_status_ok;
-}
-
-err_status_t
-aes_128_cbc_hmac_sha1_96_inv(void *key,
- void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len,
- void *auth_tag) {
- aes_cbc_ctx_t aes_ctx;
- hmac_ctx_t hmac_ctx;
- unsigned char enc_key[ENC_KEY_LEN];
- unsigned char mac_key[MAC_KEY_LEN];
- unsigned char tmp_tag[TAG_LEN];
- unsigned char *tag = auth_tag;
- err_status_t status;
- int i;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-
- /* derive encryption and authentication keys from the input key */
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
- if (status) return status;
-
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
- if (status) return status;
-
- /* perform encryption and authentication */
-
- /* set aes key */
- status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
- if (status) return status;
-
- /* set iv */
- status = rand_source_get_octet_string(iv, IV_LEN);
- if (status) return status;
- status = aes_cbc_set_iv(&aes_ctx, iv);
-
- /* encrypt the opaque data */
- status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
- if (status) return status;
-
- /* authenticate clear and opaque data */
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
- if (status) return status;
-
- status = hmac_start(&hmac_ctx);
- if (status) return status;
-
- status = hmac_update(&hmac_ctx, clear, clear_len);
- if (status) return status;
-
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
- if (status) return status;
-
- /* compare the computed tag with the one provided as input */
- for (i=0; i < TAG_LEN; i++)
- if (tmp_tag[i] != tag[i])
- return err_status_auth_fail;
-
- }
-
- return err_status_ok;
-}
-
-
-#define ENC 1
-
-// eVC4 declares DEBUG
-#undef DEBUG
-
-#define DEBUG 0
-
-err_status_t
-aes_128_cbc_hmac_sha1_96_enc(void *key,
- const void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len) {
- aes_cbc_ctx_t aes_ctx;
- hmac_ctx_t hmac_ctx;
- unsigned char enc_key[ENC_KEY_LEN];
- unsigned char mac_key[MAC_KEY_LEN];
- unsigned char *auth_tag;
- err_status_t status;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-
-#if DEBUG
- printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
-#endif
-
- /* derive encryption and authentication keys from the input key */
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
- if (status) return status;
-
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
- if (status) return status;
-
-
- /* perform encryption and authentication */
-
- /* set aes key */
- status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
- if (status) return status;
-
- /* set iv */
- status = rand_source_get_octet_string(iv, IV_LEN);
- if (status) return status;
- status = aes_cbc_set_iv(&aes_ctx, iv);
- if (status) return status;
-
-#if DEBUG
- printf("plaintext len: %d\n", *opaque_len);
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
- printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len));
-#endif
-
-#if ENC
- /* encrypt the opaque data */
- status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
- if (status) return status;
-#endif
-
-#if DEBUG
- printf("ciphertext len: %d\n", *opaque_len);
- printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
-#endif
-
- /*
- * authenticate clear and opaque data, then write the
- * authentication tag to the location immediately following the
- * ciphertext
- */
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
- if (status) return status;
-
- status = hmac_start(&hmac_ctx);
- if (status) return status;
-
- status = hmac_update(&hmac_ctx, clear, clear_len);
- if (status) return status;
-#if DEBUG
- printf("hmac input: %s\n",
- octet_string_hex_string(clear, clear_len));
-#endif
- auth_tag = (unsigned char *)opaque;
- auth_tag += *opaque_len;
- status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
- if (status) return status;
-#if DEBUG
- printf("hmac input: %s\n",
- octet_string_hex_string(opaque, *opaque_len));
-#endif
- /* bump up the opaque_len to reflect the authentication tag */
- *opaque_len += TAG_LEN;
-
-#if DEBUG
- printf("prot data len: %d\n", *opaque_len);
- printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
-#endif
- }
-
- return err_status_ok;
-}
-
-err_status_t
-aes_128_cbc_hmac_sha1_96_dec(void *key,
- const void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len) {
- aes_cbc_ctx_t aes_ctx;
- hmac_ctx_t hmac_ctx;
- unsigned char enc_key[ENC_KEY_LEN];
- unsigned char mac_key[MAC_KEY_LEN];
- unsigned char tmp_tag[TAG_LEN];
- unsigned char *auth_tag;
- unsigned ciphertext_len;
- err_status_t status;
- int i;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-#if DEBUG
- printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
-#endif
-
- /* derive encryption and authentication keys from the input key */
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
- if (status) return status;
-
- status = hmac_init(&hmac_ctx, key, KEY_LEN);
- if (status) return status;
- status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
- if (status) return status;
-
-#if DEBUG
- printf("prot data len: %d\n", *opaque_len);
- printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
-#endif
-
- /*
- * set the protected data length to that of the ciphertext, by
- * subtracting out the length of the authentication tag
- */
- ciphertext_len = *opaque_len - TAG_LEN;
-
-#if DEBUG
- printf("ciphertext len: %d\n", ciphertext_len);
-#endif
- /* verify the authentication tag */
-
- /*
- * compute the authentication tag for the clear and opaque data,
- * and write it to a temporary location
- */
- status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
- if (status) return status;
-
- status = hmac_start(&hmac_ctx);
- if (status) return status;
-
- status = hmac_update(&hmac_ctx, clear, clear_len);
- if (status) return status;
-
-#if DEBUG
- printf("hmac input: %s\n",
- octet_string_hex_string(clear, clear_len));
-#endif
-
- status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
- if (status) return status;
-
-#if DEBUG
- printf("hmac input: %s\n",
- octet_string_hex_string(opaque, ciphertext_len));
-#endif
-
- /*
- * compare the computed tag with the one provided as input (which
- * immediately follows the ciphertext)
- */
- auth_tag = (unsigned char *)opaque;
- auth_tag += ciphertext_len;
-#if DEBUG
- printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));
- printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));
-#endif
- for (i=0; i < TAG_LEN; i++) {
- if (tmp_tag[i] != auth_tag[i])
- return err_status_auth_fail;
- }
-
- /* bump down the opaque_len to reflect the authentication tag */
- *opaque_len -= TAG_LEN;
-
- /* decrypt the confidential data */
- status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
- if (status) return status;
- status = aes_cbc_set_iv(&aes_ctx, iv);
- if (status) return status;
-
-#if DEBUG
- printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
-#endif
-
-#if ENC
- status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
- if (status) return status;
-#endif
-
-#if DEBUG
- printf("plaintext len: %d\n", ciphertext_len);
- printf("plaintext: %s\n",
- octet_string_hex_string(opaque, ciphertext_len));
-#endif
-
- /* indicate the length of the plaintext */
- *opaque_len = ciphertext_len;
- }
-
- return err_status_ok;
-}
-
-cryptoalg_ctx_t cryptoalg_ctx = {
- aes_128_cbc_hmac_sha1_96_enc,
- aes_128_cbc_hmac_sha1_96_dec,
- KEY_LEN,
- IV_LEN,
- TAG_LEN,
- MAX_EXPAND,
-};
-
-cryptoalg_t cryptoalg = &cryptoalg_ctx;
-
-#define NULL_TAG_LEN 12
-
-err_status_t
-null_enc(void *key,
- const void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len) {
- int i;
- unsigned char *auth_tag;
- unsigned char *init_vec = iv;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-
-#if DEBUG
- printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
- printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN);
- printf("plaintext len: %d\n", *opaque_len);
-#endif
- for (i=0; i < IV_LEN; i++)
- init_vec[i] = i + (i * 16);
-#if DEBUG
- printf("iv: %s\n",
- octet_string_hex_string(iv, IV_LEN));
- printf("plaintext: %s\n",
- octet_string_hex_string(opaque, *opaque_len));
-#endif
- auth_tag = opaque;
- auth_tag += *opaque_len;
- for (i=0; i < NULL_TAG_LEN; i++)
- auth_tag[i] = i + (i * 16);
- *opaque_len += NULL_TAG_LEN;
-#if DEBUG
- printf("protected data len: %d\n", *opaque_len);
- printf("protected data: %s\n",
- octet_string_hex_string(opaque, *opaque_len));
-#endif
-
- }
-
- return err_status_ok;
-}
-
-err_status_t
-null_dec(void *key,
- const void *clear,
- unsigned clear_len,
- void *iv,
- void *opaque,
- unsigned *opaque_len) {
- unsigned char *auth_tag;
-
- /* check if we're doing authentication only */
- if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-
- /* perform authentication only */
-
- } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-
- /*
- * bad parameter - we expect either all three pointers to be NULL,
- * or none of those pointers to be NULL
- */
- return err_status_fail;
-
- } else {
-
-#if DEBUG
- printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
-
- printf("protected data len: %d\n", *opaque_len);
- printf("protected data: %s\n",
- octet_string_hex_string(opaque, *opaque_len));
-#endif
- auth_tag = opaque;
- auth_tag += (*opaque_len - NULL_TAG_LEN);
-#if DEBUG
- printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
-#endif
- *opaque_len -= NULL_TAG_LEN;
-#if DEBUG
- printf("plaintext len: %d\n", *opaque_len);
- printf("plaintext: %s\n",
- octet_string_hex_string(opaque, *opaque_len));
-#endif
- }
-
- return err_status_ok;
-}
-
-cryptoalg_ctx_t null_cryptoalg_ctx = {
- null_enc,
- null_dec,
- KEY_LEN,
- IV_LEN,
- NULL_TAG_LEN,
- MAX_EXPAND,
-};
-
-cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
-
-int
-cryptoalg_get_id(cryptoalg_t c) {
- if (c == cryptoalg)
- return 1;
- return 0;
-}
-
-cryptoalg_t
-cryptoalg_find_by_id(int id) {
- switch(id) {
- case 1:
- return cryptoalg;
- default:
- break;
- }
- return 0;
-}
diff --git a/third_party/srtp/crypto/cipher/aes.c b/third_party/srtp/crypto/cipher/aes.c
index f1286c36..e91e5254 100644
--- a/third_party/srtp/crypto/cipher/aes.c
+++ b/third_party/srtp/crypto/cipher/aes.c
@@ -43,6 +43,9 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#include "aes.h"
#include "err.h"
@@ -1358,51 +1361,50 @@ static uint32_t U4[256] = {
extern debug_module_t mod_aes_icm;
-void
-aes_expand_encryption_key(const v128_t *key,
- aes_expanded_key_t expanded_key) {
+static void
+aes_128_expand_encryption_key(const uint8_t *key,
+ aes_expanded_key_t *expanded_key) {
int i;
gf2_8 rc;
/* initialize round constant */
rc = 1;
- expanded_key[0].v32[0] = key->v32[0];
- expanded_key[0].v32[1] = key->v32[1];
- expanded_key[0].v32[2] = key->v32[2];
- expanded_key[0].v32[3] = key->v32[3];
+ expanded_key->num_rounds = 10;
+
+ v128_copy_octet_string(&expanded_key->round[0], key);
#if 0
debug_print(mod_aes_icm,
- "expanded key[0]: %s", v128_hex_string(&expanded_key[0]));
+ "expanded key[0]: %s", v128_hex_string(&expanded_key->round[0]));
#endif
/* loop over round keys */
for (i=1; i < 11; i++) {
/* munge first word of round key */
- expanded_key[i].v8[0] = aes_sbox[expanded_key[i-1].v8[13]] ^ rc;
- expanded_key[i].v8[1] = aes_sbox[expanded_key[i-1].v8[14]];
- expanded_key[i].v8[2] = aes_sbox[expanded_key[i-1].v8[15]];
- expanded_key[i].v8[3] = aes_sbox[expanded_key[i-1].v8[12]];
+ expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
+ expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
+ expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
+ expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
- expanded_key[i].v32[0] ^= expanded_key[i-1].v32[0];
+ expanded_key->round[i].v32[0] ^= expanded_key->round[i-1].v32[0];
/* set remaining 32 bit words to the exor of the one previous with
* the one four words previous */
- expanded_key[i].v32[1] =
- expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1];
+ expanded_key->round[i].v32[1] =
+ expanded_key->round[i].v32[0] ^ expanded_key->round[i-1].v32[1];
- expanded_key[i].v32[2] =
- expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2];
+ expanded_key->round[i].v32[2] =
+ expanded_key->round[i].v32[1] ^ expanded_key->round[i-1].v32[2];
- expanded_key[i].v32[3] =
- expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3];
+ expanded_key->round[i].v32[3] =
+ expanded_key->round[i].v32[2] ^ expanded_key->round[i-1].v32[3];
#if 0
debug_print2(mod_aes_icm,
- "expanded key[%d]: %s", i,v128_hex_string(&expanded_key[i]));
+ "expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i]));
#endif
/* modify round constant */
@@ -1411,19 +1413,107 @@ aes_expand_encryption_key(const v128_t *key,
}
}
-void
-aes_expand_decryption_key(const v128_t *key,
- aes_expanded_key_t expanded_key) {
+static void
+aes_256_expand_encryption_key(const unsigned char *key,
+ aes_expanded_key_t *expanded_key) {
+ int i;
+ gf2_8 rc;
+
+ /* initialize round constant */
+ rc = 1;
+
+ expanded_key->num_rounds = 14;
+
+ v128_copy_octet_string(&expanded_key->round[0], key);
+ v128_copy_octet_string(&expanded_key->round[1], key+16);
+
+#if 0
+ debug_print(mod_aes_icm,
+ "expanded key[0]: %s", v128_hex_string(&expanded_key->round[0]));
+ debug_print(mod_aes_icm,
+ "expanded key[1]: %s", v128_hex_string(&expanded_key->round[1]));
+#endif
+
+ /* loop over rest of round keys */
+ for (i=2; i < 15; i++) {
+
+ /* munge first word of round key */
+ if ((i & 1) == 0) {
+ expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
+ expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
+ expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
+ expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
+
+ /* modify round constant */
+ rc = gf2_8_shift(rc);
+ }
+ else {
+ expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[12]];
+ expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[13]];
+ expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[14]];
+ expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[15]];
+ }
+
+ expanded_key->round[i].v32[0] ^= expanded_key->round[i-2].v32[0];
+
+ /* set remaining 32 bit words to the exor of the one previous with
+ * the one eight words previous */
+
+ expanded_key->round[i].v32[1] =
+ expanded_key->round[i].v32[0] ^ expanded_key->round[i-2].v32[1];
+
+ expanded_key->round[i].v32[2] =
+ expanded_key->round[i].v32[1] ^ expanded_key->round[i-2].v32[2];
+
+ expanded_key->round[i].v32[3] =
+ expanded_key->round[i].v32[2] ^ expanded_key->round[i-2].v32[3];
+
+#if 0
+ debug_print2(mod_aes_icm,
+ "expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i]));
+#endif
+
+ }
+}
+
+err_status_t
+aes_expand_encryption_key(const uint8_t *key,
+ int key_len,
+ aes_expanded_key_t *expanded_key) {
+ if (key_len == 16) {
+ aes_128_expand_encryption_key(key, expanded_key);
+ return err_status_ok;
+ }
+ else if (key_len == 24) {
+ /* AES-192 not yet supported */
+ return err_status_bad_param;
+ }
+ else if (key_len == 32) {
+ aes_256_expand_encryption_key(key, expanded_key);
+ return err_status_ok;
+ }
+ else
+ return err_status_bad_param;
+}
+
+err_status_t
+aes_expand_decryption_key(const uint8_t *key,
+ int key_len,
+ aes_expanded_key_t *expanded_key) {
int i;
+ err_status_t status;
+ int num_rounds = expanded_key->num_rounds;
- aes_expand_encryption_key(key, expanded_key);
+ status = aes_expand_encryption_key(key, key_len, expanded_key);
+ if (status)
+ return status;
/* invert the order of the round keys */
- for (i=0; i < 5; i++) {
+ for (i=0; i < num_rounds/2; i++) {
v128_t tmp;
- v128_copy(&tmp, &expanded_key[10-i]);
- v128_copy(&expanded_key[10-i], &expanded_key[i]);
- v128_copy(&expanded_key[i], &tmp);
+ v128_copy(&tmp, &expanded_key->round[num_rounds-i]);
+ v128_copy(&expanded_key->round[num_rounds-i], &expanded_key->round[i]);
+ v128_copy(&expanded_key->round[i], &tmp);
}
/*
@@ -1434,68 +1524,101 @@ aes_expand_decryption_key(const v128_t *key,
* followed by the T4 table (which cancels out the use of the sbox
* in the U-tables)
*/
- for (i=1; i < 10; i++) {
+ for (i=1; i < num_rounds; i++) {
#ifdef CPU_RISC
uint32_t tmp;
- tmp = expanded_key[i].v32[0];
- expanded_key[i].v32[0] =
+#ifdef WORDS_BIGENDIAN
+ tmp = expanded_key->round[i].v32[0];
+ expanded_key->round[i].v32[0] =
U0[T4[(tmp >> 24) ] & 0xff] ^
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
U3[T4[(tmp) & 0xff] & 0xff];
- tmp = expanded_key[i].v32[1];
- expanded_key[i].v32[1] =
+ tmp = expanded_key->round[i].v32[1];
+ expanded_key->round[i].v32[1] =
U0[T4[(tmp >> 24) ] & 0xff] ^
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
U3[T4[(tmp) & 0xff] & 0xff];
- tmp = expanded_key[i].v32[2];
- expanded_key[i].v32[2] =
+ tmp = expanded_key->round[i].v32[2];
+ expanded_key->round[i].v32[2] =
U0[T4[(tmp >> 24) ] & 0xff] ^
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
U3[T4[(tmp) & 0xff] & 0xff];
- tmp = expanded_key[i].v32[3];
- expanded_key[i].v32[3] =
+ tmp = expanded_key->round[i].v32[3];
+ expanded_key->round[i].v32[3] =
U0[T4[(tmp >> 24) ] & 0xff] ^
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
U3[T4[(tmp) & 0xff] & 0xff];
+#else
+ tmp = expanded_key->round[i].v32[0];
+ expanded_key->round[i].v32[0] =
+ U3[T4[(tmp >> 24) ] & 0xff] ^
+ U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+ U1[T4[(tmp >> 8) & 0xff] & 0xff] ^
+ U0[T4[(tmp) & 0xff] & 0xff];
+
+ tmp = expanded_key->round[i].v32[1];
+ expanded_key->round[i].v32[1] =
+ U3[T4[(tmp >> 24) ] & 0xff] ^
+ U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+ U1[T4[(tmp >> 8) & 0xff] & 0xff] ^
+ U0[T4[(tmp) & 0xff] & 0xff];
+
+ tmp = expanded_key->round[i].v32[2];
+ expanded_key->round[i].v32[2] =
+ U3[T4[(tmp >> 24) ] & 0xff] ^
+ U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+ U1[T4[(tmp >> 8) & 0xff] & 0xff] ^
+ U0[T4[(tmp) & 0xff] & 0xff];
+
+ tmp = expanded_key->round[i].v32[3];
+ expanded_key->round[i].v32[3] =
+ U3[T4[(tmp >> 24) ] & 0xff] ^
+ U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+ U1[T4[(tmp >> 8) & 0xff] & 0xff] ^
+ U0[T4[(tmp) & 0xff] & 0xff];
+#endif /* WORDS_BIGENDIAN */
+
#else /* assume CPU_CISC */
uint32_t c0, c1, c2, c3;
- c0 = U0[aes_sbox[expanded_key[i].v8[0]]]
- ^ U1[aes_sbox[expanded_key[i].v8[1]]]
- ^ U2[aes_sbox[expanded_key[i].v8[2]]]
- ^ U3[aes_sbox[expanded_key[i].v8[3]]];
+ c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]]
+ ^ U1[aes_sbox[expanded_key->round[i].v8[1]]]
+ ^ U2[aes_sbox[expanded_key->round[i].v8[2]]]
+ ^ U3[aes_sbox[expanded_key->round[i].v8[3]]];
- c1 = U0[aes_sbox[expanded_key[i].v8[4]]]
- ^ U1[aes_sbox[expanded_key[i].v8[5]]]
- ^ U2[aes_sbox[expanded_key[i].v8[6]]]
- ^ U3[aes_sbox[expanded_key[i].v8[7]]];
+ c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]]
+ ^ U1[aes_sbox[expanded_key->round[i].v8[5]]]
+ ^ U2[aes_sbox[expanded_key->round[i].v8[6]]]
+ ^ U3[aes_sbox[expanded_key->round[i].v8[7]]];
- c2 = U0[aes_sbox[expanded_key[i].v8[8]]]
- ^ U1[aes_sbox[expanded_key[i].v8[9]]]
- ^ U2[aes_sbox[expanded_key[i].v8[10]]]
- ^ U3[aes_sbox[expanded_key[i].v8[11]]];
+ c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]]
+ ^ U1[aes_sbox[expanded_key->round[i].v8[9]]]
+ ^ U2[aes_sbox[expanded_key->round[i].v8[10]]]
+ ^ U3[aes_sbox[expanded_key->round[i].v8[11]]];
- c3 = U0[aes_sbox[expanded_key[i].v8[12]]]
- ^ U1[aes_sbox[expanded_key[i].v8[13]]]
- ^ U2[aes_sbox[expanded_key[i].v8[14]]]
- ^ U3[aes_sbox[expanded_key[i].v8[15]]];
+ c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]]
+ ^ U1[aes_sbox[expanded_key->round[i].v8[13]]]
+ ^ U2[aes_sbox[expanded_key->round[i].v8[14]]]
+ ^ U3[aes_sbox[expanded_key->round[i].v8[15]]];
- expanded_key[i].v32[0] = c0;
- expanded_key[i].v32[1] = c1;
- expanded_key[i].v32[2] = c2;
- expanded_key[i].v32[3] = c3;
+ expanded_key->round[i].v32[0] = c0;
+ expanded_key->round[i].v32[1] = c1;
+ expanded_key->round[i].v32[2] = c2;
+ expanded_key->round[i].v32[3] = c3;
#endif
}
+
+ return err_status_ok;
}
#ifdef CPU_CISC
@@ -1676,7 +1799,6 @@ aes_inv_round(v128_t *state, const v128_t *round_key) {
of state, using the tables U0, U1, U2, U3 */
#ifdef WORDS_BIGENDIAN
- /* FIX! WRong indexes */
column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff]
^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
@@ -1689,17 +1811,17 @@ aes_inv_round(v128_t *state, const v128_t *round_key) {
column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff]
^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
#else
- column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff]
- ^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[state->v32[3] >> 24];
+ column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff]
+ ^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[(state->v32[1] >> 24) & 0xff];
- column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff]
- ^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[state->v32[0] >> 24];
+ column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff]
+ ^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[(state->v32[2] >> 24) & 0xff];
- column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff]
- ^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[state->v32[1] >> 24];
+ column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff]
+ ^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[(state->v32[3] >> 24) & 0xff];
- column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff]
- ^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[state->v32[2] >> 24];
+ column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff]
+ ^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[(state->v32[0] >> 24) & 0xff];
#endif /* WORDS_BIGENDIAN */
state->v32[0] = column0 ^ round_key->v32[0];
@@ -1713,6 +1835,7 @@ static inline void
aes_final_round(v128_t *state, const v128_t *round_key) {
uint32_t tmp0, tmp1, tmp2, tmp3;
+#ifdef WORDS_BIGENDIAN
tmp0 = (T4[(state->v32[0] >> 24)] & 0xff000000)
^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
@@ -1736,6 +1859,31 @@ aes_final_round(v128_t *state, const v128_t *round_key) {
^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
+#else
+ tmp0 = (T4[(state->v32[3] >> 24)] & 0xff000000)
+ ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
+ ^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
+ ^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[0];
+
+ tmp1 = (T4[(state->v32[0] >> 24)] & 0xff000000)
+ ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
+ ^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
+ ^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[1];
+
+ tmp2 = (T4[(state->v32[1] >> 24)] & 0xff000000)
+ ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
+ ^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
+ ^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[2];
+
+ tmp3 = (T4[(state->v32[2] >> 24)] & 0xff000000)
+ ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
+ ^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
+ ^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[3];
+#endif /* WORDS_BIGENDIAN */
state->v32[0] = tmp0;
state->v32[1] = tmp1;
@@ -1748,6 +1896,7 @@ static inline void
aes_inv_final_round(v128_t *state, const v128_t *round_key) {
uint32_t tmp0, tmp1, tmp2, tmp3;
+#ifdef WORDS_BIGENDIAN
tmp0 = (U4[(state->v32[0] >> 24)] & 0xff000000)
^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
@@ -1771,6 +1920,31 @@ aes_inv_final_round(v128_t *state, const v128_t *round_key) {
^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
+#else
+ tmp0 = (U4[(state->v32[1] >> 24)] & 0xff000000)
+ ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
+ ^ (U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
+ ^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[0];
+
+ tmp1 = (U4[(state->v32[2] >> 24)] & 0xff000000)
+ ^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
+ ^ (U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
+ ^ (U4[(state->v32[1] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[1];
+
+ tmp2 = (U4[(state->v32[3] >> 24)] & 0xff000000)
+ ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
+ ^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
+ ^ (U4[(state->v32[2] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[2];
+
+ tmp3 = (U4[(state->v32[0] >> 24)] & 0xff000000)
+ ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
+ ^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
+ ^ (U4[(state->v32[3] ) & 0xff] & 0x000000ff)
+ ^ round_key->v32[3];
+#endif /* WORDS_BIGENDIAN */
state->v32[0] = tmp0;
state->v32[1] = tmp1;
@@ -1910,42 +2084,67 @@ aes_inv_final_round(v128_t *state, const v128_t *round_key) {
void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
+aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
/* add in the subkey */
- v128_xor_eq(plaintext, exp_key + 0);
-
- /* now do nine rounds */
- aes_round(plaintext, exp_key + 1);
- aes_round(plaintext, exp_key + 2);
- aes_round(plaintext, exp_key + 3);
- aes_round(plaintext, exp_key + 4);
- aes_round(plaintext, exp_key + 5);
- aes_round(plaintext, exp_key + 6);
- aes_round(plaintext, exp_key + 7);
- aes_round(plaintext, exp_key + 8);
- aes_round(plaintext, exp_key + 9);
- /* the last round is different */
-
- aes_final_round(plaintext, exp_key + 10);
+ v128_xor_eq(plaintext, &exp_key->round[0]);
+
+ /* now do the rounds */
+ aes_round(plaintext, &exp_key->round[1]);
+ aes_round(plaintext, &exp_key->round[2]);
+ aes_round(plaintext, &exp_key->round[3]);
+ aes_round(plaintext, &exp_key->round[4]);
+ aes_round(plaintext, &exp_key->round[5]);
+ aes_round(plaintext, &exp_key->round[6]);
+ aes_round(plaintext, &exp_key->round[7]);
+ aes_round(plaintext, &exp_key->round[8]);
+ aes_round(plaintext, &exp_key->round[9]);
+ if (exp_key->num_rounds == 10) {
+ aes_final_round(plaintext, &exp_key->round[10]);
+ }
+ else if (exp_key->num_rounds == 12) {
+ aes_round(plaintext, &exp_key->round[10]);
+ aes_round(plaintext, &exp_key->round[11]);
+ aes_final_round(plaintext, &exp_key->round[12]);
+ }
+ else if (exp_key->num_rounds == 14) {
+ aes_round(plaintext, &exp_key->round[10]);
+ aes_round(plaintext, &exp_key->round[11]);
+ aes_round(plaintext, &exp_key->round[12]);
+ aes_round(plaintext, &exp_key->round[13]);
+ aes_final_round(plaintext, &exp_key->round[14]);
+ }
}
void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
+aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
/* add in the subkey */
- v128_xor_eq(plaintext, exp_key + 0);
-
- /* now do nine rounds */
- aes_inv_round(plaintext, exp_key + 1);
- aes_inv_round(plaintext, exp_key + 2);
- aes_inv_round(plaintext, exp_key + 3);
- aes_inv_round(plaintext, exp_key + 4);
- aes_inv_round(plaintext, exp_key + 5);
- aes_inv_round(plaintext, exp_key + 6);
- aes_inv_round(plaintext, exp_key + 7);
- aes_inv_round(plaintext, exp_key + 8);
- aes_inv_round(plaintext, exp_key + 9);
- /* the last round is different */
- aes_inv_final_round(plaintext, exp_key + 10);
+ v128_xor_eq(plaintext, &exp_key->round[0]);
+
+ /* now do the rounds */
+ aes_inv_round(plaintext, &exp_key->round[1]);
+ aes_inv_round(plaintext, &exp_key->round[2]);
+ aes_inv_round(plaintext, &exp_key->round[3]);
+ aes_inv_round(plaintext, &exp_key->round[4]);
+ aes_inv_round(plaintext, &exp_key->round[5]);
+ aes_inv_round(plaintext, &exp_key->round[6]);
+ aes_inv_round(plaintext, &exp_key->round[7]);
+ aes_inv_round(plaintext, &exp_key->round[8]);
+ aes_inv_round(plaintext, &exp_key->round[9]);
+ if (exp_key->num_rounds == 10) {
+ aes_inv_final_round(plaintext, &exp_key->round[10]);
+ }
+ else if (exp_key->num_rounds == 12) {
+ aes_inv_round(plaintext, &exp_key->round[10]);
+ aes_inv_round(plaintext, &exp_key->round[11]);
+ aes_inv_final_round(plaintext, &exp_key->round[12]);
+ }
+ else if (exp_key->num_rounds == 14) {
+ aes_inv_round(plaintext, &exp_key->round[10]);
+ aes_inv_round(plaintext, &exp_key->round[11]);
+ aes_inv_round(plaintext, &exp_key->round[12]);
+ aes_inv_round(plaintext, &exp_key->round[13]);
+ aes_inv_final_round(plaintext, &exp_key->round[14]);
+ }
}
diff --git a/third_party/srtp/crypto/cipher/aes_cbc.c b/third_party/srtp/crypto/cipher/aes_cbc.c
index 8fc6a327..11953bf2 100644
--- a/third_party/srtp/crypto/cipher/aes_cbc.c
+++ b/third_party/srtp/crypto/cipher/aes_cbc.c
@@ -43,6 +43,9 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#include "aes_cbc.h"
#include "alloc.h"
@@ -55,7 +58,7 @@ debug_module_t mod_aes_cbc = {
err_status_t
-aes_cbc_alloc(cipher_t **c, int key_len) {
+aes_cbc_alloc(cipher_t **c, int key_len, int tlen) {
extern cipher_type_t aes_cbc;
uint8_t *pointer;
int tmp;
@@ -63,10 +66,10 @@ aes_cbc_alloc(cipher_t **c, int key_len) {
debug_print(mod_aes_cbc,
"allocating cipher with key length %d", key_len);
- if (key_len != 16)
+ if (key_len != 16 && key_len != 24 && key_len != 32)
return err_status_bad_param;
- /* allocate memory a cipher of type aes_icm */
+ /* allocate memory a cipher of type aes_cbc */
tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
pointer = (uint8_t*)crypto_alloc(tmp);
if (pointer == NULL)
@@ -74,6 +77,7 @@ aes_cbc_alloc(cipher_t **c, int key_len) {
/* set pointers */
*c = (cipher_t *)pointer;
+ (*c)->algorithm = AES_CBC;
(*c)->type = &aes_cbc;
(*c)->state = pointer + sizeof(cipher_t);
@@ -104,35 +108,25 @@ aes_cbc_dealloc(cipher_t *c) {
}
err_status_t
-aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
- cipher_direction_t dir) {
- v128_t tmp_key;
-
- /* set tmp_key (for alignment) */
- v128_copy_octet_string(&tmp_key, key);
+aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len) {
debug_print(mod_aes_cbc,
- "key: %s", v128_hex_string(&tmp_key));
-
- /* expand key for the appropriate direction */
- switch (dir) {
- case (direction_encrypt):
- aes_expand_encryption_key(&tmp_key, c->expanded_key);
- break;
- case (direction_decrypt):
- aes_expand_decryption_key(&tmp_key, c->expanded_key);
- break;
- default:
- return err_status_bad_param;
- }
+ "key: %s", octet_string_hex_string(key, key_len));
+ /*
+ * Save the key until we have the IV later. We don't
+ * know the direction until the IV is set.
+ */
+ c->key_len = (key_len <= 32 ? key_len : 32);
+ memcpy(c->key, key, c->key_len);
return err_status_ok;
}
err_status_t
-aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
+aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv, int direction) {
+ err_status_t status;
int i;
/* v128_t *input = iv; */
uint8_t *input = (uint8_t*) iv;
@@ -143,6 +137,24 @@ aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));
+ /* expand key for the appropriate direction */
+ switch (direction) {
+ case (direction_encrypt):
+ status = aes_expand_encryption_key(c->key, c->key_len, &c->expanded_key);
+ memset(c->key, 0, 32);
+ if (status)
+ return status;
+ break;
+ case (direction_decrypt):
+ status = aes_expand_decryption_key(c->key, c->key_len, &c->expanded_key);
+ memset(c->key, 0, 32);
+ if (status)
+ return status;
+ break;
+ default:
+ return err_status_bad_param;
+ }
+
return err_status_ok;
}
@@ -181,7 +193,7 @@ aes_cbc_encrypt(aes_cbc_ctx_t *c,
debug_print(mod_aes_cbc, "inblock: %s",
v128_hex_string(&c->state));
- aes_encrypt(&c->state, c->expanded_key);
+ aes_encrypt(&c->state, &c->expanded_key);
debug_print(mod_aes_cbc, "outblock: %s",
v128_hex_string(&c->state));
@@ -236,7 +248,7 @@ aes_cbc_decrypt(aes_cbc_ctx_t *c,
v128_hex_string(&state));
/* decrypt state */
- aes_decrypt(&state, c->expanded_key);
+ aes_decrypt(&state, &c->expanded_key);
debug_print(mod_aes_cbc, "outblock: %s",
v128_hex_string(&state));
@@ -332,7 +344,7 @@ char
aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
/*
- * Test case 0 is derived from FIPS 197 Appendix A; it uses an
+ * Test case 0 is derived from FIPS 197 Appendix C; it uses an
* all-zero IV, so that the first block encryption matches the test
* case in that appendix. This property provides a check of the base
* AES encryption and decryption algorithms; if CBC fails on some
@@ -374,6 +386,9 @@ cipher_test_case_t aes_cbc_test_case_0 = {
aes_cbc_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */
aes_cbc_test_case_0_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
NULL /* pointer to next testcase */
};
@@ -425,20 +440,126 @@ cipher_test_case_t aes_cbc_test_case_1 = {
aes_cbc_test_case_1_plaintext, /* plaintext */
80, /* octets in ciphertext */
aes_cbc_test_case_1_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
&aes_cbc_test_case_0 /* pointer to next testcase */
};
+/*
+ * Test case 2 is like test case 0, but for 256-bit keys. (FIPS 197
+ * appendix C.3).
+ */
+
+
+uint8_t aes_cbc_test_case_2_key[32] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+};
+
+uint8_t aes_cbc_test_case_2_plaintext[64] = {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+};
+
+uint8_t aes_cbc_test_case_2_ciphertext[80] = {
+ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+ 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
+ 0x72, 0x72, 0x6e, 0xe7, 0x71, 0x39, 0xbf, 0x11,
+ 0xe5, 0x40, 0xe2, 0x7c, 0x54, 0x65, 0x1d, 0xee
+};
+
+uint8_t aes_cbc_test_case_2_iv[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+cipher_test_case_t aes_cbc_test_case_2 = {
+ 32, /* octets in key */
+ aes_cbc_test_case_2_key, /* key */
+ aes_cbc_test_case_2_iv, /* initialization vector */
+ 16, /* octets in plaintext */
+ aes_cbc_test_case_2_plaintext, /* plaintext */
+ 32, /* octets in ciphertext */
+ aes_cbc_test_case_2_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ &aes_cbc_test_case_1 /* pointer to next testcase */
+};
+
+
+/*
+ * this test case is taken directly from Appendix F.2 of NIST Special
+ * Publication SP 800-38A
+ */
+
+uint8_t aes_cbc_test_case_3_key[32] = {
+ 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
+ 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
+ 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
+ 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
+};
+
+uint8_t aes_cbc_test_case_3_plaintext[64] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+ 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+ 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+ 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
+};
+
+uint8_t aes_cbc_test_case_3_ciphertext[80] = {
+ 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
+ 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
+ 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
+ 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
+ 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
+ 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
+ 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
+ 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
+ 0xfb, 0x98, 0x20, 0x2c, 0x45, 0xb2, 0xe4, 0xa0,
+ 0x63, 0xc4, 0x68, 0xba, 0x84, 0x39, 0x16, 0x5a
+};
+
+uint8_t aes_cbc_test_case_3_iv[16] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+};
+
+cipher_test_case_t aes_cbc_test_case_3 = {
+ 32, /* octets in key */
+ aes_cbc_test_case_3_key, /* key */
+ aes_cbc_test_case_3_iv, /* initialization vector */
+ 64, /* octets in plaintext */
+ aes_cbc_test_case_3_plaintext, /* plaintext */
+ 80, /* octets in ciphertext */
+ aes_cbc_test_case_3_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ &aes_cbc_test_case_2 /* pointer to next testcase */
+};
+
cipher_type_t aes_cbc = {
(cipher_alloc_func_t) aes_cbc_alloc,
(cipher_dealloc_func_t) aes_cbc_dealloc,
(cipher_init_func_t) aes_cbc_context_init,
+ (cipher_set_aad_func_t) 0,
(cipher_encrypt_func_t) aes_cbc_nist_encrypt,
(cipher_decrypt_func_t) aes_cbc_nist_decrypt,
(cipher_set_iv_func_t) aes_cbc_set_iv,
+ (cipher_get_tag_func_t) 0,
(char *) aes_cbc_description,
(int) 0, /* instance count */
- (cipher_test_case_t *) &aes_cbc_test_case_0,
- (debug_module_t *) &mod_aes_cbc
+ (cipher_test_case_t *) &aes_cbc_test_case_3,
+ (debug_module_t *) &mod_aes_cbc,
+ (cipher_type_id_t) AES_CBC
};
diff --git a/third_party/srtp/crypto/cipher/aes_gcm_ossl.c b/third_party/srtp/crypto/cipher/aes_gcm_ossl.c
new file mode 100644
index 00000000..dce2a337
--- /dev/null
+++ b/third_party/srtp/crypto/cipher/aes_gcm_ossl.c
@@ -0,0 +1,570 @@
+/*
+ * aes_gcm_ossl.c
+ *
+ * AES Galois Counter Mode
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2013, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <openssl/evp.h>
+#include "aes_icm_ossl.h"
+#include "aes_gcm_ossl.h"
+#include "alloc.h"
+#include "crypto_types.h"
+
+
+debug_module_t mod_aes_gcm = {
+ 0, /* debugging is off by default */
+ "aes gcm" /* printable module name */
+};
+
+/*
+ * The following are the global singleton instances for the
+ * 128-bit and 256-bit GCM ciphers.
+ */
+extern cipher_type_t aes_gcm_128_openssl;
+extern cipher_type_t aes_gcm_256_openssl;
+
+/*
+ * For now we only support 8 and 16 octet tags. The spec allows for
+ * optional 12 byte tag, which may be supported in the future.
+ */
+#define GCM_AUTH_TAG_LEN 16
+#define GCM_AUTH_TAG_LEN_8 8
+
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 28 or 44 for
+ * AES-128-GCM or AES-256-GCM respectively. Note that the
+ * key length includes the 14 byte salt value that is used when
+ * initializing the KDF.
+ */
+err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len, int tlen)
+{
+ aes_gcm_ctx_t *gcm;
+ int tmp;
+ uint8_t *allptr;
+
+ debug_print(mod_aes_gcm, "allocating cipher with key length %d", key_len);
+ debug_print(mod_aes_gcm, "allocating cipher with tag length %d", tlen);
+
+ /*
+ * Verify the key_len is valid for one of: AES-128/256
+ */
+ if (key_len != AES_128_GCM_KEYSIZE_WSALT &&
+ key_len != AES_256_GCM_KEYSIZE_WSALT) {
+ return (err_status_bad_param);
+ }
+
+ if (tlen != GCM_AUTH_TAG_LEN &&
+ tlen != GCM_AUTH_TAG_LEN_8) {
+ return (err_status_bad_param);
+ }
+
+ /* allocate memory a cipher of type aes_gcm */
+ tmp = sizeof(cipher_t) + sizeof(aes_gcm_ctx_t);
+ allptr = crypto_alloc(tmp);
+ if (allptr == NULL) {
+ return (err_status_alloc_fail);
+ }
+
+ /* set pointers */
+ *c = (cipher_t*)allptr;
+ (*c)->state = allptr + sizeof(cipher_t);
+ gcm = (aes_gcm_ctx_t *)(*c)->state;
+
+ /* increment ref_count */
+ switch (key_len) {
+ case AES_128_GCM_KEYSIZE_WSALT:
+ (*c)->type = &aes_gcm_128_openssl;
+ (*c)->algorithm = AES_128_GCM;
+ aes_gcm_128_openssl.ref_count++;
+ ((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
+ ((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
+ break;
+ case AES_256_GCM_KEYSIZE_WSALT:
+ (*c)->type = &aes_gcm_256_openssl;
+ (*c)->algorithm = AES_256_GCM;
+ aes_gcm_256_openssl.ref_count++;
+ ((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
+ ((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
+ break;
+ }
+
+ /* set key size */
+ (*c)->key_len = key_len;
+ EVP_CIPHER_CTX_init(&gcm->ctx);
+
+ return (err_status_ok);
+}
+
+
+/*
+ * This function deallocates a GCM session
+ */
+err_status_t aes_gcm_openssl_dealloc (cipher_t *c)
+{
+ aes_gcm_ctx_t *ctx;
+
+ ctx = (aes_gcm_ctx_t*)c->state;
+ if (ctx) {
+ EVP_CIPHER_CTX_cleanup(&ctx->ctx);
+ /* decrement ref_count for the appropriate engine */
+ switch (ctx->key_size) {
+ case AES_256_KEYSIZE:
+ aes_gcm_256_openssl.ref_count--;
+ break;
+ case AES_128_KEYSIZE:
+ aes_gcm_128_openssl.ref_count--;
+ break;
+ default:
+ return (err_status_dealloc_fail);
+ break;
+ }
+ }
+
+ /* zeroize entire state*/
+ octet_string_set_to_zero((uint8_t*)c, sizeof(cipher_t) + sizeof(aes_gcm_ctx_t));
+
+ /* free memory */
+ crypto_free(c);
+
+ return (err_status_ok);
+}
+
+/*
+ * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ */
+err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key)
+{
+ c->dir = direction_any;
+
+ /* copy key to be used later when CiscoSSL crypto context is created */
+ v128_copy_octet_string((v128_t*)&c->key, key);
+
+ if (c->key_size == AES_256_KEYSIZE) {
+ debug_print(mod_aes_gcm, "Copying last 16 bytes of key: %s",
+ v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
+ v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1,
+ key + AES_128_KEYSIZE);
+ }
+
+ debug_print(mod_aes_gcm, "key: %s", v128_hex_string((v128_t*)&c->key));
+
+ EVP_CIPHER_CTX_cleanup(&c->ctx);
+
+ return (err_status_ok);
+}
+
+
+/*
+ * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv,
+ int direction)
+{
+ const EVP_CIPHER *evp;
+
+ if (direction != direction_encrypt && direction != direction_decrypt) {
+ return (err_status_bad_param);
+ }
+ c->dir = direction;
+
+ debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(iv));
+
+ switch (c->key_size) {
+ case AES_256_KEYSIZE:
+ evp = EVP_aes_256_gcm();
+ break;
+ case AES_128_KEYSIZE:
+ evp = EVP_aes_128_gcm();
+ break;
+ default:
+ return (err_status_bad_param);
+ break;
+ }
+
+ if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8,
+ NULL, (c->dir == direction_encrypt ? 1 : 0))) {
+ return (err_status_init_fail);
+ }
+
+ /* set IV len and the IV value, the followiong 3 calls are required */
+ if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
+ return (err_status_init_fail);
+ }
+ if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) {
+ return (err_status_init_fail);
+ }
+ if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) {
+ return (err_status_init_fail);
+ }
+
+ return (err_status_ok);
+}
+
+/*
+ * This function processes the AAD
+ *
+ * Parameters:
+ * c Crypto context
+ * aad Additional data to process for AEAD cipher suites
+ * aad_len length of aad buffer
+ */
+err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad,
+ unsigned int aad_len)
+{
+ int rv;
+
+ /*
+ * Set dummy tag, OpenSSL requires the Tag to be set before
+ * processing AAD
+ */
+ EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad);
+
+ rv = EVP_Cipher(&c->ctx, NULL, aad, aad_len);
+ if (rv != aad_len) {
+ return (err_status_algo_fail);
+ } else {
+ return (err_status_ok);
+ }
+}
+
+/*
+ * This function encrypts a buffer using AES GCM mode
+ *
+ * Parameters:
+ * c Crypto context
+ * buf data to encrypt
+ * enc_len length of encrypt buffer
+ */
+err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf,
+ unsigned int *enc_len)
+{
+ if (c->dir != direction_encrypt && c->dir != direction_decrypt) {
+ return (err_status_bad_param);
+ }
+
+ /*
+ * Encrypt the data
+ */
+ EVP_Cipher(&c->ctx, buf, buf, *enc_len);
+
+ return (err_status_ok);
+}
+
+/*
+ * This function calculates and returns the GCM tag for a given context.
+ * This should be called after encrypting the data. The *len value
+ * is increased by the tag size. The caller must ensure that *buf has
+ * enough room to accept the appended tag.
+ *
+ * Parameters:
+ * c Crypto context
+ * buf data to encrypt
+ * len length of encrypt buffer
+ */
+err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf,
+ int *len)
+{
+ /*
+ * Calculate the tag
+ */
+ EVP_Cipher(&c->ctx, NULL, NULL, 0);
+
+ /*
+ * Retreive the tag
+ */
+ EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf);
+
+ /*
+ * Increase encryption length by desired tag size
+ */
+ *len = c->tag_len;
+
+ return (err_status_ok);
+}
+
+
+/*
+ * This function decrypts a buffer using AES GCM mode
+ *
+ * Parameters:
+ * c Crypto context
+ * buf data to encrypt
+ * enc_len length of encrypt buffer
+ */
+err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf,
+ unsigned int *enc_len)
+{
+ if (c->dir != direction_encrypt && c->dir != direction_decrypt) {
+ return (err_status_bad_param);
+ }
+
+ /*
+ * Set the tag before decrypting
+ */
+ EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
+ buf + (*enc_len - c->tag_len));
+ EVP_Cipher(&c->ctx, buf, buf, *enc_len - c->tag_len);
+
+ /*
+ * Check the tag
+ */
+ if (EVP_Cipher(&c->ctx, NULL, NULL, 0)) {
+ return (err_status_auth_fail);
+ }
+
+ /*
+ * Reduce the buffer size by the tag length since the tag
+ * is not part of the original payload
+ */
+ *enc_len -= c->tag_len;
+
+ return (err_status_ok);
+}
+
+
+
+/*
+ * Name of this crypto engine
+ */
+char aes_gcm_128_openssl_description[] = "AES-128 GCM using openssl";
+char aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl";
+
+
+/*
+ * KAT values for AES self-test. These
+ * values we're derived from independent test code
+ * using OpenSSL.
+ */
+uint8_t aes_gcm_test_case_0_key[AES_128_GCM_KEYSIZE_WSALT] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c,
+};
+
+uint8_t aes_gcm_test_case_0_iv[12] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88
+};
+
+uint8_t aes_gcm_test_case_0_plaintext[60] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39
+};
+
+uint8_t aes_gcm_test_case_0_aad[20] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2
+};
+
+uint8_t aes_gcm_test_case_0_ciphertext[76] = {
+ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+ 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+ 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+ 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+ 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+ 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+ 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+ 0x3d, 0x58, 0xe0, 0x91,
+ /* the last 16 bytes are the tag */
+ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+ 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
+};
+
+cipher_test_case_t aes_gcm_test_case_0a = {
+ AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
+ aes_gcm_test_case_0_key, /* key */
+ aes_gcm_test_case_0_iv, /* packet index */
+ 60, /* octets in plaintext */
+ aes_gcm_test_case_0_plaintext, /* plaintext */
+ 68, /* octets in ciphertext */
+ aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
+ 20, /* octets in AAD */
+ aes_gcm_test_case_0_aad, /* AAD */
+ GCM_AUTH_TAG_LEN_8,
+ NULL /* pointer to next testcase */
+};
+
+cipher_test_case_t aes_gcm_test_case_0 = {
+ AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
+ aes_gcm_test_case_0_key, /* key */
+ aes_gcm_test_case_0_iv, /* packet index */
+ 60, /* octets in plaintext */
+ aes_gcm_test_case_0_plaintext, /* plaintext */
+ 76, /* octets in ciphertext */
+ aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
+ 20, /* octets in AAD */
+ aes_gcm_test_case_0_aad, /* AAD */
+ GCM_AUTH_TAG_LEN,
+ &aes_gcm_test_case_0a /* pointer to next testcase */
+};
+
+uint8_t aes_gcm_test_case_1_key[AES_256_GCM_KEYSIZE_WSALT] = {
+ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+ 0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
+ 0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2,
+ 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c,
+
+};
+
+uint8_t aes_gcm_test_case_1_iv[12] = {
+ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+ 0xde, 0xca, 0xf8, 0x88
+};
+
+uint8_t aes_gcm_test_case_1_plaintext[60] = {
+ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+ 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+ 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+ 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+ 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+ 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+ 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+ 0xba, 0x63, 0x7b, 0x39
+};
+
+uint8_t aes_gcm_test_case_1_aad[20] = {
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+ 0xab, 0xad, 0xda, 0xd2
+};
+
+uint8_t aes_gcm_test_case_1_ciphertext[76] = {
+ 0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
+ 0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
+ 0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
+ 0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
+ 0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
+ 0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
+ 0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
+ 0x09, 0xc9, 0x86, 0xc1,
+ /* the last 16 bytes are the tag */
+ 0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
+ 0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
+};
+
+cipher_test_case_t aes_gcm_test_case_1a = {
+ AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
+ aes_gcm_test_case_1_key, /* key */
+ aes_gcm_test_case_1_iv, /* packet index */
+ 60, /* octets in plaintext */
+ aes_gcm_test_case_1_plaintext, /* plaintext */
+ 68, /* octets in ciphertext */
+ aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
+ 20, /* octets in AAD */
+ aes_gcm_test_case_1_aad, /* AAD */
+ GCM_AUTH_TAG_LEN_8,
+ NULL /* pointer to next testcase */
+};
+
+cipher_test_case_t aes_gcm_test_case_1 = {
+ AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
+ aes_gcm_test_case_1_key, /* key */
+ aes_gcm_test_case_1_iv, /* packet index */
+ 60, /* octets in plaintext */
+ aes_gcm_test_case_1_plaintext, /* plaintext */
+ 76, /* octets in ciphertext */
+ aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
+ 20, /* octets in AAD */
+ aes_gcm_test_case_1_aad, /* AAD */
+ GCM_AUTH_TAG_LEN,
+ &aes_gcm_test_case_1a /* pointer to next testcase */
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+cipher_type_t aes_gcm_128_openssl = {
+ (cipher_alloc_func_t) aes_gcm_openssl_alloc,
+ (cipher_dealloc_func_t) aes_gcm_openssl_dealloc,
+ (cipher_init_func_t) aes_gcm_openssl_context_init,
+ (cipher_set_aad_func_t) aes_gcm_openssl_set_aad,
+ (cipher_encrypt_func_t) aes_gcm_openssl_encrypt,
+ (cipher_decrypt_func_t) aes_gcm_openssl_decrypt,
+ (cipher_set_iv_func_t) aes_gcm_openssl_set_iv,
+ (cipher_get_tag_func_t) aes_gcm_openssl_get_tag,
+ (char*) aes_gcm_128_openssl_description,
+ (int) 0, /* instance count */
+ (cipher_test_case_t*) &aes_gcm_test_case_0,
+ (debug_module_t*) &mod_aes_gcm,
+ (cipher_type_id_t) AES_128_GCM
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+cipher_type_t aes_gcm_256_openssl = {
+ (cipher_alloc_func_t) aes_gcm_openssl_alloc,
+ (cipher_dealloc_func_t) aes_gcm_openssl_dealloc,
+ (cipher_init_func_t) aes_gcm_openssl_context_init,
+ (cipher_set_aad_func_t) aes_gcm_openssl_set_aad,
+ (cipher_encrypt_func_t) aes_gcm_openssl_encrypt,
+ (cipher_decrypt_func_t) aes_gcm_openssl_decrypt,
+ (cipher_set_iv_func_t) aes_gcm_openssl_set_iv,
+ (cipher_get_tag_func_t) aes_gcm_openssl_get_tag,
+ (char*) aes_gcm_256_openssl_description,
+ (int) 0, /* instance count */
+ (cipher_test_case_t*) &aes_gcm_test_case_1,
+ (debug_module_t*) &mod_aes_gcm,
+ (cipher_type_id_t) AES_256_GCM
+};
+
diff --git a/third_party/srtp/crypto/cipher/aes_icm.c b/third_party/srtp/crypto/cipher/aes_icm.c
index e7e8c599..3d97e2ba 100644
--- a/third_party/srtp/crypto/cipher/aes_icm.c
+++ b/third_party/srtp/crypto/cipher/aes_icm.c
@@ -9,7 +9,7 @@
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,9 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#define ALIGN_32 0
@@ -101,12 +104,13 @@ aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
/*
* Ismacryp, for example, uses 16 byte key + 8 byte
* salt so this function is called with key_len = 24.
- * The check for key_len = 30 does not apply. Our usage
+ * The check for key_len = 30/38/46 does not apply. Our usage
* of aes functions with key_len = values other than 30
* has not broken anything. Don't know what would be the
* effect of skipping this check for srtp in general.
*/
- if (!forIsmacryp && key_len != 30)
+ if (!(forIsmacryp && key_len > 16 && key_len < 30) &&
+ key_len != 30 && key_len != 38 && key_len != 46)
return err_status_bad_param;
/* allocate memory a cipher of type aes_icm */
@@ -117,6 +121,17 @@ aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
/* set pointers */
*c = (cipher_t *)pointer;
+ switch (key_len) {
+ case 46:
+ (*c)->algorithm = AES_256_ICM;
+ break;
+ case 38:
+ (*c)->algorithm = AES_192_ICM;
+ break;
+ default:
+ (*c)->algorithm = AES_128_ICM;
+ break;
+ }
(*c)->type = &aes_icm;
(*c)->state = pointer + sizeof(cipher_t);
@@ -162,30 +177,44 @@ aes_icm_dealloc(cipher_t *c) {
*/
err_status_t
-aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {
- v128_t tmp_key;
-
- /* set counter and initial values to 'offset' value */
- /* FIX!!! this assumes the salt is at key + 16, and thus that the */
- /* FIX!!! cipher key length is 16! Also note this copies past the
- end of the 'key' array by 2 bytes! */
- v128_copy_octet_string(&c->counter, key + 16);
- v128_copy_octet_string(&c->offset, key + 16);
-
- /* force last two octets of the offset to zero (for srtp compatibility) */
- c->offset.v8[14] = c->offset.v8[15] = 0;
- c->counter.v8[14] = c->counter.v8[15] = 0;
-
- /* set tmp_key (for alignment) */
- v128_copy_octet_string(&tmp_key, key);
+aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) {
+ err_status_t status;
+ int base_key_len, copy_len;
+
+ if (key_len > 16 && key_len < 30) /* Ismacryp */
+ base_key_len = 16;
+ else if (key_len == 30 || key_len == 38 || key_len == 46)
+ base_key_len = key_len - 14;
+ else
+ return err_status_bad_param;
+
+ /*
+ * set counter and initial values to 'offset' value, being careful not to
+ * go past the end of the key buffer
+ */
+ v128_set_to_zero(&c->counter);
+ v128_set_to_zero(&c->offset);
+
+ copy_len = key_len - base_key_len;
+ /* force last two octets of the offset to be left zero (for srtp compatibility) */
+ if (copy_len > 14)
+ copy_len = 14;
+
+ memcpy(&c->counter, key + base_key_len, copy_len);
+ memcpy(&c->offset, key + base_key_len, copy_len);
debug_print(mod_aes_icm,
- "key: %s", v128_hex_string(&tmp_key));
+ "key: %s", octet_string_hex_string(key, base_key_len));
debug_print(mod_aes_icm,
"offset: %s", v128_hex_string(&c->offset));
/* expand key */
- aes_expand_encryption_key(&tmp_key, c->expanded_key);
+ status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
+ if (status) {
+ v128_set_to_zero(&c->counter);
+ v128_set_to_zero(&c->offset);
+ return status;
+ }
/* indicate that the keystream_buffer is empty */
c->bytes_in_buffer = 0;
@@ -210,7 +239,7 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
((high32(octet_num) & 0x0f)<<(32-4)) |
(low32(octet_num) >> 4));
#else
- int tail_num = octet_num % 16;
+ int tail_num = (int)(octet_num % 16);
uint64_t block_num = octet_num / 16;
#endif
@@ -231,7 +260,7 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
/* fill keystream buffer, if needed */
if (tail_num) {
v128_copy(&c->keystream_buffer, &c->counter);
- aes_encrypt(&c->keystream_buffer, c->expanded_key);
+ aes_encrypt(&c->keystream_buffer, &c->expanded_key);
c->bytes_in_buffer = sizeof(v128_t);
debug_print(mod_aes_icm, "counter: %s",
@@ -257,13 +286,16 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
*/
err_status_t
-aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
- v128_t *nonce = (v128_t *) iv;
+aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) {
+ v128_t nonce;
+
+ /* set nonce (for alignment) */
+ v128_copy_octet_string(&nonce, iv);
debug_print(mod_aes_icm,
- "setting iv: %s", v128_hex_string(nonce));
+ "setting iv: %s", v128_hex_string(&nonce));
- v128_xor(&c->counter, &c->offset, nonce);
+ v128_xor(&c->counter, &c->offset, &nonce);
debug_print(mod_aes_icm,
"set_counter: %s", v128_hex_string(&c->counter));
@@ -287,7 +319,7 @@ static inline void
aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
/* fill buffer with new keystream */
v128_copy(&c->keystream_buffer, &c->counter);
- aes_encrypt(&c->keystream_buffer, c->expanded_key);
+ aes_encrypt(&c->keystream_buffer, &c->expanded_key);
c->bytes_in_buffer = sizeof(v128_t);
debug_print(mod_aes_icm, "counter: %s",
@@ -301,18 +333,14 @@ aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
uint32_t temp;
//alex's clock counter forward
temp = ntohl(c->counter.v32[3]);
- c->counter.v32[3] = htonl(++temp);
+ ++temp;
+ c->counter.v32[3] = htonl(temp);
} else {
if (!++(c->counter.v8[15]))
++(c->counter.v8[14]);
}
}
-inline void aes_icm_advance(aes_icm_ctx_t *c) {
- aes_icm_advance_ismacryp(c, 0);
-}
-
-
/*e
* icm_encrypt deals with the following cases:
*
@@ -440,7 +468,7 @@ aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
}
err_status_t
-aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
+aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, unsigned int num_octets_to_output) {
unsigned int len = num_octets_to_output;
/* zeroize the buffer */
@@ -450,6 +478,10 @@ aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
return aes_icm_encrypt(c, buffer, &len);
}
+uint16_t
+aes_icm_bytes_encrypted(aes_icm_ctx_t *c) {
+ return htons(c->counter.v16[7]);
+}
char
aes_icm_description[] = "aes integer counter mode";
@@ -488,9 +520,55 @@ cipher_test_case_t aes_icm_test_case_0 = {
aes_icm_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */
aes_icm_test_case_0_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
NULL /* pointer to next testcase */
};
+uint8_t aes_icm_test_case_1_key[46] = {
+ 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
+ 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
+ 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
+ 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+
+uint8_t aes_icm_test_case_1_nonce[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t aes_icm_test_case_1_plaintext[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint8_t aes_icm_test_case_1_ciphertext[32] = {
+ 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+ 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+ 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+ 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
+};
+
+cipher_test_case_t aes_icm_test_case_1 = {
+ 46, /* octets in key */
+ aes_icm_test_case_1_key, /* key */
+ aes_icm_test_case_1_nonce, /* packet index */
+ 32, /* octets in plaintext */
+ aes_icm_test_case_1_plaintext, /* plaintext */
+ 32, /* octets in ciphertext */
+ aes_icm_test_case_1_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ &aes_icm_test_case_0 /* pointer to next testcase */
+};
+
+
/*
* note: the encrypt function is identical to the decrypt function
@@ -500,12 +578,15 @@ cipher_type_t aes_icm = {
(cipher_alloc_func_t) aes_icm_alloc,
(cipher_dealloc_func_t) aes_icm_dealloc,
(cipher_init_func_t) aes_icm_context_init,
+ (cipher_set_aad_func_t) 0,
(cipher_encrypt_func_t) aes_icm_encrypt,
(cipher_decrypt_func_t) aes_icm_encrypt,
(cipher_set_iv_func_t) aes_icm_set_iv,
+ (cipher_get_tag_func_t) 0,
(char *) aes_icm_description,
(int) 0, /* instance count */
- (cipher_test_case_t *) &aes_icm_test_case_0,
- (debug_module_t *) &mod_aes_icm
+ (cipher_test_case_t *) &aes_icm_test_case_1,
+ (debug_module_t *) &mod_aes_icm,
+ (cipher_type_id_t) AES_ICM
};
diff --git a/third_party/srtp/crypto/cipher/aes_icm_ossl.c b/third_party/srtp/crypto/cipher/aes_icm_ossl.c
new file mode 100644
index 00000000..eb585391
--- /dev/null
+++ b/third_party/srtp/crypto/cipher/aes_icm_ossl.c
@@ -0,0 +1,563 @@
+/*
+ * aes_icm_ossl.c
+ *
+ * AES Integer Counter Mode
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ * 2/24/2012: This module was modified to use CiscoSSL for AES counter
+ * mode. Eddy Lem contributed the code to allow this.
+ *
+ * 12/20/2012: Added support for AES-192 and AES-256.
+ */
+
+/*
+ *
+ * Copyright (c) 2013, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <openssl/evp.h>
+#include "aes_icm_ossl.h"
+#include "crypto_types.h"
+#include "alloc.h"
+#include "crypto_types.h"
+
+
+debug_module_t mod_aes_icm = {
+ 0, /* debugging is off by default */
+ "aes icm ossl" /* printable module name */
+};
+extern cipher_test_case_t aes_icm_test_case_0;
+extern cipher_type_t aes_icm;
+#ifndef SRTP_NO_AES192
+extern cipher_type_t aes_icm_192;
+#endif
+extern cipher_type_t aes_icm_256;
+
+/*
+ * integer counter mode works as follows:
+ *
+ * 16 bits
+ * <----->
+ * +------+------+------+------+------+------+------+------+
+ * | nonce | packet index | ctr |---+
+ * +------+------+------+------+------+------+------+------+ |
+ * |
+ * +------+------+------+------+------+------+------+------+ v
+ * | salt |000000|->(+)
+ * +------+------+------+------+------+------+------+------+ |
+ * |
+ * +---------+
+ * | encrypt |
+ * +---------+
+ * |
+ * +------+------+------+------+------+------+------+------+ |
+ * | keystream block |<--+
+ * +------+------+------+------+------+------+------+------+
+ *
+ * All fields are big-endian
+ *
+ * ctr is the block counter, which increments from zero for
+ * each packet (16 bits wide)
+ *
+ * packet index is distinct for each packet (48 bits wide)
+ *
+ * nonce can be distinct across many uses of the same key, or
+ * can be a fixed value per key, or can be per-packet randomness
+ * (64 bits)
+ *
+ */
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 30, 38, or 46 for
+ * AES-128, AES-192, and AES-256 respectively. Note, this key_len
+ * value is inflated, as it also accounts for the 112 bit salt
+ * value. The tlen argument is for the AEAD tag length, which
+ * isn't used in counter mode.
+ */
+err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int tlen)
+{
+ aes_icm_ctx_t *icm;
+ int tmp;
+ uint8_t *allptr;
+
+ debug_print(mod_aes_icm, "allocating cipher with key length %d", key_len);
+
+ /*
+ * Verify the key_len is valid for one of: AES-128/192/256
+ */
+ if (key_len != AES_128_KEYSIZE_WSALT &&
+#ifndef SRTP_NO_AES192
+ key_len != AES_192_KEYSIZE_WSALT &&
+#endif
+ key_len != AES_256_KEYSIZE_WSALT) {
+ return err_status_bad_param;
+ }
+
+ /* allocate memory a cipher of type aes_icm */
+ tmp = sizeof(cipher_t) + sizeof(aes_icm_ctx_t);
+ allptr = (uint8_t*)crypto_alloc(tmp);
+ if (allptr == NULL) {
+ return err_status_alloc_fail;
+ }
+
+ /* set pointers */
+ *c = (cipher_t*)allptr;
+ (*c)->state = allptr + sizeof(cipher_t);
+ icm = (aes_icm_ctx_t*)(*c)->state;
+
+ /* increment ref_count */
+ switch (key_len) {
+ case AES_128_KEYSIZE_WSALT:
+ (*c)->algorithm = AES_128_ICM;
+ (*c)->type = &aes_icm;
+ aes_icm.ref_count++;
+ ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
+ break;
+#ifndef SRTP_NO_AES192
+ case AES_192_KEYSIZE_WSALT:
+ (*c)->algorithm = AES_192_ICM;
+ (*c)->type = &aes_icm_192;
+ aes_icm_192.ref_count++;
+ ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_192_KEYSIZE;
+ break;
+#endif
+ case AES_256_KEYSIZE_WSALT:
+ (*c)->algorithm = AES_256_ICM;
+ (*c)->type = &aes_icm_256;
+ aes_icm_256.ref_count++;
+ ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
+ break;
+ }
+
+ /* set key size */
+ (*c)->key_len = key_len;
+ EVP_CIPHER_CTX_init(&icm->ctx);
+
+ return err_status_ok;
+}
+
+
+/*
+ * This function deallocates an instance of this engine
+ */
+err_status_t aes_icm_openssl_dealloc (cipher_t *c)
+{
+ aes_icm_ctx_t *ctx;
+
+ if (c == NULL) {
+ return err_status_bad_param;
+ }
+
+ /*
+ * Free the EVP context
+ */
+ ctx = (aes_icm_ctx_t*)c->state;
+ if (ctx != NULL) {
+ EVP_CIPHER_CTX_cleanup(&ctx->ctx);
+ /* decrement ref_count for the appropriate engine */
+ switch (ctx->key_size) {
+ case AES_256_KEYSIZE:
+ aes_icm_256.ref_count--;
+ break;
+#ifndef SRTP_NO_AES192
+ case AES_192_KEYSIZE:
+ aes_icm_192.ref_count--;
+ break;
+#endif
+ case AES_128_KEYSIZE:
+ aes_icm.ref_count--;
+ break;
+ default:
+ return err_status_dealloc_fail;
+ break;
+ }
+ }
+
+ /* zeroize entire state*/
+ octet_string_set_to_zero((uint8_t*)c,
+ sizeof(cipher_t) + sizeof(aes_icm_ctx_t));
+
+ /* free memory */
+ crypto_free(c);
+
+ return err_status_ok;
+}
+
+/*
+ * aes_icm_openssl_context_init(...) initializes the aes_icm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ *
+ * the salt is unpredictable (but not necessarily secret) data which
+ * randomizes the starting point in the keystream
+ */
+err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key, int len)
+{
+ /*
+ * set counter and initial values to 'offset' value, being careful not to
+ * go past the end of the key buffer
+ */
+
+ if (c->key_size + SALT_SIZE != len)
+ return err_status_bad_param;
+
+ v128_set_to_zero(&c->counter);
+ v128_set_to_zero(&c->offset);
+ memcpy(&c->counter, key + c->key_size, SALT_SIZE);
+ memcpy(&c->offset, key + c->key_size, SALT_SIZE);
+
+ /* force last two octets of the offset to zero (for srtp compatibility) */
+ c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0;
+ c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0;
+
+ /* copy key to be used later when CiscoSSL crypto context is created */
+ v128_copy_octet_string((v128_t*)&c->key, key);
+
+ /* if the key is greater than 16 bytes, copy the second
+ * half. Note, we treat AES-192 and AES-256 the same here
+ * for simplicity. The storage location receiving the
+ * key is statically allocated to handle a full 32 byte key
+ * regardless of the cipher in use.
+ */
+ if (c->key_size == AES_256_KEYSIZE
+#ifndef SRTP_NO_AES192
+ || c->key_size == AES_192_KEYSIZE
+#endif
+ ) {
+ debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s",
+ v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
+ v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE);
+ }
+
+ debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key));
+ debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
+
+ EVP_CIPHER_CTX_cleanup(&c->ctx);
+
+ return err_status_ok;
+}
+
+
+/*
+ * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir)
+{
+ const EVP_CIPHER *evp;
+ v128_t nonce;
+
+ /* set nonce (for alignment) */
+ v128_copy_octet_string(&nonce, iv);
+
+ debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
+
+ v128_xor(&c->counter, &c->offset, &nonce);
+
+ debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));
+
+ switch (c->key_size) {
+ case AES_256_KEYSIZE:
+ evp = EVP_aes_256_ctr();
+ break;
+#ifndef SRTP_NO_AES192
+ case AES_192_KEYSIZE:
+ evp = EVP_aes_192_ctr();
+ break;
+#endif
+ case AES_128_KEYSIZE:
+ evp = EVP_aes_128_ctr();
+ break;
+ default:
+ return err_status_bad_param;
+ break;
+ }
+
+ if (!EVP_EncryptInit_ex(&c->ctx, evp,
+ NULL, c->key.v8, c->counter.v8)) {
+ return err_status_fail;
+ } else {
+ return err_status_ok;
+ }
+}
+
+/*
+ * This function encrypts a buffer using AES CTR mode
+ *
+ * Parameters:
+ * c Crypto context
+ * buf data to encrypt
+ * enc_len length of encrypt buffer
+ */
+err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len)
+{
+ int len = 0;
+
+ debug_print(mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
+
+ if (!EVP_EncryptUpdate(&c->ctx, buf, &len, buf, *enc_len)) {
+ return err_status_cipher_fail;
+ }
+ *enc_len = len;
+
+ if (!EVP_EncryptFinal_ex(&c->ctx, buf, &len)) {
+ return err_status_cipher_fail;
+ }
+ *enc_len += len;
+
+ return err_status_ok;
+}
+
+uint16_t aes_icm_bytes_encrypted(aes_icm_ctx_t *c)
+{
+ return htons(c->counter.v16[7]);
+}
+
+/*
+ * Name of this crypto engine
+ */
+char aes_icm_openssl_description[] = "AES-128 counter mode using openssl";
+#ifndef SRTP_NO_AES192
+char aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
+#endif
+char aes_icm_256_openssl_description[] = "AES-256 counter mode using openssl";
+
+
+/*
+ * KAT values for AES self-test. These
+ * values came from the legacy libsrtp code.
+ */
+uint8_t aes_icm_test_case_0_key[AES_128_KEYSIZE_WSALT] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+
+uint8_t aes_icm_test_case_0_nonce[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t aes_icm_test_case_0_plaintext[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint8_t aes_icm_test_case_0_ciphertext[32] = {
+ 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+ 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+ 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+ 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
+};
+
+cipher_test_case_t aes_icm_test_case_0 = {
+ AES_128_KEYSIZE_WSALT, /* octets in key */
+ aes_icm_test_case_0_key, /* key */
+ aes_icm_test_case_0_nonce, /* packet index */
+ 32, /* octets in plaintext */
+ aes_icm_test_case_0_plaintext, /* plaintext */
+ 32, /* octets in ciphertext */
+ aes_icm_test_case_0_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ NULL /* pointer to next testcase */
+};
+
+#ifndef SRTP_NO_AES192
+/*
+ * KAT values for AES-192-CTR self-test. These
+ * values came from section 7 of RFC 6188.
+ */
+uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = {
+ 0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
+ 0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
+ 0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+
+uint8_t aes_icm_192_test_case_1_nonce[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t aes_icm_192_test_case_1_plaintext[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint8_t aes_icm_192_test_case_1_ciphertext[32] = {
+ 0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d,
+ 0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
+ 0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
+ 0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
+};
+
+cipher_test_case_t aes_icm_192_test_case_1 = {
+ AES_192_KEYSIZE_WSALT, /* octets in key */
+ aes_icm_192_test_case_1_key, /* key */
+ aes_icm_192_test_case_1_nonce, /* packet index */
+ 32, /* octets in plaintext */
+ aes_icm_192_test_case_1_plaintext, /* plaintext */
+ 32, /* octets in ciphertext */
+ aes_icm_192_test_case_1_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ NULL /* pointer to next testcase */
+};
+#endif
+
+/*
+ * KAT values for AES-256-CTR self-test. These
+ * values came from section 7 of RFC 6188.
+ */
+uint8_t aes_icm_256_test_case_2_key[AES_256_KEYSIZE_WSALT] = {
+ 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
+ 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
+ 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
+ 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+
+uint8_t aes_icm_256_test_case_2_nonce[16] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint8_t aes_icm_256_test_case_2_plaintext[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+uint8_t aes_icm_256_test_case_2_ciphertext[32] = {
+ 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+ 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+ 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+ 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
+};
+
+cipher_test_case_t aes_icm_256_test_case_2 = {
+ AES_256_KEYSIZE_WSALT, /* octets in key */
+ aes_icm_256_test_case_2_key, /* key */
+ aes_icm_256_test_case_2_nonce, /* packet index */
+ 32, /* octets in plaintext */
+ aes_icm_256_test_case_2_plaintext, /* plaintext */
+ 32, /* octets in ciphertext */
+ aes_icm_256_test_case_2_ciphertext, /* ciphertext */
+ 0,
+ NULL,
+ 0,
+ NULL /* pointer to next testcase */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+cipher_type_t aes_icm = {
+ (cipher_alloc_func_t) aes_icm_openssl_alloc,
+ (cipher_dealloc_func_t) aes_icm_openssl_dealloc,
+ (cipher_init_func_t) aes_icm_openssl_context_init,
+ (cipher_set_aad_func_t) 0,
+ (cipher_encrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_decrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_set_iv_func_t) aes_icm_openssl_set_iv,
+ (cipher_get_tag_func_t) 0,
+ (char*) aes_icm_openssl_description,
+ (int) 0, /* instance count */
+ (cipher_test_case_t*) &aes_icm_test_case_0,
+ (debug_module_t*) &mod_aes_icm,
+ (cipher_type_id_t) AES_ICM
+};
+
+#ifndef SRTP_NO_AES192
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+cipher_type_t aes_icm_192 = {
+ (cipher_alloc_func_t) aes_icm_openssl_alloc,
+ (cipher_dealloc_func_t) aes_icm_openssl_dealloc,
+ (cipher_init_func_t) aes_icm_openssl_context_init,
+ (cipher_set_aad_func_t) 0,
+ (cipher_encrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_decrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_set_iv_func_t) aes_icm_openssl_set_iv,
+ (cipher_get_tag_func_t) 0,
+ (char*) aes_icm_192_openssl_description,
+ (int) 0, /* instance count */
+ (cipher_test_case_t*) &aes_icm_192_test_case_1,
+ (debug_module_t*) &mod_aes_icm,
+ (cipher_type_id_t) AES_192_ICM
+};
+#endif
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+cipher_type_t aes_icm_256 = {
+ (cipher_alloc_func_t) aes_icm_openssl_alloc,
+ (cipher_dealloc_func_t) aes_icm_openssl_dealloc,
+ (cipher_init_func_t) aes_icm_openssl_context_init,
+ (cipher_set_aad_func_t) 0,
+ (cipher_encrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_decrypt_func_t) aes_icm_openssl_encrypt,
+ (cipher_set_iv_func_t) aes_icm_openssl_set_iv,
+ (cipher_get_tag_func_t) 0,
+ (char*) aes_icm_256_openssl_description,
+ (int) 0, /* instance count */
+ (cipher_test_case_t*) &aes_icm_256_test_case_2,
+ (debug_module_t*) &mod_aes_icm,
+ (cipher_type_id_t) AES_256_ICM
+};
+
diff --git a/third_party/srtp/crypto/cipher/cipher.c b/third_party/srtp/crypto/cipher/cipher.c
index 489a52d9..15b9088f 100644
--- a/third_party/srtp/crypto/cipher/cipher.c
+++ b/third_party/srtp/crypto/cipher/cipher.c
@@ -10,7 +10,7 @@
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,12 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "cipher.h"
+#include "crypto_types.h"
#include "rand_source.h" /* used in invertibiltiy tests */
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
@@ -71,8 +76,8 @@ cipher_get_key_length(const cipher_t *c) {
}
/*
- * cipher_type_self_test(ct) tests a cipher of type ct against test cases
- * provided in an array of values of key, salt, xtd_seq_num_t,
+ * cipher_type_test(ct, test_data) tests a cipher of type ct against
+ * test cases provided in a list test_data of values of key, salt, iv,
* plaintext, and ciphertext that is known to be good
*/
@@ -81,12 +86,13 @@ cipher_get_key_length(const cipher_t *c) {
#define MAX_KEY_LEN 64
err_status_t
-cipher_type_self_test(const cipher_type_t *ct) {
- const cipher_test_case_t *test_case = ct->test_data;
+cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
+ const cipher_test_case_t *test_case = test_data;
cipher_t *c;
err_status_t status;
uint8_t buffer[SELF_TEST_BUF_OCTETS];
uint8_t buffer2[SELF_TEST_BUF_OCTETS];
+ int tag_len;
unsigned int len;
int i, j, case_num = 0;
@@ -105,9 +111,8 @@ cipher_type_self_test(const cipher_type_t *ct) {
* encryption and decryption functions
*/
while (test_case != NULL) {
-
/* allocate cipher */
- status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
+ status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
if (status)
return status;
@@ -117,7 +122,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
debug_print(mod_cipher, "testing encryption", NULL);
/* initialize cipher */
- status = cipher_init(c, test_case->key, direction_encrypt);
+ status = cipher_init(c, test_case->key);
if (status) {
cipher_dealloc(c);
return status;
@@ -136,12 +141,30 @@ cipher_type_self_test(const cipher_type_t *ct) {
test_case->plaintext_length_octets));
/* set the initialization vector */
- status = cipher_set_iv(c, test_case->idx);
+ status = cipher_set_iv(c, test_case->idx, direction_encrypt);
if (status) {
cipher_dealloc(c);
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ debug_print(mod_cipher, "IV: %s",
+ octet_string_hex_string(test_case->idx, 12));
+
+ /*
+ * Set the AAD
+ */
+ status = cipher_set_aad(c, test_case->aad,
+ test_case->aad_length_octets);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ debug_print(mod_cipher, "AAD: %s",
+ octet_string_hex_string(test_case->aad,
+ test_case->aad_length_octets));
+ }
+
/* encrypt */
len = test_case->plaintext_length_octets;
status = cipher_encrypt(c, buffer, &len);
@@ -150,6 +173,18 @@ cipher_type_self_test(const cipher_type_t *ct) {
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ /*
+ * Get the GCM tag
+ */
+ status = cipher_get_tag(c, buffer + len, &tag_len);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ len += tag_len;
+ }
+
debug_print(mod_cipher, "ciphertext: %s",
octet_string_hex_string(buffer,
test_case->ciphertext_length_octets));
@@ -184,7 +219,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
debug_print(mod_cipher, "testing decryption", NULL);
/* re-initialize cipher for decryption */
- status = cipher_init(c, test_case->key, direction_decrypt);
+ status = cipher_init(c, test_case->key);
if (status) {
cipher_dealloc(c);
return status;
@@ -203,12 +238,27 @@ cipher_type_self_test(const cipher_type_t *ct) {
test_case->plaintext_length_octets));
/* set the initialization vector */
- status = cipher_set_iv(c, test_case->idx);
+ status = cipher_set_iv(c, test_case->idx, direction_decrypt);
if (status) {
cipher_dealloc(c);
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ /*
+ * Set the AAD
+ */
+ status = cipher_set_aad(c, test_case->aad,
+ test_case->aad_length_octets);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ debug_print(mod_cipher, "AAD: %s",
+ octet_string_hex_string(test_case->aad,
+ test_case->aad_length_octets));
+ }
+
/* decrypt */
len = test_case->ciphertext_length_octets;
status = cipher_decrypt(c, buffer, &len);
@@ -260,8 +310,8 @@ cipher_type_self_test(const cipher_type_t *ct) {
/* now run some random invertibility tests */
/* allocate cipher, using paramaters from the first test case */
- test_case = ct->test_data;
- status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
+ test_case = test_data;
+ status = cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
if (status)
return status;
@@ -269,7 +319,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
for (j=0; j < NUM_RAND_TESTS; j++) {
unsigned length;
- unsigned plaintext_len;
+ int plaintext_len;
uint8_t key[MAX_KEY_LEN];
uint8_t iv[MAX_KEY_LEN];
@@ -297,19 +347,34 @@ cipher_type_self_test(const cipher_type_t *ct) {
if (status) return status;
/* initialize cipher */
- status = cipher_init(c, key, direction_encrypt);
+ status = cipher_init(c, key);
if (status) {
cipher_dealloc(c);
return status;
}
/* set initialization vector */
- status = cipher_set_iv(c, test_case->idx);
+ status = cipher_set_iv(c, test_case->idx, direction_encrypt);
if (status) {
cipher_dealloc(c);
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ /*
+ * Set the AAD
+ */
+ status = cipher_set_aad(c, test_case->aad,
+ test_case->aad_length_octets);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ debug_print(mod_cipher, "AAD: %s",
+ octet_string_hex_string(test_case->aad,
+ test_case->aad_length_octets));
+ }
+
/* encrypt buffer with cipher */
plaintext_len = length;
status = cipher_encrypt(c, buffer, &length);
@@ -317,6 +382,17 @@ cipher_type_self_test(const cipher_type_t *ct) {
cipher_dealloc(c);
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ /*
+ * Get the GCM tag
+ */
+ status = cipher_get_tag(c, buffer + length, &tag_len);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ length += tag_len;
+ }
debug_print(mod_cipher, "ciphertext: %s",
octet_string_hex_string(buffer, length));
@@ -324,16 +400,30 @@ cipher_type_self_test(const cipher_type_t *ct) {
* re-initialize cipher for decryption, re-set the iv, then
* decrypt the ciphertext
*/
- status = cipher_init(c, key, direction_decrypt);
+ status = cipher_init(c, key);
if (status) {
cipher_dealloc(c);
return status;
}
- status = cipher_set_iv(c, test_case->idx);
+ status = cipher_set_iv(c, test_case->idx, direction_decrypt);
if (status) {
cipher_dealloc(c);
return status;
}
+ if (c->algorithm == AES_128_GCM || c->algorithm == AES_256_GCM) {
+ /*
+ * Set the AAD
+ */
+ status = cipher_set_aad(c, test_case->aad,
+ test_case->aad_length_octets);
+ if (status) {
+ cipher_dealloc(c);
+ return status;
+ }
+ debug_print(mod_cipher, "AAD: %s",
+ octet_string_hex_string(test_case->aad,
+ test_case->aad_length_octets));
+ }
status = cipher_decrypt(c, buffer, &length);
if (status) {
cipher_dealloc(c);
@@ -344,8 +434,9 @@ cipher_type_self_test(const cipher_type_t *ct) {
octet_string_hex_string(buffer, length));
/* compare the resulting plaintext with the original one */
- if (length != plaintext_len)
+ if (length != plaintext_len) {
return err_status_algo_fail;
+ }
status = err_status_ok;
for (i=0; i < plaintext_len; i++)
if (buffer[i] != buffer2[i]) {
@@ -359,13 +450,25 @@ cipher_type_self_test(const cipher_type_t *ct) {
}
}
-
- cipher_dealloc(c);
+
+ status = cipher_dealloc(c);
+ if (status)
+ return status;
return err_status_ok;
}
+/*
+ * cipher_type_self_test(ct) performs cipher_type_test on ct's internal
+ * list of test data.
+ */
+
+err_status_t
+cipher_type_self_test(const cipher_type_t *ct) {
+ return cipher_type_test(ct, ct->test_data);
+}
+
/*
* cipher_bits_per_second(c, l, t) computes (an estimate of) the
* number of bits that a cipher implementation can encrypt in a second
@@ -393,7 +496,7 @@ cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {
v128_set_to_zero(&nonce);
timer = clock();
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
- cipher_set_iv(c, &nonce);
+ cipher_set_iv(c, &nonce, direction_encrypt);
cipher_encrypt(c, enc_buf, &len);
}
timer = clock() - timer;
diff --git a/third_party/srtp/crypto/cipher/null_cipher.c b/third_party/srtp/crypto/cipher/null_cipher.c
index 721f50cf..3cd49fb9 100644
--- a/third_party/srtp/crypto/cipher/null_cipher.c
+++ b/third_party/srtp/crypto/cipher/null_cipher.c
@@ -10,7 +10,7 @@
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "datatypes.h"
#include "null_cipher.h"
#include "alloc.h"
@@ -53,7 +57,7 @@
extern debug_module_t mod_cipher;
err_status_t
-null_cipher_alloc(cipher_t **c, int key_len) {
+null_cipher_alloc(cipher_t **c, int key_len, int tlen) {
extern cipher_type_t null_cipher;
uint8_t *pointer;
@@ -67,6 +71,7 @@ null_cipher_alloc(cipher_t **c, int key_len) {
/* set pointers */
*c = (cipher_t *)pointer;
+ (*c)->algorithm = NULL_CIPHER;
(*c)->type = &null_cipher;
(*c)->state = pointer + sizeof(cipher_t);
@@ -99,7 +104,7 @@ null_cipher_dealloc(cipher_t *c) {
}
err_status_t
-null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key) {
+null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) {
debug_print(mod_cipher, "initializing null cipher", NULL);
@@ -129,6 +134,9 @@ null_cipher_test_0 = {
NULL, /* plaintext */
0, /* octets in plaintext */
NULL, /* ciphertext */
+ 0,
+ NULL,
+ 0,
NULL /* pointer to next testcase */
};
@@ -141,12 +149,15 @@ cipher_type_t null_cipher = {
(cipher_alloc_func_t) null_cipher_alloc,
(cipher_dealloc_func_t) null_cipher_dealloc,
(cipher_init_func_t) null_cipher_init,
+ (cipher_set_aad_func_t) 0,
(cipher_encrypt_func_t) null_cipher_encrypt,
(cipher_decrypt_func_t) null_cipher_encrypt,
(cipher_set_iv_func_t) null_cipher_set_iv,
+ (cipher_get_tag_func_t) 0,
(char *) null_cipher_description,
(int) 0,
(cipher_test_case_t *) &null_cipher_test_0,
- (debug_module_t *) NULL
+ (debug_module_t *) NULL,
+ (cipher_type_id_t) NULL_CIPHER
};
diff --git a/third_party/srtp/crypto/hash/auth.c b/third_party/srtp/crypto/hash/auth.c
index 8eb722d0..4ca0f03e 100644
--- a/third_party/srtp/crypto/hash/auth.c
+++ b/third_party/srtp/crypto/hash/auth.c
@@ -43,6 +43,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "auth.h"
/* the debug module for authentiation */
@@ -74,8 +78,8 @@ auth_type_get_ref_count(const auth_type_t *at) {
}
/*
- * auth_type_self_test() tests an auth function of type ct against
- * test cases provided in an array of values of key, data, and tag
+ * auth_type_test() tests an auth function of type ct against
+ * test cases provided in a list test_data of values of key, data, and tag
* that is known to be good
*/
@@ -83,8 +87,8 @@ auth_type_get_ref_count(const auth_type_t *at) {
#define SELF_TEST_TAG_BUF_OCTETS 32
err_status_t
-auth_type_self_test(const auth_type_t *at) {
- auth_test_case_t *test_case = at->test_data;
+auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) {
+ const auth_test_case_t *test_case = test_data;
auth_t *a;
err_status_t status;
uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
@@ -171,3 +175,13 @@ auth_type_self_test(const auth_type_t *at) {
}
+/*
+ * auth_type_self_test(at) performs auth_type_test on at's internal
+ * list of test data.
+ */
+
+err_status_t
+auth_type_self_test(const auth_type_t *at) {
+ return auth_type_test(at, at->test_data);
+}
+
diff --git a/third_party/srtp/crypto/hash/hmac.c b/third_party/srtp/crypto/hash/hmac.c
index 4336cf0a..ddb75ea3 100644
--- a/third_party/srtp/crypto/hash/hmac.c
+++ b/third_party/srtp/crypto/hash/hmac.c
@@ -42,6 +42,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "hmac.h"
#include "alloc.h"
@@ -262,6 +266,7 @@ hmac = {
(char *) hmac_description,
(int) 0, /* instance count */
(auth_test_case_t *) &hmac_test_case_0,
- (debug_module_t *) &mod_hmac
+ (debug_module_t *) &mod_hmac,
+ (auth_type_id_t) HMAC_SHA1
};
diff --git a/third_party/srtp/crypto/hash/hmac_ossl.c b/third_party/srtp/crypto/hash/hmac_ossl.c
new file mode 100644
index 00000000..f62ce570
--- /dev/null
+++ b/third_party/srtp/crypto/hash/hmac_ossl.c
@@ -0,0 +1,302 @@
+/*
+ * hmac_ossl.c
+ *
+ * Implementation of hmac auth_type_t that leverages OpenSSL
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright(c) 2013, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "hmac.h"
+#include "alloc.h"
+#include <openssl/evp.h>
+
+#define HMAC_KEYLEN_MAX 20
+
+/* the debug module for authentiation */
+
+debug_module_t mod_hmac = {
+ 0, /* debugging is off by default */
+ "hmac sha-1 openssl" /* printable name for module */
+};
+
+
+err_status_t
+hmac_alloc (auth_t **a, int key_len, int out_len)
+{
+ extern auth_type_t hmac;
+ uint8_t *pointer;
+ hmac_ctx_t *new_hmac_ctx;
+
+ debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
+ debug_print(mod_hmac, " tag length %d", out_len);
+
+ /*
+ * check key length - note that we don't support keys larger
+ * than 20 bytes yet
+ */
+ if (key_len > HMAC_KEYLEN_MAX) {
+ return err_status_bad_param;
+ }
+
+ /* check output length - should be less than 20 bytes */
+ if (out_len > HMAC_KEYLEN_MAX) {
+ return err_status_bad_param;
+ }
+
+ /* allocate memory for auth and hmac_ctx_t structures */
+ pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
+ if (pointer == NULL) {
+ return err_status_alloc_fail;
+ }
+
+ /* set pointers */
+ *a = (auth_t*)pointer;
+ (*a)->type = &hmac;
+ (*a)->state = pointer + sizeof(auth_t);
+ (*a)->out_len = out_len;
+ (*a)->key_len = key_len;
+ (*a)->prefix_len = 0;
+ new_hmac_ctx = (hmac_ctx_t*)((*a)->state);
+ memset(new_hmac_ctx, 0, sizeof(hmac_ctx_t));
+
+ /* increment global count of all hmac uses */
+ hmac.ref_count++;
+
+ return err_status_ok;
+}
+
+err_status_t
+hmac_dealloc (auth_t *a)
+{
+ extern auth_type_t hmac;
+ hmac_ctx_t *hmac_ctx;
+
+ hmac_ctx = (hmac_ctx_t*)a->state;
+ if (hmac_ctx->ctx_initialized) {
+ EVP_MD_CTX_cleanup(&hmac_ctx->ctx);
+ }
+ if (hmac_ctx->init_ctx_initialized) {
+ EVP_MD_CTX_cleanup(&hmac_ctx->init_ctx);
+ }
+
+ /* zeroize entire state*/
+ octet_string_set_to_zero((uint8_t*)a,
+ sizeof(hmac_ctx_t) + sizeof(auth_t));
+
+ /* free memory */
+ crypto_free(a);
+
+ /* decrement global count of all hmac uses */
+ hmac.ref_count--;
+
+ return err_status_ok;
+}
+
+err_status_t
+hmac_init (hmac_ctx_t *state, const uint8_t *key, int key_len)
+{
+ int i;
+ uint8_t ipad[64];
+
+ /*
+ * check key length - note that we don't support keys larger
+ * than 20 bytes yet
+ */
+ if (key_len > HMAC_KEYLEN_MAX) {
+ return err_status_bad_param;
+ }
+
+ /*
+ * set values of ipad and opad by exoring the key into the
+ * appropriate constant values
+ */
+ for (i = 0; i < key_len; i++) {
+ ipad[i] = key[i] ^ 0x36;
+ state->opad[i] = key[i] ^ 0x5c;
+ }
+ /* set the rest of ipad, opad to constant values */
+ for (; i < sizeof(ipad); i++) {
+ ipad[i] = 0x36;
+ ((uint8_t*)state->opad)[i] = 0x5c;
+ }
+
+ debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, sizeof(ipad)));
+
+ /* initialize sha1 context */
+ sha1_init(&state->init_ctx);
+ state->init_ctx_initialized = 1;
+
+ /* hash ipad ^ key */
+ sha1_update(&state->init_ctx, ipad, sizeof(ipad));
+ return (hmac_start(state));
+}
+
+err_status_t
+hmac_start (hmac_ctx_t *state)
+{
+ if (state->ctx_initialized) {
+ EVP_MD_CTX_cleanup(&state->ctx);
+ }
+ if (!EVP_MD_CTX_copy(&state->ctx, &state->init_ctx)) {
+ return err_status_auth_fail;
+ } else {
+ state->ctx_initialized = 1;
+ return err_status_ok;
+ }
+}
+
+err_status_t
+hmac_update (hmac_ctx_t *state, const uint8_t *message, int msg_octets)
+{
+ debug_print(mod_hmac, "input: %s",
+ octet_string_hex_string(message, msg_octets));
+
+ /* hash message into sha1 context */
+ sha1_update(&state->ctx, message, msg_octets);
+
+ return err_status_ok;
+}
+
+err_status_t
+hmac_compute (hmac_ctx_t *state, const void *message,
+ int msg_octets, int tag_len, uint8_t *result)
+{
+ uint32_t hash_value[5];
+ uint32_t H[5];
+ int i;
+
+ /* check tag length, return error if we can't provide the value expected */
+ if (tag_len > HMAC_KEYLEN_MAX) {
+ return err_status_bad_param;
+ }
+
+ /* hash message, copy output into H */
+ sha1_update(&state->ctx, message, msg_octets);
+ sha1_final(&state->ctx, H);
+
+ /*
+ * note that we don't need to debug_print() the input, since the
+ * function hmac_update() already did that for us
+ */
+ debug_print(mod_hmac, "intermediate state: %s",
+ octet_string_hex_string((uint8_t*)H, sizeof(H)));
+
+ /* re-initialize hash context */
+ sha1_init(&state->ctx);
+
+ /* hash opad ^ key */
+ sha1_update(&state->ctx, (uint8_t*)state->opad, sizeof(state->opad));
+
+ /* hash the result of the inner hash */
+ sha1_update(&state->ctx, (uint8_t*)H, sizeof(H));
+
+ /* the result is returned in the array hash_value[] */
+ sha1_final(&state->ctx, hash_value);
+
+ /* copy hash_value to *result */
+ for (i = 0; i < tag_len; i++) {
+ result[i] = ((uint8_t*)hash_value)[i];
+ }
+
+ debug_print(mod_hmac, "output: %s",
+ octet_string_hex_string((uint8_t*)hash_value, tag_len));
+
+ return err_status_ok;
+}
+
+
+/* begin test case 0 */
+
+uint8_t
+ hmac_test_case_0_key[HMAC_KEYLEN_MAX] = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b
+};
+
+uint8_t
+ hmac_test_case_0_data[8] = {
+ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
+};
+
+uint8_t
+ hmac_test_case_0_tag[HMAC_KEYLEN_MAX] = {
+ 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
+ 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
+ 0xf1, 0x46, 0xbe, 0x00
+};
+
+auth_test_case_t
+ hmac_test_case_0 = {
+ sizeof(hmac_test_case_0_key), /* octets in key */
+ hmac_test_case_0_key, /* key */
+ sizeof(hmac_test_case_0_data), /* octets in data */
+ hmac_test_case_0_data, /* data */
+ sizeof(hmac_test_case_0_tag), /* octets in tag */
+ hmac_test_case_0_tag, /* tag */
+ NULL /* pointer to next testcase */
+};
+
+/* end test case 0 */
+
+char hmac_description[] = "hmac sha-1 authentication function";
+
+/*
+ * auth_type_t hmac is the hmac metaobject
+ */
+
+auth_type_t
+ hmac = {
+ (auth_alloc_func) hmac_alloc,
+ (auth_dealloc_func) hmac_dealloc,
+ (auth_init_func) hmac_init,
+ (auth_compute_func) hmac_compute,
+ (auth_update_func) hmac_update,
+ (auth_start_func) hmac_start,
+ (char*) hmac_description,
+ (int) 0, /* instance count */
+ (auth_test_case_t*) &hmac_test_case_0,
+ (debug_module_t*) &mod_hmac,
+ (auth_type_id_t) HMAC_SHA1
+};
+
diff --git a/third_party/srtp/crypto/hash/null_auth.c b/third_party/srtp/crypto/hash/null_auth.c
index 301348b6..73fd9187 100644
--- a/third_party/srtp/crypto/hash/null_auth.c
+++ b/third_party/srtp/crypto/hash/null_auth.c
@@ -44,6 +44,9 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#include "null_auth.h"
#include "alloc.h"
@@ -155,6 +158,8 @@ null_auth = {
(auth_start_func) null_auth_start,
(char *) null_auth_description,
(int) 0, /* instance count */
- (auth_test_case_t *) &null_auth_test_case_0
+ (auth_test_case_t *) &null_auth_test_case_0,
+ (debug_module_t *) NULL,
+ (auth_type_id_t) NULL_AUTH
};
diff --git a/third_party/srtp/crypto/hash/sha1.c b/third_party/srtp/crypto/hash/sha1.c
index 566672de..c200437b 100644
--- a/third_party/srtp/crypto/hash/sha1.c
+++ b/third_party/srtp/crypto/hash/sha1.c
@@ -44,6 +44,9 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#include "sha1.h"
@@ -114,7 +117,7 @@ sha1_core(const uint32_t M[16], uint32_t hash_value[5]) {
H4 = hash_value[4];
/* copy/xor message into array */
-
+
W[0] = be32_to_cpu(M[0]);
W[1] = be32_to_cpu(M[1]);
W[2] = be32_to_cpu(M[2]);
@@ -184,7 +187,7 @@ sha1_core(const uint32_t M[16], uint32_t hash_value[5]) {
void
sha1_init(sha1_ctx_t *ctx) {
-
+
/* initialize state vector */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
@@ -210,7 +213,7 @@ sha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) {
/* loop over 16-word blocks of M */
while (octets_in_msg > 0) {
-
+
if (octets_in_msg + ctx->octets_in_buffer >= 64) {
/*
@@ -260,7 +263,7 @@ sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
*/
{
int tail = ctx->octets_in_buffer % 4;
-
+
/* copy/xor message into array */
for (i=0; i < (ctx->octets_in_buffer+3)/4; i++)
W[i] = be32_to_cpu(ctx->M[i]);
@@ -283,7 +286,7 @@ sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
W[i] = 0x80000000;
break;
}
-
+
/* zeroize remaining words */
for (i++ ; i < 15; i++)
W[i] = 0x0;
@@ -299,7 +302,8 @@ sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
else if (ctx->octets_in_buffer < 60)
W[15] = 0x0;
- /* process the word array */ for (t=16; t < 80; t++) {
+ /* process the word array */
+ for (t=16; t < 80; t++) {
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = S1(TEMP);
}
diff --git a/third_party/srtp/crypto/include/aes.h b/third_party/srtp/crypto/include/aes.h
index 20d28047..d88ce403 100644
--- a/third_party/srtp/crypto/include/aes.h
+++ b/third_party/srtp/crypto/include/aes.h
@@ -46,28 +46,32 @@
#ifndef _AES_H
#define _AES_H
-#include "srtp_config.h"
-
#include "datatypes.h"
#include "gf2_8.h"
+#include "err.h"
/* aes internals */
-typedef v128_t aes_expanded_key_t[11];
+typedef struct {
+ v128_t round[15];
+ int num_rounds;
+} aes_expanded_key_t;
-void
-aes_expand_encryption_key(const v128_t *key,
- aes_expanded_key_t expanded_key);
+err_status_t
+aes_expand_encryption_key(const uint8_t *key,
+ int key_len,
+ aes_expanded_key_t *expanded_key);
-void
-aes_expand_decryption_key(const v128_t *key,
- aes_expanded_key_t expanded_key);
+err_status_t
+aes_expand_decryption_key(const uint8_t *key,
+ int key_len,
+ aes_expanded_key_t *expanded_key);
void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
+aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
+aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
#if 0
/*
diff --git a/third_party/srtp/crypto/include/aes_cbc.h b/third_party/srtp/crypto/include/aes_cbc.h
index 9fb6682b..4fda3903 100644
--- a/third_party/srtp/crypto/include/aes_cbc.h
+++ b/third_party/srtp/crypto/include/aes_cbc.h
@@ -8,6 +8,42 @@
*
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef AES_CBC_H
#define AES_CBC_H
@@ -17,6 +53,8 @@
typedef struct {
v128_t state; /* cipher chaining state */
v128_t previous; /* previous ciphertext block */
+ uint8_t key[32];
+ int key_len;
aes_expanded_key_t expanded_key; /* the cipher key */
} aes_cbc_ctx_t;
@@ -31,10 +69,10 @@ aes_cbc_encrypt(aes_cbc_ctx_t *c,
err_status_t
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
- cipher_direction_t dir);
+ int key_len);
err_status_t
-aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv);
+aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv, int direction);
err_status_t
aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
diff --git a/third_party/srtp/crypto/include/aes_gcm_ossl.h b/third_party/srtp/crypto/include/aes_gcm_ossl.h
new file mode 100644
index 00000000..8e7711dc
--- /dev/null
+++ b/third_party/srtp/crypto/include/aes_gcm_ossl.h
@@ -0,0 +1,63 @@
+/*
+ * aes_gcm_ossl.h
+ *
+ * Header for AES Galois Counter Mode.
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ */
+/*
+ *
+ * Copyright (c) 2013, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef AES_GCM_OSSL_H
+#define AES_GCM_OSSL_H
+
+#include "cipher.h"
+#include "srtp.h"
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+
+typedef struct {
+ v256_t key;
+ int key_size;
+ int tag_len;
+ EVP_CIPHER_CTX ctx;
+ cipher_direction_t dir;
+} aes_gcm_ctx_t;
+
+#endif /* AES_GCM_OSSL_H */
+
diff --git a/third_party/srtp/crypto/include/aes_icm.h b/third_party/srtp/crypto/include/aes_icm.h
index 17a1ddba..1a2fd82c 100644
--- a/third_party/srtp/crypto/include/aes_icm.h
+++ b/third_party/srtp/crypto/include/aes_icm.h
@@ -8,6 +8,42 @@
*
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef AES_ICM_H
#define AES_ICM_H
@@ -25,10 +61,11 @@ typedef struct {
err_status_t
aes_icm_context_init(aes_icm_ctx_t *c,
- const unsigned char *key);
+ const unsigned char *key,
+ int key_len);
err_status_t
-aes_icm_set_iv(aes_icm_ctx_t *c, void *iv);
+aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction);
err_status_t
aes_icm_encrypt(aes_icm_ctx_t *c,
@@ -36,7 +73,7 @@ aes_icm_encrypt(aes_icm_ctx_t *c,
err_status_t
aes_icm_output(aes_icm_ctx_t *c,
- unsigned char *buf, int bytes_to_output);
+ unsigned char *buf, unsigned int bytes_to_output);
err_status_t
aes_icm_dealloc(cipher_t *c);
@@ -52,5 +89,8 @@ aes_icm_alloc_ismacryp(cipher_t **c,
int key_len,
int forIsmacryp);
+uint16_t
+aes_icm_bytes_encrypted(aes_icm_ctx_t *c);
+
#endif /* AES_ICM_H */
diff --git a/third_party/srtp/crypto/include/aes_icm_ossl.h b/third_party/srtp/crypto/include/aes_icm_ossl.h
new file mode 100644
index 00000000..b4ec40a4
--- /dev/null
+++ b/third_party/srtp/crypto/include/aes_icm_ossl.h
@@ -0,0 +1,85 @@
+/*
+ * aes_icm.h
+ *
+ * Header for AES Integer Counter Mode.
+ *
+ * David A. McGrew
+ * Cisco Systems, Inc.
+ *
+ */
+/*
+ *
+ * Copyright (c) 2001-2005,2012, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef AES_ICM_H
+#define AES_ICM_H
+
+#include "cipher.h"
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+
+#ifdef OPENSSL_IS_BORINGSSL
+// BoringSSL doesn't support AES-192, cipher will be disabled
+#define SRTP_NO_AES192
+#endif
+
+#define SALT_SIZE 14
+#define AES_128_KEYSIZE AES_BLOCK_SIZE
+#ifndef SRTP_NO_AES192
+#define AES_192_KEYSIZE AES_BLOCK_SIZE + AES_BLOCK_SIZE / 2
+#endif
+#define AES_256_KEYSIZE AES_BLOCK_SIZE * 2
+#define AES_128_KEYSIZE_WSALT AES_128_KEYSIZE + SALT_SIZE
+#ifndef SRTP_NO_AES192
+#define AES_192_KEYSIZE_WSALT AES_192_KEYSIZE + SALT_SIZE
+#endif
+#define AES_256_KEYSIZE_WSALT AES_256_KEYSIZE + SALT_SIZE
+
+typedef struct {
+ v128_t counter; /* holds the counter value */
+ v128_t offset; /* initial offset value */
+ v256_t key;
+ int key_size;
+ EVP_CIPHER_CTX ctx;
+} aes_icm_ctx_t;
+
+err_status_t aes_icm_openssl_set_iv(aes_icm_ctx_t *c, void *iv, int dir);
+err_status_t aes_icm_openssl_context_init(aes_icm_ctx_t *c, const uint8_t *key, int len);
+err_status_t aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output);
+uint16_t aes_icm_bytes_encrypted(aes_icm_ctx_t *c);
+
+
+#endif /* AES_ICM_H */
+
diff --git a/third_party/srtp/crypto/include/auth.h b/third_party/srtp/crypto/include/auth.h
index 295b5f6f..5b5e4b21 100644
--- a/third_party/srtp/crypto/include/auth.h
+++ b/third_party/srtp/crypto/include/auth.h
@@ -48,6 +48,8 @@
#include "datatypes.h"
#include "err.h" /* error codes */
+#include "crypto.h" /* for auth_type_id_t */
+#include "crypto_types.h" /* for values of auth_type_id_t */
typedef struct auth_type_t *auth_type_pointer;
typedef struct auth_t *auth_pointer_t;
@@ -129,6 +131,7 @@ typedef struct auth_type_t {
int ref_count;
auth_test_case_t *test_data;
debug_module_t *debug;
+ auth_type_id_t id;
} auth_type_t;
typedef struct auth_t {
@@ -148,6 +151,15 @@ typedef struct auth_t {
err_status_t
auth_type_self_test(const auth_type_t *at);
+/*
+ * auth_type_test() tests an auth_type against external test cases
+ * provided in an array of values of key/message/tag that is known to
+ * be good
+ */
+
+err_status_t
+auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data);
+
/*
* auth_type_get_ref_count(at) returns the reference count (the number
* of instantiations) of the auth_type_t at
diff --git a/third_party/srtp/crypto/include/cipher.h b/third_party/srtp/crypto/include/cipher.h
index f485660c..d0d6b57f 100644
--- a/third_party/srtp/crypto/include/cipher.h
+++ b/third_party/srtp/crypto/include/cipher.h
@@ -8,7 +8,7 @@
*/
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,8 @@
#include "datatypes.h"
#include "rdbx.h" /* for xtd_seq_num_t */
#include "err.h" /* for error codes */
+#include "crypto.h" /* for cipher_type_id_t */
+#include "crypto_types.h" /* for values of cipher_type_id_t */
/**
@@ -78,15 +80,14 @@ typedef struct cipher_t *cipher_pointer_t;
*/
typedef err_status_t (*cipher_alloc_func_t)
- (cipher_pointer_t *cp, int key_len);
+ (cipher_pointer_t *cp, int key_len, int tag_len);
/*
* a cipher_init_func_t [re-]initializes a cipher_t with a given key
- * and direction (i.e., encrypt or decrypt)
*/
typedef err_status_t (*cipher_init_func_t)
- (void *state, const uint8_t *key, cipher_direction_t dir);
+(void *state, const uint8_t *key, int key_len);
/* a cipher_dealloc_func_t de-allocates a cipher_t */
@@ -97,6 +98,13 @@ typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp);
typedef err_status_t (*cipher_set_segment_func_t)
(void *state, xtd_seq_num_t idx);
+/*
+ * a cipher_set_aad_func_t processes the AAD data for AEAD ciphers
+ */
+typedef err_status_t (*cipher_set_aad_func_t)
+ (void *state, uint8_t *aad, unsigned int aad_len);
+
+
/* a cipher_encrypt_func_t encrypts data in-place */
typedef err_status_t (*cipher_encrypt_func_t)
@@ -108,12 +116,19 @@ typedef err_status_t (*cipher_decrypt_func_t)
(void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);
/*
- * a cipher_set_nonce_seq_func_t function sets both the nonce
- * and the extended sequence number
+ * a cipher_set_iv_func_t function sets the current initialization vector
*/
typedef err_status_t (*cipher_set_iv_func_t)
- (cipher_pointer_t cp, void *iv);
+ (cipher_pointer_t cp, void *iv, cipher_direction_t direction);
+
+/*
+ * a cipher_get_tag_funct_t function is used to get the authentication
+ * tag that was calculated by an AEAD cipher.
+ */
+typedef err_status_t (*cipher_get_tag_func_t)
+ (void *state, void *tag, int *len);
+
/*
* cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t,
@@ -127,10 +142,13 @@ typedef struct cipher_test_case_t {
int key_length_octets; /* octets in key */
uint8_t *key; /* key */
uint8_t *idx; /* packet index */
- unsigned int plaintext_length_octets; /* octets in plaintext */
+ int plaintext_length_octets; /* octets in plaintext */
uint8_t *plaintext; /* plaintext */
- unsigned int ciphertext_length_octets; /* octets in plaintext */
+ int ciphertext_length_octets; /* octets in plaintext */
uint8_t *ciphertext; /* ciphertext */
+ int aad_length_octets; /* octets in AAD */
+ uint8_t *aad; /* AAD */
+ int tag_length_octets; /* Length of AEAD tag */
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */
} cipher_test_case_t;
@@ -140,13 +158,16 @@ typedef struct cipher_type_t {
cipher_alloc_func_t alloc;
cipher_dealloc_func_t dealloc;
cipher_init_func_t init;
+ cipher_set_aad_func_t set_aad;
cipher_encrypt_func_t encrypt;
cipher_encrypt_func_t decrypt;
cipher_set_iv_func_t set_iv;
+ cipher_get_tag_func_t get_tag;
char *description;
int ref_count;
cipher_test_case_t *test_data;
debug_module_t *debug;
+ cipher_type_id_t id;
} cipher_type_t;
/*
@@ -158,27 +179,32 @@ typedef struct cipher_t {
cipher_type_t *type;
void *state;
int key_len;
-#ifdef FORCE_64BIT_ALIGN
- int pad;
-#endif
+ int algorithm;
} cipher_t;
/* some syntactic sugar on these function types */
-#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen)))
+#define cipher_type_alloc(ct, c, klen, tlen) ((ct)->alloc((c), (klen), (tlen)))
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
-#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), (dir)))
+#define cipher_init(c, k) (((c)->type)->init(((c)->state), (k), ((c)->key_len)))
#define cipher_encrypt(c, buf, len) \
(((c)->type)->encrypt(((c)->state), (buf), (len)))
+#define cipher_get_tag(c, buf, len) \
+ (((c)->type)->get_tag(((c)->state), (buf), (len)))
+
#define cipher_decrypt(c, buf, len) \
(((c)->type)->decrypt(((c)->state), (buf), (len)))
-#define cipher_set_iv(c, n) \
- ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) : \
+#define cipher_set_iv(c, n, dir) \
+ ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n), (dir))) : \
+ err_status_no_such_op)
+#define cipher_set_aad(c, a, l) \
+ (((c) && (((c)->type)->set_aad)) ? \
+ (((c)->type)->set_aad(((c)->state), (a), (l))) : \
err_status_no_such_op)
err_status_t
@@ -201,6 +227,16 @@ err_status_t
cipher_type_self_test(const cipher_type_t *ct);
+/*
+ * cipher_type_test() tests a cipher against external test cases provided in
+ * an array of values of key/xtd_seq_num_t/plaintext/ciphertext
+ * that is known to be good
+ */
+
+err_status_t
+cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data);
+
+
/*
* cipher_bits_per_second(c, l, t) computes (and estimate of) the
* number of bits that a cipher implementation can encrypt in a second
diff --git a/third_party/srtp/crypto/include/crypto.h b/third_party/srtp/crypto/include/crypto.h
index 0e9667da..ab6f6bef 100644
--- a/third_party/srtp/crypto/include/crypto.h
+++ b/third_party/srtp/crypto/include/crypto.h
@@ -7,6 +7,42 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef CRYPTO_H
#define CRYPTO_H
diff --git a/third_party/srtp/crypto/include/crypto_kernel.h b/third_party/srtp/crypto/include/crypto_kernel.h
index b8cd9be1..caccfa03 100644
--- a/third_party/srtp/crypto/include/crypto_kernel.h
+++ b/third_party/srtp/crypto/include/crypto_kernel.h
@@ -182,6 +182,28 @@ crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
err_status_t
crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);
+/*
+ * crypto_kernel_replace_cipher_type(ct, id)
+ *
+ * replaces the crypto kernel's existing cipher for the cipher_type id
+ * with a new one passed in externally. The new cipher must pass all the
+ * existing cipher_type's self tests as well as its own.
+ */
+err_status_t
+crypto_kernel_replace_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
+
+
+/*
+ * crypto_kernel_replace_auth_type(ct, id)
+ *
+ * replaces the crypto kernel's existing cipher for the auth_type id
+ * with a new one passed in externally. The new auth type must pass all the
+ * existing auth_type's self tests as well as its own.
+ */
+err_status_t
+crypto_kernel_replace_auth_type(auth_type_t *ct, auth_type_id_t id);
+
+
err_status_t
crypto_kernel_load_debug_module(debug_module_t *new_dm);
@@ -199,7 +221,8 @@ crypto_kernel_load_debug_module(debug_module_t *new_dm);
err_status_t
crypto_kernel_alloc_cipher(cipher_type_id_t id,
cipher_pointer_t *cp,
- int key_len);
+ int key_len,
+ int tag_len);
/*
* crypto_kernel_alloc_auth(id, ap, key_len, tag_len);
diff --git a/third_party/srtp/crypto/include/crypto_math.h b/third_party/srtp/crypto/include/crypto_math.h
index c3e7b76b..52f08372 100644
--- a/third_party/srtp/crypto/include/crypto_math.h
+++ b/third_party/srtp/crypto/include/crypto_math.h
@@ -233,40 +233,6 @@ void
octet_string_set_to_zero(uint8_t *s, int len);
-/*
- * functions manipulating bit_vector_t
- *
- * A bitvector_t consists of an array of words and an integer
- * representing the number of significant bits stored in the array.
- * The bits are packed as follows: the least significant bit is that
- * of word[0], while the most significant bit is the nth most
- * significant bit of word[m], where length = bits_per_word * m + n.
- *
- */
-
-#define bits_per_word 32
-#define bytes_per_word 4
-
-typedef struct {
- uint32_t length;
- uint32_t *word;
-} bitvector_t;
-
-int
-bitvector_alloc(bitvector_t *v, unsigned long length);
-
-void
-bitvector_set_bit(bitvector_t *v, int bit_index);
-
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index);
-
-int
-bitvector_print_hex(const bitvector_t *v, FILE *stream);
-
-int
-bitvector_set_from_hex(bitvector_t *v, char *string);
-
#endif /* MATH_H */
diff --git a/third_party/srtp/crypto/include/crypto_types.h b/third_party/srtp/crypto/include/crypto_types.h
index 0ce50f4b..dbb50c37 100644
--- a/third_party/srtp/crypto/include/crypto_types.h
+++ b/third_party/srtp/crypto/include/crypto_types.h
@@ -8,7 +8,7 @@
*/
/*
*
- * Copyright(c) 2001-2006 Cisco Systems, Inc.
+ * Copyright(c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -97,12 +97,19 @@
#define NULL_CIPHER 0
/**
- * @brief AES-128 Integer Counter Mode (AES ICM)
+ * @brief AES Integer Counter Mode (AES ICM)
*
- * AES-128 ICM is the variant of counter mode that is used by Secure RTP.
- * This cipher uses a 16-octet key and a 30-octet offset (or salt) value.
+ * AES ICM is the variant of counter mode that is used by Secure RTP.
+ * This cipher uses a 16-, 24-, or 32-octet key concatenated with a
+ * 14-octet offset (or salt) value.
+ */
+#define AES_ICM 1
+
+/**
+ * @brief AES-128 Integer Counter Mode (AES ICM)
+ * AES-128 ICM is a deprecated alternate name for AES ICM.
*/
-#define AES_128_ICM 1
+#define AES_128_ICM AES_ICM
/**
* @brief SEAL 3.0
@@ -113,19 +120,54 @@
#define SEAL 2
/**
- * @brief AES-128 Integer Counter Mode (AES ICM)
+ * @brief AES Cipher Block Chaining mode (AES CBC)
*
- * AES-128 ICM is the variant of counter mode that is used by Secure RTP.
- * This cipher uses a 16-octet key and a 30-octet offset (or salt) value.
+ * AES CBC is the AES Cipher Block Chaining mode.
+ * This cipher uses a 16-, 24-, or 32-octet key.
*/
-#define AES_128_CBC 3
+#define AES_CBC 3
+
+/**
+ * @brief AES-128 Cipher Block Chaining mode (AES CBC)
+ *
+ * AES-128 CBC is a deprecated alternate name for AES CBC.
+ */
+#define AES_128_CBC AES_CBC
/**
* @brief Strongest available cipher.
*
* This identifier resolves to the strongest cipher type available.
*/
-#define STRONGHOLD_CIPHER AES_128_ICM
+#define STRONGHOLD_CIPHER AES_ICM
+
+/**
+ * @brief AES-192 Integer Counter Mode (AES ICM)
+ * AES-192 ICM is a deprecated alternate name for AES ICM.
+ */
+#define AES_192_ICM 4
+
+/**
+ * @brief AES-256 Integer Counter Mode (AES ICM)
+ * AES-256 ICM is a deprecated alternate name for AES ICM.
+ */
+#define AES_256_ICM 5
+
+/**
+ * @brief AES-128_GCM Galois Counter Mode (AES GCM)
+ *
+ * AES-128 GCM is the variant of galois counter mode that is used by
+ * Secure RTP. This cipher uses a 16-octet key.
+ */
+#define AES_128_GCM 6
+
+/**
+ * @brief AES-256_GCM Galois Counter Mode (AES GCM)
+ *
+ * AES-256 GCM is the variant of galois counter mode that is used by
+ * Secure RTP. This cipher uses a 32-octet key.
+ */
+#define AES_256_GCM 7
/**
* @}
diff --git a/third_party/srtp/crypto/include/datatypes.h b/third_party/srtp/crypto/include/datatypes.h
index 4f86b556..b18435f0 100644
--- a/third_party/srtp/crypto/include/datatypes.h
+++ b/third_party/srtp/crypto/include/datatypes.h
@@ -92,6 +92,12 @@ typedef union {
uint64_t v64[2];
} v128_t;
+typedef union {
+ uint8_t v8[32];
+ uint16_t v16[16];
+ uint32_t v32[8];
+ uint64_t v64[4];
+} v256_t;
/* some useful and simple math functions */
@@ -155,10 +161,10 @@ void
v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
void
-v128_left_shift(v128_t *x, int index);
+v128_left_shift(v128_t *x, int shift_index);
void
-v128_right_shift(v128_t *x, int index);
+v128_right_shift(v128_t *x, int shift_index);
/*
* the following macros define the data manipulation functions
@@ -377,7 +383,7 @@ void
octet_string_set_to_zero(uint8_t *s, int len);
-#ifndef SRTP_KERNEL_LINUX
+#if !defined(SRTP_KERNEL_LINUX) && defined(HAVE_CONFIG_H)
/*
* Convert big endian integers to CPU byte order.
@@ -424,4 +430,87 @@ static inline uint64_t be64_to_cpu(uint64_t v) {
#endif /* WORDS_BIGENDIAN */
+/*
+ * functions manipulating bitvector_t
+ *
+ * A bitvector_t consists of an array of words and an integer
+ * representing the number of significant bits stored in the array.
+ * The bits are packed as follows: the least significant bit is that
+ * of word[0], while the most significant bit is the nth most
+ * significant bit of word[m], where length = bits_per_word * m + n.
+ *
+ */
+
+#define bits_per_word 32
+#define bytes_per_word 4
+
+typedef struct {
+ uint32_t length;
+ uint32_t *word;
+} bitvector_t;
+
+
+#define _bitvector_get_bit(v, bit_index) \
+( \
+ ((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \
+)
+
+
+#define _bitvector_set_bit(v, bit_index) \
+( \
+ (((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \
+)
+
+#define _bitvector_clear_bit(v, bit_index) \
+( \
+ (((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \
+)
+
+#define _bitvector_get_length(v) \
+( \
+ ((v)->length) \
+)
+
+#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
+
+#define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index)
+#define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index)
+#define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index)
+#define bitvector_get_length(v) _bitvector_get_length(v)
+
+#else
+
+int
+bitvector_get_bit(const bitvector_t *v, int bit_index);
+
+void
+bitvector_set_bit(bitvector_t *v, int bit_index);
+
+void
+bitvector_clear_bit(bitvector_t *v, int bit_index);
+
+unsigned long
+bitvector_get_length(const bitvector_t *v);
+
+#endif
+
+int
+bitvector_alloc(bitvector_t *v, unsigned long length);
+
+void
+bitvector_dealloc(bitvector_t *v);
+
+void
+bitvector_set_to_zero(bitvector_t *x);
+
+void
+bitvector_left_shift(bitvector_t *x, int index);
+
+char *
+bitvector_bit_string(bitvector_t *x, char* buf, int len);
+
+#ifdef TESTAPP_SOURCE
+int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len);
+#endif
+
#endif /* _DATATYPES_H */
diff --git a/third_party/srtp/crypto/include/err.h b/third_party/srtp/crypto/include/err.h
index 1a6e1701..4f401a6d 100644
--- a/third_party/srtp/crypto/include/err.h
+++ b/third_party/srtp/crypto/include/err.h
@@ -46,7 +46,8 @@
#ifndef ERR_H
#define ERR_H
-#include "datatypes.h"
+#include <stdio.h>
+#include <stdarg.h>
/**
* @defgroup Error Error Codes
@@ -87,7 +88,7 @@ typedef enum {
err_status_nonce_bad = 18, /**< nonce check failed */
err_status_read_fail = 19, /**< couldn't read data */
err_status_write_fail = 20, /**< couldn't write data */
- err_status_parse_err = 21, /**< error pasring data */
+ err_status_parse_err = 21, /**< error parsing data */
err_status_encode_err = 22, /**< error encoding data */
err_status_semaphore_err = 23,/**< error while using semaphores */
err_status_pfkey_err = 24 /**< error while using pfkey */
@@ -118,7 +119,7 @@ typedef enum {
*/
err_status_t
-err_reporting_init(char *ident);
+err_reporting_init(const char *ident);
#ifdef SRTP_KERNEL_LINUX
extern err_reporting_level_t err_level;
@@ -135,7 +136,7 @@ extern err_reporting_level_t err_level;
*/
void
-err_report(int priority, char *format, ...);
+err_report(int priority, const char *format, ...);
#endif /* ! SRTP_KERNEL_LINUX */
@@ -145,7 +146,7 @@ err_report(int priority, char *format, ...);
typedef struct {
int on; /* 1 if debugging is on, 0 if it is off */
- char *name; /* printable name for debug module */
+ const char *name; /* printable name for debug module */
} debug_module_t;
#ifdef ENABLE_DEBUGGING
diff --git a/third_party/srtp/crypto/include/hmac.h b/third_party/srtp/crypto/include/hmac.h
index 262c0e2d..875f45c6 100644
--- a/third_party/srtp/crypto/include/hmac.h
+++ b/third_party/srtp/crypto/include/hmac.h
@@ -9,7 +9,7 @@
*/
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -53,6 +53,10 @@ typedef struct {
uint8_t opad[64];
sha1_ctx_t ctx;
sha1_ctx_t init_ctx;
+#ifdef OPENSSL
+ int ctx_initialized;
+ int init_ctx_initialized;
+#endif
} hmac_ctx_t;
err_status_t
diff --git a/third_party/srtp/crypto/include/integers.h b/third_party/srtp/crypto/include/integers.h
index 138ea9c5..179ec39f 100644
--- a/third_party/srtp/crypto/include/integers.h
+++ b/third_party/srtp/crypto/include/integers.h
@@ -47,7 +47,7 @@
#ifndef INTEGERS_H
#define INTEGERS_H
-#include "srtp_config.h" /* configuration file, using autoconf */
+#include "config.h"
#ifdef SRTP_KERNEL
@@ -76,7 +76,7 @@
#endif
/* Can we do 64 bit integers? */
-#ifndef HAVE_UINT64_T
+#if !defined(HAVE_UINT64_T)
# if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long uint64_t;
# elif SIZEOF_UNSIGNED_LONG_LONG == 8
@@ -99,7 +99,7 @@ typedef unsigned int uint32_t;
#endif
-#ifdef NO_64BIT_MATH
+#if defined(NO_64BIT_MATH) && defined(HAVE_CONFIG_H)
typedef double uint64_t;
/* assert that sizeof(double) == 8 */
extern uint64_t make64(uint32_t high, uint32_t low);
diff --git a/third_party/srtp/crypto/include/null_cipher.h b/third_party/srtp/crypto/include/null_cipher.h
index 7d6bbdd6..39da59a8 100644
--- a/third_party/srtp/crypto/include/null_cipher.h
+++ b/third_party/srtp/crypto/include/null_cipher.h
@@ -62,11 +62,11 @@ typedef struct {
*/
err_status_t
-null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key);
+null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key, int key_len);
err_status_t
null_cipher_set_segment(null_cipher_ctx_t *c,
- unsigned long index);
+ unsigned long segment_index);
err_status_t
null_cipher_encrypt(null_cipher_ctx_t *c,
diff --git a/third_party/srtp/crypto/include/prng.h b/third_party/srtp/crypto/include/prng.h
index fb96b5eb..c5ec2306 100644
--- a/third_party/srtp/crypto/include/prng.h
+++ b/third_party/srtp/crypto/include/prng.h
@@ -7,12 +7,53 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef PRNG_H
#define PRNG_H
#include "rand_source.h" /* for rand_source_func_t definition */
#include "aes.h" /* for aes */
+//FIXME: this is temporary until we pull in the code to use OpenSSL for RNG
+#ifdef OPENSSL
+#include "aes_icm_ossl.h" /* for aes ctr */
+#else
#include "aes_icm.h" /* for aes ctr */
+#endif
#define MAX_PRNG_OUT_LEN 0xffffffffU
diff --git a/third_party/srtp/crypto/include/rdb.h b/third_party/srtp/crypto/include/rdb.h
index 5a26c5e3..300c569f 100644
--- a/third_party/srtp/crypto/include/rdb.h
+++ b/third_party/srtp/crypto/include/rdb.h
@@ -8,6 +8,42 @@
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef REPLAY_DB_H
#define REPLAY_DB_H
@@ -49,7 +85,7 @@ rdb_init(rdb_t *rdb);
*/
err_status_t
-rdb_check(const rdb_t *rdb, uint32_t index);
+rdb_check(const rdb_t *rdb, uint32_t rdb_index);
/*
* rdb_add_index
@@ -61,7 +97,7 @@ rdb_check(const rdb_t *rdb, uint32_t index);
*/
err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t index);
+rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
/*
* the functions rdb_increment() and rdb_get_value() are for use by
diff --git a/third_party/srtp/crypto/include/rdbx.h b/third_party/srtp/crypto/include/rdbx.h
index ce9ecf6f..4b8dd229 100644
--- a/third_party/srtp/crypto/include/rdbx.h
+++ b/third_party/srtp/crypto/include/rdbx.h
@@ -8,6 +8,42 @@
*
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef RDBX_H
#define RDBX_H
@@ -46,19 +82,29 @@ typedef uint64_t xtd_seq_num_t;
typedef struct {
xtd_seq_num_t index;
- v128_t bitmask;
+ bitvector_t bitmask;
} rdbx_t;
/*
- * rdbx_init(rdbx_ptr)
+ * rdbx_init(rdbx_ptr, ws)
*
- * initializes the rdbx pointed to by its argument, setting the
- * rollover counter and sequence number to zero
+ * initializes the rdbx pointed to by its argument with the window size ws,
+ * setting the rollover counter and sequence number to zero
*/
err_status_t
-rdbx_init(rdbx_t *rdbx);
+rdbx_init(rdbx_t *rdbx, unsigned long ws);
+
+
+/*
+ * rdbx_dealloc(rdbx_ptr)
+ *
+ * frees memory associated with the rdbx
+ */
+
+err_status_t
+rdbx_dealloc(rdbx_t *rdbx);
/*
@@ -100,12 +146,42 @@ rdbx_check(const rdbx_t *rdbx, int difference);
err_status_t
rdbx_add_index(rdbx_t *rdbx, int delta);
+
+/*
+ * rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx
+ * to have the rollover counter value roc. If that value is less than
+ * the current rollover counter value, then the function returns
+ * err_status_replay_old; otherwise, err_status_ok is returned.
+ *
+ */
+
+err_status_t
+rdbx_set_roc(rdbx_t *rdbx, uint32_t roc);
+
+/*
+ * rdbx_get_roc(rdbx) returns the value of the rollover counter for
+ * the rdbx_t pointed to by rdbx
+ *
+ */
+
+xtd_seq_num_t
+rdbx_get_packet_index(const rdbx_t *rdbx);
+
/*
* xtd_seq_num_t functions - these are *internal* functions of rdbx, and
* shouldn't be used to manipulate rdbx internal values. use the rdbx
* api instead!
*/
+/*
+ * rdbx_get_ws(rdbx_ptr)
+ *
+ * gets the window size which was used to initialize the rdbx
+ */
+
+unsigned long
+rdbx_get_window_size(const rdbx_t *rdbx);
+
/* index_init(&pi) initializes a packet index pi (sets it to zero) */
diff --git a/third_party/srtp/crypto/include/sha1.h b/third_party/srtp/crypto/include/sha1.h
index e3af4d4b..f1744ced 100644
--- a/third_party/srtp/crypto/include/sha1.h
+++ b/third_party/srtp/crypto/include/sha1.h
@@ -47,7 +47,49 @@
#ifndef SHA1_H
#define SHA1_H
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "err.h"
+#ifdef OPENSSL
+#include <openssl/evp.h>
+#include <stdint.h>
+
+typedef EVP_MD_CTX sha1_ctx_t;
+
+/*
+ * sha1_init(&ctx) initializes the SHA1 context ctx
+ *
+ * sha1_update(&ctx, msg, len) hashes the len octets starting at msg
+ * into the SHA1 context
+ *
+ * sha1_final(&ctx, output) performs the final processing of the SHA1
+ * context and writes the result to the 20 octets at output
+ *
+ * Return values are ignored on the EVP functions since all three
+ * of these functions return void.
+ *
+ */
+
+static inline void sha1_init (sha1_ctx_t *ctx)
+{
+ EVP_MD_CTX_init(ctx);
+ EVP_DigestInit(ctx, EVP_sha1());
+}
+
+static inline void sha1_update (sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg)
+{
+ EVP_DigestUpdate(ctx, M, octets_in_msg);
+}
+
+static inline void sha1_final (sha1_ctx_t *ctx, uint32_t *output)
+{
+ unsigned int len = 0;
+
+ EVP_DigestFinal(ctx, (unsigned char*)output, &len);
+}
+#else
#include "datatypes.h"
typedef struct {
@@ -104,5 +146,7 @@ sha1_final(sha1_ctx_t *ctx, uint32_t output[5]);
void
sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
+
+#endif /* else OPENSSL */
#endif /* SHA1_H */
diff --git a/third_party/srtp/crypto/include/xfm.h b/third_party/srtp/crypto/include/xfm.h
index 5837149b..80774f96 100644
--- a/third_party/srtp/crypto/include/xfm.h
+++ b/third_party/srtp/crypto/include/xfm.h
@@ -7,6 +7,42 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#ifndef XFM_H
#define XFM_H
diff --git a/third_party/srtp/crypto/kernel/alloc.c b/third_party/srtp/crypto/kernel/alloc.c
index 5dd09474..e728798c 100644
--- a/third_party/srtp/crypto/kernel/alloc.c
+++ b/third_party/srtp/crypto/kernel/alloc.c
@@ -42,6 +42,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "alloc.h"
#include "crypto_kernel.h"
@@ -73,8 +77,9 @@ crypto_alloc(size_t size) {
if (ptr) {
debug_print(mod_alloc, "(location: %p) allocated", ptr);
- } else
+ } else {
debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
+ }
return ptr;
}
@@ -98,9 +103,10 @@ crypto_alloc(size_t size) {
if (ptr) {
debug_print(mod_alloc, "(location: %p) allocated", ptr);
- } else
+ } else {
debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
-
+ }
+
return ptr;
}
diff --git a/third_party/srtp/crypto/kernel/crypto_kernel.c b/third_party/srtp/crypto/kernel/crypto_kernel.c
index 230dda62..f01a72a5 100644
--- a/third_party/srtp/crypto/kernel/crypto_kernel.c
+++ b/third_party/srtp/crypto/kernel/crypto_kernel.c
@@ -8,7 +8,7 @@
*/
/*
*
- * Copyright(c) 2001-2006 Cisco Systems, Inc.
+ * Copyright(c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "alloc.h"
#include "crypto_kernel.h"
@@ -69,7 +73,12 @@ extern debug_module_t mod_alloc;
extern cipher_type_t null_cipher;
extern cipher_type_t aes_icm;
+#ifndef OPENSSL
extern cipher_type_t aes_cbc;
+#else
+extern cipher_type_t aes_gcm_128_openssl;
+extern cipher_type_t aes_gcm_256_openssl;
+#endif
/*
@@ -137,6 +146,7 @@ crypto_kernel_init() {
if (status)
return status;
+#ifndef OPENSSL
/* initialize pseudorandom number generator */
status = ctr_prng_init(rand_source_get_octet_string);
if (status)
@@ -146,17 +156,29 @@ crypto_kernel_init() {
status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);
if (status)
return status;
+#endif
/* load cipher types */
status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
if (status)
return status;
- status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM);
+ status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
if (status)
return status;
- status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC);
+#ifndef OPENSSL
+ status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
if (status)
return status;
+#else
+ status = crypto_kernel_load_cipher_type(&aes_gcm_128_openssl, AES_128_GCM);
+ if (status) {
+ return status;
+ }
+ status = crypto_kernel_load_cipher_type(&aes_gcm_256_openssl, AES_256_GCM);
+ if (status) {
+ return status;
+ }
+#endif
/* load auth func types */
status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
@@ -297,8 +319,9 @@ crypto_kernel_shutdown() {
return err_status_ok;
}
-err_status_t
-crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
+static inline err_status_t
+crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id,
+ int replace) {
kernel_cipher_type_t *ctype, *new_ctype;
err_status_t status;
@@ -306,6 +329,9 @@ crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
if (new_ct == NULL)
return err_status_bad_param;
+ if (new_ct->id != id)
+ return err_status_bad_param;
+
/* check cipher type by running self-test */
status = cipher_type_self_test(new_ct);
if (status) {
@@ -315,24 +341,35 @@ crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
/* walk down list, checking if this type is in the list already */
ctype = crypto_kernel.cipher_type_list;
while (ctype != NULL) {
- if ((new_ct == ctype->cipher_type) || (id == ctype->id))
+ if (id == ctype->id) {
+ if (!replace)
+ return err_status_bad_param;
+ status = cipher_type_test(new_ct, ctype->cipher_type->test_data);
+ if (status)
+ return status;
+ new_ctype = ctype;
+ break;
+ }
+ else if (new_ct == ctype->cipher_type)
return err_status_bad_param;
ctype = ctype->next;
}
- /* put new_ct at the head of the list */
+ /* if not found, put new_ct at the head of the list */
+ if (ctype == NULL) {
/* allocate memory */
- new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
- if (new_ctype == NULL)
- return err_status_alloc_fail;
+ new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
+ if (new_ctype == NULL)
+ return err_status_alloc_fail;
+ new_ctype->next = crypto_kernel.cipher_type_list;
+
+ /* set head of list to new cipher type */
+ crypto_kernel.cipher_type_list = new_ctype;
+ }
/* set fields */
new_ctype->cipher_type = new_ct;
new_ctype->id = id;
- new_ctype->next = crypto_kernel.cipher_type_list;
-
- /* set head of list to new cipher type */
- crypto_kernel.cipher_type_list = new_ctype;
/* load debug module, if there is one present */
if (new_ct->debug != NULL)
@@ -343,7 +380,18 @@ crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
}
err_status_t
-crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
+crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
+ return crypto_kernel_do_load_cipher_type(new_ct, id, 0);
+}
+
+err_status_t
+crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
+ return crypto_kernel_do_load_cipher_type(new_ct, id, 1);
+}
+
+err_status_t
+crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id,
+ int replace) {
kernel_auth_type_t *atype, *new_atype;
err_status_t status;
@@ -351,6 +399,9 @@ crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
if (new_at == NULL)
return err_status_bad_param;
+ if (new_at->id != id)
+ return err_status_bad_param;
+
/* check auth type by running self-test */
status = auth_type_self_test(new_at);
if (status) {
@@ -360,24 +411,35 @@ crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
/* walk down list, checking if this type is in the list already */
atype = crypto_kernel.auth_type_list;
while (atype != NULL) {
- if ((new_at == atype->auth_type) || (id == atype->id))
+ if (id == atype->id) {
+ if (!replace)
+ return err_status_bad_param;
+ status = auth_type_test(new_at, atype->auth_type->test_data);
+ if (status)
+ return status;
+ new_atype = atype;
+ break;
+ }
+ else if (new_at == atype->auth_type)
return err_status_bad_param;
atype = atype->next;
}
- /* put new_at at the head of the list */
- /* allocate memory */
- new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
- if (new_atype == NULL)
- return err_status_alloc_fail;
+ /* if not found, put new_at at the head of the list */
+ if (atype == NULL) {
+ /* allocate memory */
+ new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
+ if (new_atype == NULL)
+ return err_status_alloc_fail;
+
+ new_atype->next = crypto_kernel.auth_type_list;
+ /* set head of list to new auth type */
+ crypto_kernel.auth_type_list = new_atype;
+ }
/* set fields */
new_atype->auth_type = new_at;
new_atype->id = id;
- new_atype->next = crypto_kernel.auth_type_list;
-
- /* set head of list to new auth type */
- crypto_kernel.auth_type_list = new_atype;
/* load debug module, if there is one present */
if (new_at->debug != NULL)
@@ -388,6 +450,16 @@ crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
}
+err_status_t
+crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
+ return crypto_kernel_do_load_auth_type(new_at, id, 0);
+}
+
+err_status_t
+crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) {
+ return crypto_kernel_do_load_auth_type(new_at, id, 1);
+}
+
cipher_type_t *
crypto_kernel_get_cipher_type(cipher_type_id_t id) {
@@ -409,7 +481,8 @@ crypto_kernel_get_cipher_type(cipher_type_id_t id) {
err_status_t
crypto_kernel_alloc_cipher(cipher_type_id_t id,
cipher_pointer_t *cp,
- int key_len) {
+ int key_len,
+ int tag_len) {
cipher_type_t *ct;
/*
@@ -423,7 +496,7 @@ crypto_kernel_alloc_cipher(cipher_type_id_t id,
if (!ct)
return err_status_fail;
- return ((ct)->alloc(cp, key_len));
+ return ((ct)->alloc(cp, key_len, tag_len));
}
@@ -517,7 +590,11 @@ crypto_kernel_set_debug_module(char *name, int on) {
err_status_t
crypto_get_random(unsigned char *buffer, unsigned int length) {
if (crypto_kernel.state == crypto_kernel_state_secure)
+#ifdef OPENSSL
+ return rand_source_get_octet_string(buffer, length);
+#else
return ctr_prng_get_octet_string(buffer, length);
+#endif
else
return err_status_fail;
}
diff --git a/third_party/srtp/crypto/kernel/err.c b/third_party/srtp/crypto/kernel/err.c
index 4a3a8589..fcd90784 100644
--- a/third_party/srtp/crypto/kernel/err.c
+++ b/third_party/srtp/crypto/kernel/err.c
@@ -42,6 +42,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "err.h"
#ifdef ERR_REPORTING_SYSLOG
@@ -57,7 +61,7 @@ err_reporting_level_t err_level = err_level_none;
#ifdef SRTP_KERNEL_LINUX
err_status_t
-err_reporting_init(char *ident) {
+err_reporting_init(const char *ident) {
return err_status_ok;
}
@@ -69,7 +73,7 @@ err_reporting_init(char *ident) {
static FILE *err_file = NULL;
err_status_t
-err_reporting_init(char *ident) {
+err_reporting_init(const char *ident) {
#ifdef ERR_REPORTING_SYSLOG
openlog(ident, LOG_PID, LOG_AUTHPRIV);
#endif
@@ -92,7 +96,7 @@ err_reporting_init(char *ident) {
}
void
-err_report(int priority, char *format, ...) {
+err_report(int priority, const char *format, ...) {
va_list args;
if (priority <= err_level) {
diff --git a/third_party/srtp/crypto/kernel/key.c b/third_party/srtp/crypto/kernel/key.c
index 9f63b22c..3521e2f8 100644
--- a/third_party/srtp/crypto/kernel/key.c
+++ b/third_party/srtp/crypto/kernel/key.c
@@ -42,6 +42,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "key.h"
#define soft_limit 0x10000
diff --git a/third_party/srtp/crypto/math/datatypes.c b/third_party/srtp/crypto/math/datatypes.c
index c8f44a52..a30873ee 100644
--- a/third_party/srtp/crypto/math/datatypes.c
+++ b/third_party/srtp/crypto/math/datatypes.c
@@ -43,6 +43,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "datatypes.h"
int
@@ -113,8 +117,8 @@ octet_string_hex_string(const void *s, int length) {
length *= 2;
/* truncate string if it would be too long */
- if (length >= MAX_PRINT_STRING_LEN-1)
- length = MAX_PRINT_STRING_LEN-2;
+ if (length > MAX_PRINT_STRING_LEN)
+ length = MAX_PRINT_STRING_LEN-1;
for (i=0; i < length; i+=2) {
bit_string[i] = nibble_to_hex_char(*str >> 4);
@@ -149,9 +153,10 @@ hex_char_to_nibble(uint8_t c) {
case ('E'): return 0xe;
case ('f'): return 0xf;
case ('F'): return 0xf;
- default: break; /* this flags an error */
+ default: return -1; /* this flags an error */
}
- return -1;
+ /* NOTREACHED */
+ return -1; /* this keeps compilers from complaining */
}
int
@@ -206,16 +211,16 @@ v128_hex_string(v128_t *x) {
char *
v128_bit_string(v128_t *x) {
- int j, index;
+ int j, i;
uint32_t mask;
- for (j=index=0; j < 4; j++) {
+ for (j=i=0; j < 4; j++) {
for (mask=0x80000000; mask > 0; mask >>= 1) {
if (x->v32[j] & mask)
- bit_string[index] = '1';
+ bit_string[i] = '1';
else
- bit_string[index] = '0';
- ++index;
+ bit_string[i] = '0';
+ ++i;
}
}
bit_string[128] = 0; /* null terminate string */
@@ -322,13 +327,13 @@ v128_set_bit_to(v128_t *x, int i, int y){
#endif /* DATATYPES_USE_MACROS */
void
-v128_right_shift(v128_t *x, int index) {
- const int base_index = index >> 5;
- const int bit_index = index & 31;
+v128_right_shift(v128_t *x, int shift) {
+ const int base_index = shift >> 5;
+ const int bit_index = shift & 31;
int i, from;
uint32_t b;
- if (index > 127) {
+ if (shift > 127) {
v128_set_to_zero(x);
return;
}
@@ -360,12 +365,12 @@ v128_right_shift(v128_t *x, int index) {
}
void
-v128_left_shift(v128_t *x, int index) {
+v128_left_shift(v128_t *x, int shift) {
int i;
- const int base_index = index >> 5;
- const int bit_index = index & 31;
+ const int base_index = shift >> 5;
+ const int bit_index = shift & 31;
- if (index > 127) {
+ if (shift > 127) {
v128_set_to_zero(x);
return;
}
@@ -386,6 +391,124 @@ v128_left_shift(v128_t *x, int index) {
}
+/* functions manipulating bitvector_t */
+
+#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
+
+int
+bitvector_get_bit(const bitvector_t *v, int bit_index)
+{
+ return _bitvector_get_bit(v, bit_index);
+}
+
+void
+bitvector_set_bit(bitvector_t *v, int bit_index)
+{
+ _bitvector_set_bit(v, bit_index);
+}
+
+void
+bitvector_clear_bit(bitvector_t *v, int bit_index)
+{
+ _bitvector_clear_bit(v, bit_index);
+}
+
+
+#endif /* DATATYPES_USE_MACROS */
+
+int
+bitvector_alloc(bitvector_t *v, unsigned long length) {
+ unsigned long l;
+
+ /* Round length up to a multiple of bits_per_word */
+ length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
+
+ l = length / bits_per_word * bytes_per_word;
+
+ /* allocate memory, then set parameters */
+ if (l == 0)
+ v->word = NULL;
+ else {
+ v->word = (uint32_t*)crypto_alloc(l);
+ if (v->word == NULL) {
+ v->word = NULL;
+ v->length = 0;
+ return -1;
+ }
+ }
+ v->length = length;
+
+ /* initialize bitvector to zero */
+ bitvector_set_to_zero(v);
+
+ return 0;
+}
+
+
+void
+bitvector_dealloc(bitvector_t *v) {
+ if (v->word != NULL)
+ crypto_free(v->word);
+ v->word = NULL;
+ v->length = 0;
+}
+
+void
+bitvector_set_to_zero(bitvector_t *x)
+{
+ /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
+ memset(x->word, 0, x->length >> 3);
+}
+
+char *
+bitvector_bit_string(bitvector_t *x, char* buf, int len) {
+ int j, i;
+ uint32_t mask;
+
+ for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) {
+ for (mask=0x80000000; mask > 0; mask >>= 1) {
+ if (x->word[j] & mask)
+ buf[i] = '1';
+ else
+ buf[i] = '0';
+ ++i;
+ if (i >= len-1)
+ break;
+ }
+ }
+ buf[i] = 0; /* null terminate string */
+
+ return buf;
+}
+
+void
+bitvector_left_shift(bitvector_t *x, int shift) {
+ int i;
+ const int base_index = shift >> 5;
+ const int bit_index = shift & 31;
+ const int word_length = x->length >> 5;
+
+ if (shift >= (int)x->length) {
+ bitvector_set_to_zero(x);
+ return;
+ }
+
+ if (bit_index == 0) {
+ for (i=0; i < word_length - base_index; i++)
+ x->word[i] = x->word[i+base_index];
+ } else {
+ for (i=0; i < word_length - base_index - 1; i++)
+ x->word[i] = (x->word[i+base_index] >> bit_index) ^
+ (x->word[i+base_index+1] << (32 - bit_index));
+ x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index;
+ }
+
+ /* now wrap up the final portion */
+ for (i = word_length - base_index; i < word_length; i++)
+ x->word[i] = 0;
+
+}
+
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
@@ -406,194 +529,41 @@ octet_string_set_to_zero(uint8_t *s, int len) {
}
+#ifdef TESTAPP_SOURCE
-/*
- * From RFC 1521: The Base64 Alphabet
- *
- * Value Encoding Value Encoding Value Encoding Value Encoding
- * 0 A 17 R 34 i 51 z
- * 1 B 18 S 35 j 52 0
- * 2 C 19 T 36 k 53 1
- * 3 D 20 U 37 l 54 2
- * 4 E 21 V 38 m 55 3
- * 5 F 22 W 39 n 56 4
- * 6 G 23 X 40 o 57 5
- * 7 H 24 Y 41 p 58 6
- * 8 I 25 Z 42 q 59 7
- * 9 J 26 a 43 r 60 8
- * 10 K 27 b 44 s 61 9
- * 11 L 28 c 45 t 62 +
- * 12 M 29 d 46 u 63 /
- * 13 N 30 e 47 v
- * 14 O 31 f 48 w (pad) =
- * 15 P 32 g 49 x
- * 16 Q 33 h 50 y
- */
+static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789+/";
-int
-base64_char_to_sextet(uint8_t c) {
- switch(c) {
- case 'A':
- return 0;
- case 'B':
- return 1;
- case 'C':
- return 2;
- case 'D':
- return 3;
- case 'E':
- return 4;
- case 'F':
- return 5;
- case 'G':
- return 6;
- case 'H':
- return 7;
- case 'I':
- return 8;
- case 'J':
- return 9;
- case 'K':
- return 10;
- case 'L':
- return 11;
- case 'M':
- return 12;
- case 'N':
- return 13;
- case 'O':
- return 14;
- case 'P':
- return 15;
- case 'Q':
- return 16;
- case 'R':
- return 17;
- case 'S':
- return 18;
- case 'T':
- return 19;
- case 'U':
- return 20;
- case 'V':
- return 21;
- case 'W':
- return 22;
- case 'X':
- return 23;
- case 'Y':
- return 24;
- case 'Z':
- return 25;
- case 'a':
- return 26;
- case 'b':
- return 27;
- case 'c':
- return 28;
- case 'd':
- return 29;
- case 'e':
- return 30;
- case 'f':
- return 31;
- case 'g':
- return 32;
- case 'h':
- return 33;
- case 'i':
- return 34;
- case 'j':
- return 35;
- case 'k':
- return 36;
- case 'l':
- return 37;
- case 'm':
- return 38;
- case 'n':
- return 39;
- case 'o':
- return 40;
- case 'p':
- return 41;
- case 'q':
- return 42;
- case 'r':
- return 43;
- case 's':
- return 44;
- case 't':
- return 45;
- case 'u':
- return 46;
- case 'v':
- return 47;
- case 'w':
- return 48;
- case 'x':
- return 49;
- case 'y':
- return 50;
- case 'z':
- return 51;
- case '0':
- return 52;
- case '1':
- return 53;
- case '2':
- return 54;
- case '3':
- return 55;
- case '4':
- return 56;
- case '5':
- return 57;
- case '6':
- return 58;
- case '7':
- return 59;
- case '8':
- return 60;
- case '9':
- return 61;
- case '+':
- return 62;
- case '/':
- return 63;
- case '=':
- return 64;
- default:
- break;
- }
- return -1;
-}
+static int base64_block_to_octet_triple(char *out, char *in) {
+ unsigned char sextets[4] = {0};
+ int j = 0;
+ int i;
-/*
- * base64_string_to_octet_string converts a hexadecimal string
- * of length 2 * len to a raw octet string of length len
- */
+ for (i = 0; i < 4; i++) {
+ char *p = strchr(b64chars, in[i]);
+ if (p != NULL) sextets[i] = p - b64chars;
+ else j++;
+ }
-int
-base64_string_to_octet_string(char *raw, char *base64, int len) {
- uint8_t x;
- int tmp;
- int base64_len;
+ out[0] = (sextets[0]<<2)|(sextets[1]>>4);
+ if (j < 2) out[1] = (sextets[1]<<4)|(sextets[2]>>2);
+ if (j < 1) out[2] = (sextets[2]<<6)|sextets[3];
+ return j;
+}
- base64_len = 0;
- while (base64_len < len) {
- tmp = base64_char_to_sextet(base64[0]);
- if (tmp == -1)
- return base64_len;
- x = (tmp << 6);
- base64_len++;
- tmp = base64_char_to_sextet(base64[1]);
- if (tmp == -1)
- return base64_len;
- x |= (tmp & 0xffff);
- base64_len++;
- *raw++ = x;
- base64 += 2;
+int base64_string_to_octet_string(char *out, int *pad, char *in, int len) {
+ int k = 0;
+ int i = 0;
+ int j = 0;
+ if (len % 4 != 0) return 0;
+
+ while (i < len && j == 0) {
+ j = base64_block_to_octet_triple(out + k, in + i);
+ k += 3;
+ i += 4;
}
- return base64_len;
+ *pad = j;
+ return i;
}
+
+#endif
diff --git a/third_party/srtp/crypto/math/gf2_8.c b/third_party/srtp/crypto/math/gf2_8.c
index 8a112ba7..c57f8d23 100644
--- a/third_party/srtp/crypto/math/gf2_8.c
+++ b/third_party/srtp/crypto/math/gf2_8.c
@@ -45,12 +45,16 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "datatypes.h"
#include "gf2_8.h"
/* gf2_8_shift() moved to gf2_8.h as an inline function */
-inline gf2_8
+gf2_8
gf2_8_multiply(gf2_8 x, gf2_8 y) {
gf2_8 z = 0;
diff --git a/third_party/srtp/crypto/math/math.c b/third_party/srtp/crypto/math/math.c
index 3e619979..7f0bcd2b 100644
--- a/third_party/srtp/crypto/math/math.c
+++ b/third_party/srtp/crypto/math/math.c
@@ -42,8 +42,11 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "crypto_math.h"
-#include <stdlib.h> /* malloc() used in bitvector_alloc */
int
octet_weight[256] = {
@@ -173,7 +176,7 @@ v32_weight(v32_t a) {
return wt;
}
-inline unsigned char
+unsigned char
v32_distance(v32_t x, v32_t y) {
x.value ^= y.value;
return v32_weight(x);
@@ -524,13 +527,13 @@ A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
return b;
}
-inline void
+void
v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
x->v8[0] = s[0];
x->v8[1] = s[1];
}
-inline void
+void
v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
x->v8[0] = s[0];
x->v8[1] = s[1];
@@ -538,7 +541,7 @@ v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
x->v8[3] = s[3];
}
-inline void
+void
v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
x->v8[0] = s[0];
x->v8[1] = s[1];
@@ -632,7 +635,7 @@ v128_set_bit_to(v128_t *x, int i, int y){
#endif /* DATATYPES_USE_MACROS */
-inline void
+static inline void
v128_left_shift2(v128_t *x, int num_bits) {
int i;
int word_shift = num_bits >> 5;
@@ -773,165 +776,6 @@ octet_string_set_to_zero(uint8_t *s, int len) {
}
-/* functions manipulating bit_vector_t */
-
-#define BITVECTOR_MAX_WORDS 5
-
-int
-bitvector_alloc(bitvector_t *v, unsigned long length) {
- unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;
- int i;
-
- /* allocate memory, then set parameters */
- if (l > BITVECTOR_MAX_WORDS)
- return -1;
- else
- l = BITVECTOR_MAX_WORDS;
- v->word = malloc(l);
- if (v->word == NULL)
- return -1;
- v->length = length;
-
- /* initialize bitvector to zero */
- for (i=0; i < (length >> 5); i++) {
- v->word = 0;
- }
-
- return 0;
-}
-
-void
-bitvector_set_bit(bitvector_t *v, int bit_index) {
-
- v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));
-
-}
-
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index) {
-
- return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;
-
-}
-
-#include <stdio.h>
-
-int
-bitvector_print_hex(const bitvector_t *v, FILE *stream) {
- int i;
- int m = v->length >> 5;
- int n = v->length & 31;
- char string[9];
- uint32_t tmp;
-
- /* if length isn't a multiple of four, we can't hex_print */
- if (n & 3)
- return -1;
-
- /* if the length is zero, do nothing */
- if (v->length == 0)
- return 0;
-
- /*
- * loop over words from most significant to least significant -
- */
-
- for (i=m; i > 0; i++) {
- char *str = string + 7;
- tmp = v->word[i];
-
- /* null terminate string */
- string[8] = 0;
-
- /* loop over nibbles */
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
- *str-- = nibble_to_hex_char(tmp & 0xf);
-
- /* now print stream */
- fprintf(stream, string);
- }
-
- return 0;
-
-}
-
-
-int
-hex_string_length(char *s) {
- int count = 0;
-
- /* ignore leading zeros */
- while ((*s != 0) && *s == '0')
- s++;
-
- /* count remaining characters */
- while (*s != 0) {
- if (hex_char_to_nibble(*s++) == -1)
- return -1;
- count++;
- }
-
- return count;
-}
-
-int
-bitvector_set_from_hex(bitvector_t *v, char *string) {
- int num_hex_chars, m, n, i, j;
- uint32_t tmp;
-
- num_hex_chars = hex_string_length(string);
- if (num_hex_chars == -1)
- return -1;
-
- /* set length */
- v->length = num_hex_chars * 4;
- /*
- * at this point, we should subtract away a bit if the high
- * bit of the first character is zero, but we ignore that
- * for now and assume that we're four-bit aligned - DAM
- */
-
-
- m = num_hex_chars / 8; /* number of words */
- n = num_hex_chars % 8; /* number of nibbles in last word */
-
- /* if the length is greater than the bitvector, return an error */
- if (m > BITVECTOR_MAX_WORDS)
- return -1;
-
- /*
- * loop over words from most significant - first word is a special
- * case
- */
-
- if (n) {
- tmp = 0;
- for (i=0; i < n; i++) {
- tmp = hex_char_to_nibble(*string++);
- tmp <<= 4;
- }
- v->word[m] = tmp;
- }
-
- /* now loop over the rest of the words */
- for (i=m-1; i >= 0; i--) {
- tmp = 0;
- for (j=0; j < 8; j++) {
- tmp = hex_char_to_nibble(*string++);
- tmp <<= 4;
- }
- v->word[i] = tmp;
- }
-
- return 0;
-}
-
/* functions below not yet tested! */
diff --git a/third_party/srtp/crypto/math/stat.c b/third_party/srtp/crypto/math/stat.c
index 5e46c209..aaff3c4f 100644
--- a/third_party/srtp/crypto/math/stat.c
+++ b/third_party/srtp/crypto/math/stat.c
@@ -7,6 +7,46 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "stat.h"
debug_module_t mod_stat = {
diff --git a/third_party/srtp/crypto/replay/rdb.c b/third_party/srtp/crypto/replay/rdb.c
index c826912a..c84222fd 100644
--- a/third_party/srtp/crypto/replay/rdb.c
+++ b/third_party/srtp/crypto/replay/rdb.c
@@ -44,6 +44,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "rdb.h"
@@ -70,18 +74,18 @@ rdb_init(rdb_t *rdb) {
*/
err_status_t
-rdb_check(const rdb_t *rdb, uint32_t index) {
+rdb_check(const rdb_t *rdb, uint32_t p_index) {
/* if the index appears after (or at very end of) the window, its good */
- if (index >= rdb->window_start + rdb_bits_in_bitmask)
+ if (p_index >= rdb->window_start + rdb_bits_in_bitmask)
return err_status_ok;
/* if the index appears before the window, its bad */
- if (index < rdb->window_start)
+ if (p_index < rdb->window_start)
return err_status_replay_old;
/* otherwise, the index appears within the window, so check the bitmask */
- if (v128_get_bit(&rdb->bitmask, (index - rdb->window_start)) == 1)
+ if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1)
return err_status_replay_fail;
/* otherwise, the index is okay */
@@ -98,15 +102,15 @@ rdb_check(const rdb_t *rdb, uint32_t index) {
*/
err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t index) {
+rdb_add_index(rdb_t *rdb, uint32_t p_index) {
int delta;
- /* here we *assume* that index > rdb->window_start */
+ /* here we *assume* that p_index > rdb->window_start */
- delta = (index - rdb->window_start);
+ delta = (p_index - rdb->window_start);
if (delta < rdb_bits_in_bitmask) {
- /* if the index is within the window, set the appropriate bit */
+ /* if the p_index is within the window, set the appropriate bit */
v128_set_bit(&rdb->bitmask, delta);
} else {
diff --git a/third_party/srtp/crypto/replay/rdbx.c b/third_party/srtp/crypto/replay/rdbx.c
index 12e4e8f8..153676f3 100644
--- a/third_party/srtp/crypto/replay/rdbx.c
+++ b/third_party/srtp/crypto/replay/rdbx.c
@@ -43,20 +43,23 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "rdbx.h"
-#define rdbx_high_bit_in_bitmask 127
/*
- * from draft-ietf-avt-srtp-00.txt:
+ * from RFC 3711:
*
* A receiver reconstructs the index i of a packet with sequence
- * number s using the estimate
+ * number SEQ using the estimate
*
- * i = 65,536 * t + s,
+ * i = 2^16 * v + SEQ,
*
- * where t is chosen from the set { r-1, r, r+1 } such that i is
- * closest to the value 65,536 * r + s_l. If the value r+1 is used,
+ * where v is chosen from the set { ROC-1, ROC, ROC+1 } such that i is
+ * closest to the value 2^16 * ROC + s_l. If the value r+1 is used,
* then the rollover counter r in the cryptographic context is
* incremented by one (if the packet containing s is authentic).
*/
@@ -146,18 +149,18 @@ index_guess(const xtd_seq_num_t *local,
if (local_seq < seq_num_median) {
if (s - local_seq > seq_num_median) {
guess_roc = local_roc - 1;
- difference = seq_num_max - s + local_seq;
+ difference = s - local_seq - seq_num_max;
} else {
guess_roc = local_roc;
difference = s - local_seq;
}
} else {
if (local_seq - seq_num_median > s) {
- guess_roc = local_roc+1;
- difference = seq_num_max - local_seq + s;
+ guess_roc = local_roc + 1;
+ difference = s - local_seq + seq_num_max;
} else {
- difference = s - local_seq;
guess_roc = local_roc;
+ difference = s - local_seq;
}
}
guess_seq = s;
@@ -180,17 +183,81 @@ index_guess(const xtd_seq_num_t *local,
/*
- * rdbx_init(&r) initalizes the rdbx_t pointed to by r
+ * rdbx_init(&r, ws) initializes the rdbx_t pointed to by r with window size ws
*/
err_status_t
-rdbx_init(rdbx_t *rdbx) {
- v128_set_to_zero(&rdbx->bitmask);
+rdbx_init(rdbx_t *rdbx, unsigned long ws) {
+ if (ws == 0)
+ return err_status_bad_param;
+
+ if (bitvector_alloc(&rdbx->bitmask, ws) != 0)
+ return err_status_alloc_fail;
+
index_init(&rdbx->index);
return err_status_ok;
}
+/*
+ * rdbx_dealloc(&r) frees memory for the rdbx_t pointed to by r
+ */
+
+err_status_t
+rdbx_dealloc(rdbx_t *rdbx) {
+ bitvector_dealloc(&rdbx->bitmask);
+
+ return err_status_ok;
+}
+
+/*
+ * rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx
+ * to have the rollover counter value roc. If that value is less than
+ * the current rollover counter value, then the function returns
+ * err_status_replay_old; otherwise, err_status_ok is returned.
+ *
+ */
+
+err_status_t
+rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) {
+ bitvector_set_to_zero(&rdbx->bitmask);
+
+#ifdef NO_64BIT_MATH
+ #error not yet implemented
+#else
+
+ /* make sure that we're not moving backwards */
+ if (roc < (rdbx->index >> 16))
+ return err_status_replay_old;
+
+ rdbx->index &= 0xffff; /* retain lowest 16 bits */
+ rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
+#endif
+
+ return err_status_ok;
+}
+
+/*
+ * rdbx_get_packet_index(rdbx) returns the value of the packet index
+ * for the rdbx_t pointed to by rdbx
+ *
+ */
+
+xtd_seq_num_t
+rdbx_get_packet_index(const rdbx_t *rdbx) {
+ return rdbx->index;
+}
+
+/*
+ * rdbx_get_window_size(rdbx) returns the value of the window size
+ * for the rdbx_t pointed to by rdbx
+ *
+ */
+
+unsigned long
+rdbx_get_window_size(const rdbx_t *rdbx) {
+ return bitvector_get_length(&rdbx->bitmask);
+}
/*
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
@@ -202,11 +269,11 @@ rdbx_check(const rdbx_t *rdbx, int delta) {
if (delta > 0) { /* if delta is positive, it's good */
return err_status_ok;
- } else if (rdbx_high_bit_in_bitmask + delta < 0) {
+ } else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
/* if delta is lower than the bitmask, it's bad */
return err_status_replay_old;
- } else if (v128_get_bit(&rdbx->bitmask,
- rdbx_high_bit_in_bitmask + delta) == 1) {
+ } else if (bitvector_get_bit(&rdbx->bitmask,
+ (int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
/* delta is within the window, so check the bitmask */
return err_status_replay_fail;
}
@@ -230,11 +297,11 @@ rdbx_add_index(rdbx_t *rdbx, int delta) {
if (delta > 0) {
/* shift forward by delta */
index_advance(&rdbx->index, delta);
- v128_left_shift(&rdbx->bitmask, delta);
- v128_set_bit(&rdbx->bitmask, 127);
+ bitvector_left_shift(&rdbx->bitmask, delta);
+ bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
} else {
- /* delta is in window, so flip bit in bitmask */
- v128_set_bit(&rdbx->bitmask, -delta);
+ /* delta is in window */
+ bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
}
/* note that we need not consider the case that delta == 0 */
diff --git a/third_party/srtp/crypto/replay/ut_sim.c b/third_party/srtp/crypto/replay/ut_sim.c
index 43c411e4..5a1c37c7 100644
--- a/third_party/srtp/crypto/replay/ut_sim.c
+++ b/third_party/srtp/crypto/replay/ut_sim.c
@@ -45,6 +45,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "ut_sim.h"
diff --git a/third_party/srtp/crypto/rng/ctr_prng.c b/third_party/srtp/crypto/rng/ctr_prng.c
index ab76df36..e24b0aba 100644
--- a/third_party/srtp/crypto/rng/ctr_prng.c
+++ b/third_party/srtp/crypto/rng/ctr_prng.c
@@ -43,6 +43,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "prng.h"
/* single, global prng structure */
@@ -66,7 +70,11 @@ ctr_prng_init(rand_source_func_t random_source) {
return status;
/* initialize aes ctr context with random key */
- status = aes_icm_context_init(&ctr_prng.state, tmp_key);
+#ifdef OPENSSL
+ status = aes_icm_openssl_context_init(&ctr_prng.state, tmp_key, 30);
+#else
+ status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30);
+#endif
if (status)
return status;
@@ -79,10 +87,8 @@ ctr_prng_get_octet_string(void *dest, uint32_t len) {
/*
* if we need to re-initialize the prng, do so now
- *
- * avoid 32-bit overflows by subtracting instead of adding
*/
- if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
+ if ((aes_icm_bytes_encrypted(&ctr_prng.state) + len) > 0xffff) {
status = ctr_prng_init(ctr_prng.rand);
if (status)
return status;
diff --git a/third_party/srtp/crypto/rng/prng.c b/third_party/srtp/crypto/rng/prng.c
index 69350a48..208e2680 100644
--- a/third_party/srtp/crypto/rng/prng.c
+++ b/third_party/srtp/crypto/rng/prng.c
@@ -43,6 +43,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "prng.h"
/* single, global prng structure */
@@ -51,7 +55,7 @@ x917_prng_t x917_prng;
err_status_t
x917_prng_init(rand_source_func_t random_source) {
- v128_t tmp_key;
+ uint8_t tmp_key[16];
err_status_t status;
/* initialize output count to zero */
@@ -61,12 +65,12 @@ x917_prng_init(rand_source_func_t random_source) {
x917_prng.rand = random_source;
/* initialize secret key from random source */
- status = random_source((uint8_t *)&tmp_key, 16);
+ status = random_source(tmp_key, 16);
if (status)
return status;
/* expand aes key */
- aes_expand_encryption_key(&tmp_key, x917_prng.key);
+ aes_expand_encryption_key(tmp_key, 16, &x917_prng.key);
/* initialize prng state from random source */
status = x917_prng.rand((uint8_t *)&x917_prng.state, 16);
@@ -108,7 +112,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
v128_copy(&buffer, &x917_prng.state);
/* apply aes to buffer */
- aes_encrypt(&buffer, x917_prng.key);
+ aes_encrypt(&buffer, &x917_prng.key);
/* write data to output */
*dest++ = buffer.v8[0];
@@ -132,7 +136,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
buffer.v32[0] ^= t;
/* encrypt buffer */
- aes_encrypt(&buffer, x917_prng.key);
+ aes_encrypt(&buffer, &x917_prng.key);
/* copy buffer into state */
v128_copy(&x917_prng.state, &buffer);
@@ -150,7 +154,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
v128_copy(&buffer, &x917_prng.state);
/* apply aes to buffer */
- aes_encrypt(&buffer, x917_prng.key);
+ aes_encrypt(&buffer, &x917_prng.key);
/* write data to output */
for (i=0; i < tail_len; i++) {
@@ -163,7 +167,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
buffer.v32[0] ^= t;
/* encrypt buffer */
- aes_encrypt(&buffer, x917_prng.key);
+ aes_encrypt(&buffer, &x917_prng.key);
/* copy buffer into state */
v128_copy(&x917_prng.state, &buffer);
diff --git a/third_party/srtp/crypto/rng/rand_source.c b/third_party/srtp/crypto/rng/rand_source.c
index 3d01d25a..1eb6fbb0 100644
--- a/third_party/srtp/crypto/rng/rand_source.c
+++ b/third_party/srtp/crypto/rng/rand_source.c
@@ -42,15 +42,14 @@
*
*/
-#include "srtp_config.h"
+#include "config.h"
-#if defined(DEV_URANDOM) || defined(PJ_DEV_URANDOM)
+#ifdef DEV_URANDOM
# include <fcntl.h> /* for open() */
# include <unistd.h> /* for close() */
-#elif (_MSC_VER >= 1400)
-#define _CRT_RAND_S
+#elif defined(HAVE_RAND_S)
+# define _CRT_RAND_S
# include <stdlib.h>
-# include <stdio.h>
#else
# include <stdio.h>
#endif
@@ -87,18 +86,11 @@ rand_source_init(void) {
dev_random_fdes = open(DEV_URANDOM, O_RDONLY);
if (dev_random_fdes < 0)
return err_status_init_fail;
-#elif defined(PJ_DEV_URANDOM)
- /* open random source for reading */
- dev_random_fdes = open(PJ_DEV_URANDOM, O_RDONLY);
- if (dev_random_fdes < 0) {
- err_report(3,"Ugh: /dev/urandom not present, using rand() instead");
- return err_status_ok; /* it's ok, it'll fallback to using rand() */
- }
-#elif (_MSC_VER >= 1400)
+#elif defined(HAVE_RAND_S)
dev_random_fdes = RAND_SOURCE_READY;
#else
- /* no random source available; let the user know */
- err_report(err_level_info, "WARNING: no real random source present!\n");
+ /* no random source available; let the user know */
+ fprintf(stderr, "WARNING: no real random source present!\n");
dev_random_fdes = RAND_SOURCE_READY;
#endif
return err_status_ok;
@@ -113,35 +105,32 @@ rand_source_get_octet_string(void *dest, uint32_t len) {
* written
*/
#ifdef DEV_URANDOM
- if (read(dev_random_fdes, dest, len) != len)
- return err_status_fail;
-#elif 0 && (_MSC_VER >= 1400) /* disabled rand_s, causing assertion 'rand_s not supported' in vs8 */
- unsigned int *dst = dest;
+ uint8_t *dst = (uint8_t *)dest;
while (len)
{
- unsigned int val = 0;
- errno_t err = rand_s(&val);
- if (err != 0)
- {
- return err_status_fail;
- }
-
- *dst++ = val;
- len--;
+ ssize_t num_read = read(dev_random_fdes, dst, len);
+ if (num_read <= 0 || num_read > len)
+ return err_status_fail;
+ len -= num_read;
+ dst += num_read;
}
-#else
+#elif defined(HAVE_RAND_S)
uint8_t *dst = (uint8_t *)dest;
-
-#ifdef PJ_DEV_URANDOM
- /* First try with /dev/urandom, if it's opened */
- if (dev_random_fdes >= 0) {
- if (read(dev_random_fdes, dest, len) == len)
- return err_status_ok; /* success */
- }
-#endif
+ while (len)
+ {
+ unsigned int val;
+ errno_t err = rand_s(&val);
+ if (err != 0)
+ return err_status_fail;
+
+ *dst++ = val & 0xff;
+ len--;
+ }
+#else
/* Generic C-library (rand()) version */
/* This is a random source of last resort */
+ uint8_t *dst = (uint8_t *)dest;
while (len)
{
int val = rand();
@@ -157,19 +146,13 @@ rand_source_get_octet_string(void *dest, uint32_t len) {
err_status_t
rand_source_deinit(void) {
-#ifndef PJ_DEV_URANDOM
if (dev_random_fdes < 0)
return err_status_dealloc_fail; /* well, we haven't really failed, *
* but there is something wrong */
+#ifdef DEV_URANDOM
+ close(dev_random_fdes);
#endif
-
-#if defined(DEV_URANDOM) || defined(PJ_DEV_URANDOM)
- if (dev_random_fdes >= 0)
- close(dev_random_fdes);
-
- dev_random_fdes = RAND_SOURCE_NOT_READY;
-#endif
+ dev_random_fdes = RAND_SOURCE_NOT_READY;
return err_status_ok;
}
-
diff --git a/third_party/srtp/crypto/rng/rand_source_ossl.c b/third_party/srtp/crypto/rng/rand_source_ossl.c
new file mode 100644
index 00000000..4bca6ac8
--- /dev/null
+++ b/third_party/srtp/crypto/rng/rand_source_ossl.c
@@ -0,0 +1,70 @@
+/*
+ * rand_source_ossl.c
+ *
+ * implements a random source based on OpenSSL RAND_bytes()
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright(c) 2013, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:crypto/test/aes_calc.c
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "rand_source.h"
+#include <openssl/rand.h>
+
+
+err_status_t rand_source_init (void)
+{
+ return err_status_ok;
+}
+
+err_status_t rand_source_get_octet_string (void *dest, uint32_t len)
+{
+ if (RAND_bytes(dest, len) == 1) {
+ return err_status_ok;
+ } else {
+ return err_status_fail;
+ }
+}
+
+err_status_t rand_source_deinit (void)
+{
+ return err_status_ok;
+}
diff --git a/third_party/srtp/crypto/test/aes_calc.c b/third_party/srtp/crypto/test/aes_calc.c
index 2fac07ae..b40e3726 100644
--- a/third_party/srtp/crypto/test/aes_calc.c
+++ b/third_party/srtp/crypto/test/aes_calc.c
@@ -8,6 +8,42 @@
*/
/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
Example usage (with first NIST FIPS 197 test case):
@@ -18,6 +54,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include "aes.h"
#include <stdio.h>
#include <string.h>
@@ -28,14 +68,16 @@ usage(char *prog_name) {
exit(255);
}
-#define AES_KEY_LEN 16
+#define AES_MAX_KEY_LEN 32
int
main (int argc, char *argv[]) {
- v128_t data, key;
+ v128_t data;
+ uint8_t key[AES_MAX_KEY_LEN];
aes_expanded_key_t exp_key;
- int len;
- int verbose;
+ int key_len, len;
+ int verbose = 0;
+ err_status_t status;
if (argc == 3) {
/* we're not in verbose mode */
@@ -54,22 +96,23 @@ main (int argc, char *argv[]) {
}
/* read in key, checking length */
- if (strlen(argv[1]) > AES_KEY_LEN*2) {
+ if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) {
fprintf(stderr,
"error: too many digits in key "
- "(should be %d hexadecimal digits, found %u)\n",
- AES_KEY_LEN*2, (unsigned)strlen(argv[1]));
+ "(should be at most %d hexadecimal digits, found %u)\n",
+ AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1]));
exit(1);
}
- len = hex_string_to_octet_string((char *)&key, argv[1], AES_KEY_LEN*2);
+ len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2);
/* check that hex string is the right length */
- if (len < AES_KEY_LEN*2) {
+ if (len != 32 && len != 48 && len != 64) {
fprintf(stderr,
- "error: too few digits in key "
- "(should be %d hexadecimal digits, found %d)\n",
- AES_KEY_LEN*2, len);
+ "error: bad number of digits in key "
+ "(should be 32/48/64 hexadecimal digits, found %d)\n",
+ len);
exit(1);
}
+ key_len = len/2;
/* read in plaintext, checking length */
if (strlen(argv[2]) > 16*2) {
@@ -95,13 +138,18 @@ main (int argc, char *argv[]) {
}
/* encrypt plaintext */
- aes_expand_encryption_key(&key, exp_key);
+ status = aes_expand_encryption_key(key, key_len, &exp_key);
+ if (status) {
+ fprintf(stderr,
+ "error: AES key expansion failed.\n");
+ exit(1);
+ }
- aes_encrypt(&data, exp_key);
+ aes_encrypt(&data, &exp_key);
/* write ciphertext to output */
if (verbose) {
- printf("key:\t\t%s\n", v128_hex_string(&key));
+ printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
printf("ciphertext:\t");
}
printf("%s\n", v128_hex_string(&data));
diff --git a/third_party/srtp/crypto/test/cipher_driver.c b/third_party/srtp/crypto/test/cipher_driver.c
index 25ca90af..9c9c2203 100644
--- a/third_party/srtp/crypto/test/cipher_driver.c
+++ b/third_party/srtp/crypto/test/cipher_driver.c
@@ -9,7 +9,7 @@
/*
*
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,12 +43,21 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */
#include <string.h> /* for memset() */
-#include <unistd.h> /* for getopt() */
+#include "getopt_s.h"
#include "cipher.h"
+#ifdef OPENSSL
+#include "aes_icm_ossl.h"
+#include "aes_gcm_ossl.h"
+#else
#include "aes_icm.h"
+#endif
#include "null_cipher.h"
#define PRINT_DEBUG 0
@@ -114,16 +123,28 @@ check_status(err_status_t s) {
extern cipher_type_t null_cipher;
extern cipher_type_t aes_icm;
+#ifndef OPENSSL
extern cipher_type_t aes_cbc;
+#else
+#ifndef SRTP_NO_AES192
+extern cipher_type_t aes_icm_192;
+#endif
+extern cipher_type_t aes_icm_256;
+extern cipher_type_t aes_gcm_128_openssl;
+extern cipher_type_t aes_gcm_256_openssl;
+#endif
int
main(int argc, char *argv[]) {
cipher_t *c = NULL;
err_status_t status;
- unsigned char test_key[20] = {
+ unsigned char test_key[48] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
};
int q;
unsigned do_timing_test = 0;
@@ -132,7 +153,7 @@ main(int argc, char *argv[]) {
/* process input arguments */
while (1) {
- q = getopt(argc, argv, "tva");
+ q = getopt_s(argc, argv, "tva");
if (q == -1)
break;
switch (q) {
@@ -168,22 +189,53 @@ main(int argc, char *argv[]) {
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher);
+#ifndef OPENSSL
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
+ cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher);
+
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher);
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
+ cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher);
+#else
+#ifndef SRTP_NO_AES192
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
+ cipher_driver_test_array_throughput(&aes_icm_192, 38, num_cipher);
+#endif
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
+ cipher_driver_test_array_throughput(&aes_icm_256, 46, num_cipher);
+
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) {
+ cipher_driver_test_array_throughput(&aes_gcm_128_openssl, AES_128_GCM_KEYSIZE_WSALT, num_cipher);
+ }
+
+ for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) {
+ cipher_driver_test_array_throughput(&aes_gcm_256_openssl, AES_256_GCM_KEYSIZE_WSALT, num_cipher);
+ }
+#endif
}
if (do_validation) {
cipher_driver_self_test(&null_cipher);
cipher_driver_self_test(&aes_icm);
+#ifndef OPENSSL
cipher_driver_self_test(&aes_cbc);
+#else
+#ifndef SRTP_NO_AES192
+ cipher_driver_self_test(&aes_icm_192);
+#endif
+ cipher_driver_self_test(&aes_icm_256);
+ cipher_driver_self_test(&aes_gcm_128_openssl);
+ cipher_driver_self_test(&aes_gcm_256_openssl);
+#endif
}
/* do timing and/or buffer_test on null_cipher */
- status = cipher_type_alloc(&null_cipher, &c, 0);
+ status = cipher_type_alloc(&null_cipher, &c, 0, 0);
check_status(status);
- status = cipher_init(c, NULL, direction_encrypt);
+ status = cipher_init(c, NULL);
check_status(status);
if (do_timing_test)
@@ -196,14 +248,14 @@ main(int argc, char *argv[]) {
check_status(status);
- /* run the throughput test on the aes_icm cipher */
- status = cipher_type_alloc(&aes_icm, &c, 30);
+ /* run the throughput test on the aes_icm cipher (128-bit key) */
+ status = cipher_type_alloc(&aes_icm, &c, 30, 0);
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
}
- status = cipher_init(c, test_key, direction_encrypt);
+ status = cipher_init(c, test_key);
check_status(status);
if (do_timing_test)
@@ -216,8 +268,73 @@ main(int argc, char *argv[]) {
status = cipher_dealloc(c);
check_status(status);
-
- return 0;
+
+ /* repeat the tests with 256-bit keys */
+#ifndef OPENSSL
+ status = cipher_type_alloc(&aes_icm, &c, 46, 0);
+#else
+ status = cipher_type_alloc(&aes_icm_256, &c, 46, 0);
+#endif
+ if (status) {
+ fprintf(stderr, "error: can't allocate cipher\n");
+ exit(status);
+ }
+
+ status = cipher_init(c, test_key);
+ check_status(status);
+
+ if (do_timing_test)
+ cipher_driver_test_throughput(c);
+
+ if (do_validation) {
+ status = cipher_driver_test_buffering(c);
+ check_status(status);
+ }
+
+ status = cipher_dealloc(c);
+ check_status(status);
+
+#ifdef OPENSSL
+ /* run the throughput test on the aes_gcm_128_openssl cipher */
+ status = cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8);
+ if (status) {
+ fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
+ exit(status);
+ }
+ status = cipher_init(c, test_key);
+ check_status(status);
+ if (do_timing_test) {
+ cipher_driver_test_throughput(c);
+ }
+
+ if (do_validation) {
+ status = cipher_driver_test_buffering(c);
+ check_status(status);
+ }
+ status = cipher_dealloc(c);
+ check_status(status);
+
+ /* run the throughput test on the aes_gcm_256_openssl cipher */
+ status = cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16);
+ if (status) {
+ fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
+ exit(status);
+ }
+ status = cipher_init(c, test_key);
+ check_status(status);
+ if (do_timing_test) {
+ cipher_driver_test_throughput(c);
+ }
+
+ if (do_validation) {
+ status = cipher_driver_test_buffering(c);
+ check_status(status);
+ }
+ status = cipher_dealloc(c);
+ check_status(status);
+#endif
+
+ return 0;
}
void
@@ -225,9 +342,9 @@ cipher_driver_test_throughput(cipher_t *c) {
int i;
int min_enc_len = 32;
int max_enc_len = 2048; /* should be a power of two */
- int num_trials = 100000;
+ int num_trials = 1000000;
- printf("timing %s throughput:\n", c->type->description);
+ printf("timing %s throughput, key length %d:\n", c->type->description, c->key_len);
fflush(stdout);
for (i=min_enc_len; i <= max_enc_len; i = i * 2)
printf("msg len: %d\tgigabits per second: %f\n",
@@ -256,11 +373,12 @@ cipher_driver_self_test(cipher_type_t *ct) {
* calls
*/
+#define INITIAL_BUFLEN 1024
err_status_t
cipher_driver_test_buffering(cipher_t *c) {
int i, j, num_trials = 1000;
- unsigned len, buflen = 1024;
- uint8_t buffer0[buflen], buffer1[buflen], *current, *end;
+ unsigned len, buflen = INITIAL_BUFLEN;
+ uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
uint8_t idx[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34
@@ -273,11 +391,12 @@ cipher_driver_test_buffering(cipher_t *c) {
for (i=0; i < num_trials; i++) {
/* set buffers to zero */
- for (j=0; j < buflen; j++)
+ for (j=0; j < (int) buflen; j++) {
buffer0[j] = buffer1[j] = 0;
+ }
/* initialize cipher */
- status = cipher_set_iv(c, idx);
+ status = cipher_set_iv(c, idx, direction_encrypt);
if (status)
return status;
@@ -287,7 +406,7 @@ cipher_driver_test_buffering(cipher_t *c) {
return status;
/* re-initialize cipher */
- status = cipher_set_iv(c, idx);
+ status = cipher_set_iv(c, idx, direction_encrypt);
if (status)
return status;
@@ -316,7 +435,7 @@ cipher_driver_test_buffering(cipher_t *c) {
}
/* compare buffers */
- for (j=0; j < buflen; j++)
+ for (j=0; j < (int) buflen; j++) {
if (buffer0[j] != buffer1[j]) {
#if PRINT_DEBUG
printf("test case %d failed at byte %d\n", i, j);
@@ -325,6 +444,7 @@ cipher_driver_test_buffering(cipher_t *c) {
#endif
return err_status_algo_fail;
}
+ }
}
printf("passed\n");
@@ -348,6 +468,9 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
err_status_t status;
uint8_t *key;
cipher_t **cipher_array;
+ /* pad klen allocation, to handle aes_icm reading 16 bytes for the
+ 14-byte salt */
+ int klen_pad = ((klen + 15) >> 4) << 4;
/* allocate array of pointers to ciphers */
cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers);
@@ -358,7 +481,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
*ca = cipher_array;
/* allocate key */
- key = crypto_alloc(klen);
+ key = crypto_alloc(klen_pad);
if (key == NULL) {
free(cipher_array);
return err_status_alloc_fail;
@@ -368,14 +491,16 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
for (i=0; i < num_ciphers; i++) {
/* allocate cipher */
- status = cipher_type_alloc(ctype, cipher_array, klen);
+ status = cipher_type_alloc(ctype, cipher_array, klen, 16);
if (status)
return status;
/* generate random key and initialize cipher */
for (j=0; j < klen; j++)
key[j] = (uint8_t) rand();
- status = cipher_init(*cipher_array, key, direction_encrypt);
+ for (; j < klen_pad; j++)
+ key[j] = 0;
+ status = cipher_init(*cipher_array, key);
if (status)
return status;
@@ -387,6 +512,8 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
cipher_array++;
}
+ crypto_free(key);
+
return err_status_ok;
}
@@ -423,24 +550,28 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
v128_t nonce;
clock_t timer;
unsigned char *enc_buf;
- int cipher_index = 0;
+ int cipher_index = rand() % num_cipher;
-
- enc_buf = crypto_alloc(octets_in_buffer);
+ /* Over-alloc, for NIST CBC padding */
+ enc_buf = crypto_alloc(octets_in_buffer+17);
if (enc_buf == NULL)
return 0; /* indicate bad parameters by returning null */
+ memset(enc_buf, 0, octets_in_buffer);
/* time repeated trials */
v128_set_to_zero(&nonce);
timer = clock();
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
+ /* length parameter to cipher_encrypt is in/out -- out is total, padded
+ * length -- so reset it each time. */
+ unsigned octets_to_encrypt = octets_in_buffer;
+
+ /* encrypt buffer with cipher */
+ cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt);
+ cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
/* choose a cipher at random from the array*/
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
-
- /* encrypt buffer with cipher */
- cipher_set_iv(cipher_array[cipher_index], &nonce);
- cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer);
}
timer = clock() - timer;
@@ -451,7 +582,7 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
return 0;
}
- return CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
+ return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
}
void
@@ -459,10 +590,10 @@ cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
int i;
int min_enc_len = 16;
int max_enc_len = 2048; /* should be a power of two */
- int num_trials = 10000;
+ int num_trials = 1000000;
- printf("timing %s throughput with array size %d:\n",
- (ca[0])->type->description, num_cipher);
+ printf("timing %s throughput with key length %d, array size %d:\n",
+ (ca[0])->type->description, (ca[0])->key_len, num_cipher);
fflush(stdout);
for (i=min_enc_len; i <= max_enc_len; i = i * 4)
printf("msg len: %d\tgigabits per second: %f\n", i,
diff --git a/third_party/srtp/crypto/test/datatypes_driver.c b/third_party/srtp/crypto/test/datatypes_driver.c
index f1866524..4b5e46c7 100644
--- a/third_party/srtp/crypto/test/datatypes_driver.c
+++ b/third_party/srtp/crypto/test/datatypes_driver.c
@@ -44,6 +44,10 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h> /* for printf() */
#include <string.h> /* for strlen() */
#include "datatypes.h"
@@ -205,7 +209,7 @@ test_hex_string_funcs(void) {
void
print_string(char *s) {
- int i;
+ size_t i;
printf("%s\n", s);
printf("strlen(s) = %u\n", (unsigned)strlen(s));
printf("{ ");
diff --git a/third_party/srtp/crypto/test/env.c b/third_party/srtp/crypto/test/env.c
index 37a6e273..6cc0f958 100644
--- a/third_party/srtp/crypto/test/env.c
+++ b/third_party/srtp/crypto/test/env.c
@@ -49,7 +49,9 @@
int
main(void) {
int err_count = 0;
+#ifndef OPENSSL
char *str;
+#endif
#ifdef WORDS_BIGENDIAN
printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
@@ -80,6 +82,7 @@ main(void) {
printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
#endif
+#ifndef OPENSSL
#ifdef DEV_URANDOM
str = DEV_URANDOM;
#else
@@ -90,6 +93,7 @@ main(void) {
if (strcmp("", str) == 0) {
err_count++;
}
+#endif
if (err_count)
printf("warning: configuration is probably in error "
diff --git a/third_party/srtp/crypto/test/kernel_driver.c b/third_party/srtp/crypto/test/kernel_driver.c
index 8ef8a5f4..188637cd 100644
--- a/third_party/srtp/crypto/test/kernel_driver.c
+++ b/third_party/srtp/crypto/test/kernel_driver.c
@@ -43,8 +43,12 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h> /* for printf() */
-#include <unistd.h> /* for getopt() */
+#include "getopt_s.h"
#include "crypto_kernel.h"
void
@@ -55,7 +59,6 @@ usage(char *prog_name) {
int
main (int argc, char *argv[]) {
- extern char *optarg;
int q;
int do_validation = 0;
err_status_t status;
@@ -73,7 +76,7 @@ main (int argc, char *argv[]) {
/* process input arguments */
while (1) {
- q = getopt(argc, argv, "vd:");
+ q = getopt_s(argc, argv, "vd:");
if (q == -1)
break;
switch (q) {
@@ -81,9 +84,9 @@ main (int argc, char *argv[]) {
do_validation = 1;
break;
case 'd':
- status = crypto_kernel_set_debug_module(optarg, 1);
+ status = crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
- printf("error: set debug module (%s) failed\n", optarg);
+ printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
diff --git a/third_party/srtp/crypto/test/rand_gen.c b/third_party/srtp/crypto/test/rand_gen.c
index ccea097f..b8051d5b 100644
--- a/third_party/srtp/crypto/test/rand_gen.c
+++ b/third_party/srtp/crypto/test/rand_gen.c
@@ -43,8 +43,12 @@
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h> /* for printf() */
-#include <unistd.h> /* for getopt() */
+#include "getopt_s.h"
#include "crypto_kernel.h"
/*
@@ -68,7 +72,6 @@ usage(char *prog_name) {
int
main (int argc, char *argv[]) {
- extern char *optarg;
int q;
int num_octets = 0;
unsigned do_list_mods = 0;
@@ -86,14 +89,14 @@ main (int argc, char *argv[]) {
/* process input arguments */
while (1) {
- q = getopt(argc, argv, "ld:n:");
+ q = getopt_s(argc, argv, "ld:n:");
if (q == -1)
break;
switch (q) {
case 'd':
- status = crypto_kernel_set_debug_module(optarg, 1);
+ status = crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
- printf("error: set debug module (%s) failed\n", optarg);
+ printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
@@ -101,7 +104,7 @@ main (int argc, char *argv[]) {
do_list_mods = 1;
break;
case 'n':
- num_octets = atoi(optarg);
+ num_octets = atoi(optarg_s);
if (num_octets < 0 || num_octets > BUF_LEN)
usage(argv[0]);
break;
diff --git a/third_party/srtp/crypto/test/rand_gen_soak.c b/third_party/srtp/crypto/test/rand_gen_soak.c
new file mode 100644
index 00000000..b0e67a73
--- /dev/null
+++ b/third_party/srtp/crypto/test/rand_gen_soak.c
@@ -0,0 +1,116 @@
+/*
+ * Soak test the RNG for exhaustion failures
+ */
+
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <stdio.h> /* for printf() */
+#include "getopt_s.h"
+#include "crypto_kernel.h"
+
+#define BUF_LEN (MAX_PRINT_STRING_LEN/2)
+
+int main(int argc, char *argv[])
+{
+ int q;
+ int num_octets = 0;
+ err_status_t status;
+ uint32_t iterations = 0;
+ int print_values = 0;
+
+ if (argc == 1) {
+ exit(255);
+ }
+
+ status = crypto_kernel_init();
+ if (status) {
+ printf("error: crypto_kernel init failed\n");
+ exit(1);
+ }
+
+ while (1) {
+ q = getopt_s(argc, argv, "pvn:");
+ if (q == -1) {
+ break;
+ }
+ switch (q) {
+ case 'p':
+ print_values = 1;
+ break;
+ case 'n':
+ num_octets = atoi(optarg_s);
+ if (num_octets < 0 || num_octets > BUF_LEN) {
+ exit(255);
+ }
+ break;
+ case 'v':
+ num_octets = 30;
+ print_values = 0;
+ break;
+ default:
+ exit(255);
+ }
+ }
+
+ if (num_octets > 0) {
+ while (iterations < 300000) {
+ uint8_t buffer[BUF_LEN];
+
+ status = crypto_get_random(buffer, num_octets);
+ if (status) {
+ printf("iteration %d error: failure in random source\n", iterations);
+ exit(255);
+ } else if (print_values) {
+ printf("%s\n", octet_string_hex_string(buffer, num_octets));
+ }
+ iterations++;
+ }
+ }
+
+ status = crypto_kernel_shutdown();
+ if (status) {
+ printf("error: crypto_kernel shutdown failed\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
diff --git a/third_party/srtp/crypto/test/sha1_driver.c b/third_party/srtp/crypto/test/sha1_driver.c
index f7cb6ca2..6adfad17 100644
--- a/third_party/srtp/crypto/test/sha1_driver.c
+++ b/third_party/srtp/crypto/test/sha1_driver.c
@@ -43,8 +43,14 @@
*
*/
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
#include <stdio.h>
+#include <string.h>
#include "sha1.h"
+#include "datatypes.h"
#define SHA_PASS 0
#define SHA_FAIL 1
@@ -113,17 +119,17 @@ sha1_test_case_validate(const hash_test_case_t *test_case) {
if (0 == memcmp(test_case->hash, hash_value, 20)) {
#if VERBOSE
printf("PASSED: reference value: %s\n",
- octet_string_hex_string((uint8_t *)test_case->hash, 20));
+ octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("PASSED: computed value: %s\n",
- octet_string_hex_string((uint8_t *)hash_value, 20));
+ octet_string_hex_string((const uint8_t *)hash_value, 20));
#endif
return err_status_ok;
}
printf("reference value: %s\n",
- octet_string_hex_string((uint8_t *)test_case->hash, 20));
+ octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("computed value: %s\n",
- octet_string_hex_string((uint8_t *)hash_value, 20));
+ octet_string_hex_string((const uint8_t *)hash_value, 20));
return err_status_algo_fail;
@@ -136,7 +142,7 @@ struct hex_sha1_test_case_t {
};
err_status_t
-sha1_add_test_cases() {
+sha1_add_test_cases(void) {
int i;
err_status_t err;
@@ -485,6 +491,21 @@ sha1_add_test_cases() {
return err_status_ok;
}
+err_status_t
+sha1_dealloc_test_cases(void) {
+ hash_test_case_t *t, *next;
+
+ for (t = sha1_test_case_list; t != NULL; t = next) {
+ next = t->next_test_case;
+ free(t);
+ }
+
+ sha1_test_case_list = NULL;
+
+ return err_status_ok;
+}
+
+
err_status_t
sha1_validate(void) {
@@ -510,6 +531,8 @@ sha1_validate(void) {
test_case = test_case->next_test_case;
}
+ sha1_dealloc_test_cases();
+
return err_status_ok;
}
diff --git a/third_party/srtp/crypto/test/stat_driver.c b/third_party/srtp/crypto/test/stat_driver.c
index 09cc44a6..962f7484 100644
--- a/third_party/srtp/crypto/test/stat_driver.c
+++ b/third_party/srtp/crypto/test/stat_driver.c
@@ -7,11 +7,51 @@
* Cisco Systems, Inc.
*/
+/*
+ *
+ * Copyright (c) 2001-2006, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
#include <stdio.h> /* for printf() */
#include "err.h"
#include "stat.h"
+#include "srtp.h"
#include "cipher.h"
@@ -32,12 +72,18 @@ err_check(err_status_t s) {
int
main (int argc, char *argv[]) {
- uint8_t buffer[2500];
+ uint8_t buffer[2532];
unsigned int buf_len = 2500;
int i, j;
extern cipher_type_t aes_icm;
+#ifdef OPENSSL
+ extern cipher_type_t aes_gcm_128_openssl;
+ extern cipher_type_t aes_gcm_256_openssl;
+#endif
cipher_t *c;
- uint8_t key[30] = {
+ uint8_t key[46] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -49,6 +95,7 @@ main (int argc, char *argv[]) {
printf("statistical tests driver\n");
+ v128_set_to_zero(&nonce);
for (i=0; i < 2500; i++)
buffer[i] = 0;
@@ -69,9 +116,9 @@ main (int argc, char *argv[]) {
/* set buffer to cipher output */
for (i=0; i < 2500; i++)
buffer[i] = 0;
- err_check(cipher_type_alloc(&aes_icm, &c, 30));
- err_check(cipher_init(c, key, direction_encrypt));
- err_check(cipher_set_iv(c, &nonce));
+ err_check(cipher_type_alloc(&aes_icm, &c, 30, 0));
+ err_check(cipher_init(c, key));
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
@@ -86,7 +133,7 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++)
buffer[i] = 0;
nonce.v32[3] = i;
- err_check(cipher_set_iv(c, &nonce));
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) {
num_fail++;
@@ -97,5 +144,103 @@ main (int argc, char *argv[]) {
printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n");
+ err_check(cipher_dealloc(c));
+
+ printf("running stat_tests on AES-256-ICM, expecting success\n");
+ /* set buffer to cipher output */
+ for (i=0; i < 2500; i++)
+ buffer[i] = 0;
+ err_check(cipher_type_alloc(&aes_icm, &c, 46, 0));
+ err_check(cipher_init(c, key));
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ /* run tests on cipher outout */
+ printf("monobit %d\n", stat_test_monobit(buffer));
+ printf("poker %d\n", stat_test_poker(buffer));
+ printf("runs %d\n", stat_test_runs(buffer));
+
+ printf("runs test (please be patient): ");
+ fflush(stdout);
+ num_fail = 0;
+ v128_set_to_zero(&nonce);
+ for(j=0; j < num_trials; j++) {
+ for (i=0; i < 2500; i++)
+ buffer[i] = 0;
+ nonce.v32[3] = i;
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ if (stat_test_runs(buffer)) {
+ num_fail++;
+ }
+ }
+
+#ifdef OPENSSL
+ {
+ printf("running stat_tests on AES-128-GCM, expecting success\n");
+ /* set buffer to cipher output */
+ for (i=0; i < 2500; i++) {
+ buffer[i] = 0;
+ }
+ err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8));
+ err_check(cipher_init(c, key));
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ /* run tests on cipher outout */
+ printf("monobit %d\n", stat_test_monobit(buffer));
+ printf("poker %d\n", stat_test_poker(buffer));
+ printf("runs %d\n", stat_test_runs(buffer));
+ fflush(stdout);
+ num_fail = 0;
+ v128_set_to_zero(&nonce);
+ for(j=0; j < num_trials; j++) {
+ for (i=0; i < 2500; i++) {
+ buffer[i] = 0;
+ }
+ nonce.v32[3] = i;
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ buf_len = 2500;
+ if (stat_test_runs(buffer)) {
+ num_fail++;
+ }
+ }
+
+ printf("running stat_tests on AES-256-GCM, expecting success\n");
+ /* set buffer to cipher output */
+ for (i=0; i < 2500; i++) {
+ buffer[i] = 0;
+ }
+ err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16));
+ err_check(cipher_init(c, key));
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ /* run tests on cipher outout */
+ printf("monobit %d\n", stat_test_monobit(buffer));
+ printf("poker %d\n", stat_test_poker(buffer));
+ printf("runs %d\n", stat_test_runs(buffer));
+ fflush(stdout);
+ num_fail = 0;
+ v128_set_to_zero(&nonce);
+ for(j=0; j < num_trials; j++) {
+ for (i=0; i < 2500; i++) {
+ buffer[i] = 0;
+ }
+ nonce.v32[3] = i;
+ err_check(cipher_set_iv(c, &nonce, direction_encrypt));
+ err_check(cipher_encrypt(c, buffer, &buf_len));
+ buf_len = 2500;
+ if (stat_test_runs(buffer)) {
+ num_fail++;
+ }
+ }
+ }
+#endif
+
+ printf("%d failures in %d tests\n", num_fail, num_trials);
+ printf("(nota bene: a small fraction of stat_test failures does not \n"
+ "indicate that the random source is invalid)\n");
+
+ err_check(cipher_dealloc(c));
+
return 0;
}