update libsrtp to use openssl
This commit is contained in:
parent
365f81b412
commit
80c7eb85e6
|
@ -5,28 +5,37 @@ AM_CFLAGS = $(new_AM_CFLAGS) -I./src -Icrypto/include -I$(srcdir)/include -I$
|
|||
AM_CPPFLAGS = $(AM_CFLAGS)
|
||||
AM_LDFLAGS = $(new_AM_LDFLAGS) -L.
|
||||
|
||||
HMAC_OBJS = @HMAC_OBJS@
|
||||
RNG_EXTRA_OBJS = @RNG_EXTRA_OBJS@
|
||||
AES_ICM_OBJS = @AES_ICM_OBJS@
|
||||
|
||||
lib_LTLIBRARIES = libsrtp.la libcryptomath.la
|
||||
libsrtp_la_SOURCES = srtp/srtp.c srtp/ekt.c crypto/cipher/cipher.c crypto/cipher/null_cipher.c \
|
||||
crypto/cipher/aes.c crypto/cipher/aes_icm.c \
|
||||
crypto/cipher/aes_cbc.c \
|
||||
crypto/hash/null_auth.c crypto/hash/sha1.c \
|
||||
crypto/hash/hmac.c crypto/hash/auth.c \
|
||||
crypto/hash/null_auth.c crypto/hash/auth.c \
|
||||
crypto/math/datatypes.c crypto/math/stat.c \
|
||||
crypto/kernel/crypto_kernel.c crypto/kernel/alloc.c \
|
||||
crypto/kernel/key.c \
|
||||
crypto/rng/prng.c crypto/rng/ctr_prng.c \
|
||||
crypto/kernel/err.c \
|
||||
crypto/replay/rdb.c crypto/replay/rdbx.c crypto/replay/ut_sim.c
|
||||
crypto/replay/rdb.c crypto/replay/rdbx.c crypto/replay/ut_sim.c
|
||||
|
||||
libsrtp_la_LDFLAGS = -version-info 1:42:1
|
||||
|
||||
EXTRA_DIST=
|
||||
|
||||
if ENABLE_OPENSSL
|
||||
libsrtp_la_SOURCES += crypto/cipher/aes_icm_ossl.c crypto/cipher/aes_gcm_ossl.c
|
||||
libsrtp_la_SOURCES += crypto/rng/rand_source_ossl.c
|
||||
else
|
||||
libsrtp_la_SOURCES += crypto/hash/sha1.c crypto/hash/hmac.c
|
||||
libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c crypto/cipher/aes_cbc.c
|
||||
if RNG_OBJS_LINUX
|
||||
libsrtp_la_SOURCES += crypto/rng/rand_linux_kernel.c
|
||||
EXTRA_DIST += crypto/rng/rand_source.c
|
||||
else
|
||||
libsrtp_la_SOURCES += crypto/rng/rand_source.c
|
||||
endif
|
||||
endif
|
||||
|
||||
if GDOI
|
||||
libsrtp_la_SOURCES += gdoi/srtp+gdoi.c
|
||||
|
|
|
@ -26,9 +26,10 @@ The configure script accepts the following options:
|
|||
--enable-syslog use syslog for error reporting
|
||||
--disable-stdout use stdout for error reporting
|
||||
--enable-console use /dev/console for error reporting
|
||||
--enable-openssl use OpenSSL crypto primitives
|
||||
--gdoi use GDOI key management (disabled at present)
|
||||
|
||||
By default, debugging is enabled and stdout is used for debugging.
|
||||
By default, debbuging is enabled and stdout is used for debugging.
|
||||
You can use the above configure options to have the debugging output
|
||||
sent to syslog or the system console. Alternatively, you can define
|
||||
ERR_REPORTING_FILE in include/conf.h to be any other file that can be
|
||||
|
@ -77,7 +78,7 @@ Applications
|
|||
Manual srtp keying uses the -k option; automated key management
|
||||
using gdoi will be added later.
|
||||
|
||||
usage: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port
|
||||
usage: rtpw [-d <debug>]* [-k <key> [-a][-e <key size>][-g]] [-s | -r] dest_ip dest_port
|
||||
or rtpw -l
|
||||
|
||||
Either the -s (sender) or -r (receiver) option must be chosen.
|
||||
|
@ -86,25 +87,15 @@ or rtpw -l
|
|||
which the dictionary will be sent, respectively.
|
||||
|
||||
options:
|
||||
|
||||
-s (s)rtp sender - causes app to send words
|
||||
|
||||
-r (s)rtp receive - causes app to receive words
|
||||
|
||||
-k <key> use srtp master key <key>, where the
|
||||
key is a hexadecimal value (without the
|
||||
leading "0x")
|
||||
|
||||
-e encrypt/decrypt (for data confidentiality)
|
||||
(requires use of -k option as well)
|
||||
|
||||
-a message authentication
|
||||
(requires use of -k option as well)
|
||||
|
||||
-l list debug modules
|
||||
|
||||
-d <debug> turn on debugging for module <debug>
|
||||
|
||||
-a use message authentication
|
||||
-e <key size> use encryption (use 128, 192, or 256 for key size)
|
||||
-g Use AES-GCM mode (must be used with -e)
|
||||
-k <key> sets the srtp master key
|
||||
-s act as rtp sender
|
||||
-r act as rtp receiver
|
||||
-l list debug modules
|
||||
-d <debug> turn on debugging for module <debug>
|
||||
-i specify input/output file
|
||||
|
||||
In order to get random 30-byte values for use as key/salt pairs , you
|
||||
can use the following bash function to format the output of
|
||||
|
@ -119,7 +110,7 @@ An example of an SRTP session using two rtpw programs follows:
|
|||
|
||||
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
|
||||
|
||||
[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999
|
||||
[sh1]$ test/rtpw -s -k $k -e 128 -a 0.0.0.0 9999
|
||||
Security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
setting SSRC to 2078917053
|
||||
|
@ -129,7 +120,7 @@ sending word: aa
|
|||
sending word: aal
|
||||
...
|
||||
|
||||
[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999
|
||||
[sh2]$ test/rtpw -r -k $k -e 128 -a 0.0.0.0 9999
|
||||
security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
19 octets received from SSRC 2078917053 word: A
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#! /bin/sh
|
||||
srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
|
||||
$srcpath/configure "$@" --disable-shared --with-pic
|
||||
$srcpath/configure "$@" --disable-shared --with-pic --enable-openssl
|
||||
|
||||
|
|
|
@ -143,22 +143,6 @@ if test "$cross_compiling" != yes; then
|
|||
[AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(which random device to use)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
RNG_OBJS=rand_linux_kernel.o
|
||||
AC_MSG_RESULT([Linux kernel builtin])
|
||||
else
|
||||
RNG_OBJS=rand_source.o
|
||||
if test -n "$DEV_URANDOM"; then
|
||||
AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device])
|
||||
AC_MSG_RESULT([$DEV_URANDOM])
|
||||
else
|
||||
AC_MSG_RESULT([standard rand() function...])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(RNG_OBJS)
|
||||
AM_CONDITIONAL(RNG_OBJS_LINUX, test x$enable_kernel_linux = xyes)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(stdlib.h)
|
||||
|
@ -273,6 +257,56 @@ if test "$enable_generic_aesicm" = "yes"; then
|
|||
fi
|
||||
AC_MSG_RESULT($enable_generic_aesicm)
|
||||
|
||||
AC_MSG_CHECKING(whether to leverage OpenSSL crypto)
|
||||
AC_ARG_ENABLE(openssl,
|
||||
[AS_HELP_STRING([--enable-openssl],
|
||||
[compile in OpenSSL crypto engine])],
|
||||
[], enable_openssl=no)
|
||||
if test "$enable_openssl" = "yes"; then
|
||||
echo $enable_openssl
|
||||
LDFLAGS="$LDFLAGS $(pkg-config --libs openssl)";
|
||||
CFLAGS="$CFLAGS $(pkg-config --cflags openssl)";
|
||||
|
||||
AC_CHECK_LIB([crypto], [EVP_EncryptInit], [],
|
||||
[AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])])
|
||||
AC_CHECK_LIB([crypto], [EVP_aes_128_ctr], [],
|
||||
[AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])])
|
||||
AC_CHECK_LIB([crypto], [EVP_aes_128_gcm], [],
|
||||
[AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])])
|
||||
AC_DEFINE(OPENSSL, 1, [Define this to use OpenSSL crypto.])
|
||||
AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o"
|
||||
RNG_OBJS=rand_source_ossl.o
|
||||
HMAC_OBJS=crypto/hash/hmac_ossl.o
|
||||
USE_OPENSSL=1
|
||||
AC_SUBST(USE_OPENSSL)
|
||||
else
|
||||
echo $enable_openssl
|
||||
AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o crypto/cipher/aes_cbc.o"
|
||||
AC_MSG_CHECKING(which random device to use)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
RNG_OBJS=rand_linux_kernel.o
|
||||
AC_MSG_RESULT([Linux kernel builtin])
|
||||
else
|
||||
RNG_OBJS=rand_source.o
|
||||
if test -n "$DEV_URANDOM"; then
|
||||
AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device])
|
||||
AC_MSG_RESULT([$DEV_URANDOM])
|
||||
else
|
||||
AC_MSG_RESULT([standard rand() function...])
|
||||
fi
|
||||
fi
|
||||
RNG_EXTRA_OBJS="crypto/rng/prng.o crypto/rng/ctr_prng.o"
|
||||
HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
|
||||
fi
|
||||
AM_CONDITIONAL([ENABLE_OPENSSL],[test "${enable_openssl}" = "yes"])
|
||||
AM_CONDITIONAL([RNG_OBJS_LINUX], test x$enable_kernel_linux = xyes)
|
||||
|
||||
AC_SUBST(AES_ICM_OBJS)
|
||||
AC_SUBST(RNG_OBJS)
|
||||
AC_SUBST(RNG_EXTRA_OBJS)
|
||||
AC_SUBST(HMAC_OBJS)
|
||||
AC_MSG_RESULT($enable_openssl)
|
||||
|
||||
AC_MSG_CHECKING(whether to use syslog for error reporting)
|
||||
AC_ARG_ENABLE(syslog,
|
||||
[AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])],
|
||||
|
|
|
@ -9,14 +9,14 @@ top_builddir = @top_builddir@
|
|||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
INCDIR = -Iinclude -I$(srcdir)/include
|
||||
INCDIR = -Iinclude -I$(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
|
||||
|
@ -41,9 +41,13 @@ 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 for AES-128
|
||||
|
@ -58,60 +62,31 @@ 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..."
|
||||
@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."
|
||||
@echo "crypto 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
|
||||
%$(EXE): %.c
|
||||
$(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)
|
||||
all: $(testapp)
|
||||
|
||||
# housekeeping functions
|
||||
|
||||
|
|
|
@ -104,36 +104,25 @@ aes_cbc_dealloc(cipher_t *c) {
|
|||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len,
|
||||
cipher_direction_t dir) {
|
||||
err_status_t status;
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len) {
|
||||
|
||||
debug_print(mod_aes_cbc,
|
||||
"key: %s", octet_string_hex_string(key, key_len));
|
||||
|
||||
/* expand key for the appropriate direction */
|
||||
switch (dir) {
|
||||
case (direction_encrypt):
|
||||
status = aes_expand_encryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
case (direction_decrypt):
|
||||
status = aes_expand_decryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
return err_status_bad_param;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -144,6 +133,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;
|
||||
}
|
||||
|
||||
|
@ -375,6 +382,8 @@ 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,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -426,6 +435,8 @@ 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,
|
||||
&aes_cbc_test_case_0 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -467,6 +478,8 @@ cipher_test_case_t aes_cbc_test_case_2 = {
|
|||
aes_cbc_test_case_2_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_cbc_test_case_2_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
&aes_cbc_test_case_1 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -520,6 +533,8 @@ cipher_test_case_t aes_cbc_test_case_3 = {
|
|||
aes_cbc_test_case_3_plaintext, /* plaintext */
|
||||
80, /* octets in ciphertext */
|
||||
aes_cbc_test_case_3_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
&aes_cbc_test_case_2 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -527,9 +542,11 @@ 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_3,
|
||||
|
|
|
@ -0,0 +1,529 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#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 octet tags. The spec allows for
|
||||
* optional 12 and 16 byte tags. These longer tag lengths may
|
||||
* be implemented in the future.
|
||||
*/
|
||||
#define GCM_AUTH_TAG_LEN 8
|
||||
|
||||
|
||||
/*
|
||||
* This function allocates a new instance of this crypto engine.
|
||||
* The key_len parameter should be one of 30 or 46 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)
|
||||
{
|
||||
aes_gcm_ctx_t *gcm;
|
||||
int tmp;
|
||||
uint8_t *allptr;
|
||||
|
||||
debug_print(mod_aes_gcm, "allocating cipher with key length %d", key_len);
|
||||
|
||||
/*
|
||||
* Verify the key_len is valid for one of: AES-128/256
|
||||
*/
|
||||
if (key_len != AES_128_KEYSIZE_WSALT &&
|
||||
key_len != AES_256_KEYSIZE_WSALT) {
|
||||
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_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 = GCM_AUTH_TAG_LEN;
|
||||
break;
|
||||
case AES_256_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 = GCM_AUTH_TAG_LEN;
|
||||
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;
|
||||
v128_t *nonce = iv;
|
||||
|
||||
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(nonce));
|
||||
|
||||
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_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, 0x0d, 0x0e,
|
||||
};
|
||||
|
||||
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[68] = {
|
||||
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 8 bytes are the tag */
|
||||
0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_0 = {
|
||||
AES_128_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 */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
uint8_t aes_gcm_test_case_1_key[AES_256_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, 0x0d, 0x0e,
|
||||
|
||||
};
|
||||
|
||||
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[68] = {
|
||||
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 8 bytes are the tag */
|
||||
0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_1 = {
|
||||
AES_256_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 */
|
||||
NULL /* 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
|
||||
};
|
||||
|
|
@ -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
|
||||
|
@ -272,7 +272,7 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
|
|||
*/
|
||||
|
||||
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) {
|
||||
v128_t *nonce = (v128_t *) iv;
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
|
@ -503,6 +503,8 @@ 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,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -542,6 +544,8 @@ cipher_test_case_t aes_icm_test_case_1 = {
|
|||
aes_icm_test_case_1_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_1_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
&aes_icm_test_case_0 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -555,9 +559,11 @@ 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_1,
|
||||
|
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#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;
|
||||
extern cipher_type_t aes_icm_192;
|
||||
extern cipher_type_t aes_icm_256;
|
||||
|
||||
/*
|
||||
* integer counter mode works as follows:
|
||||
*
|
||||
* 16 bits
|
||||
* <----->
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* | nonce | pakcet 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.
|
||||
*/
|
||||
err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int x)
|
||||
{
|
||||
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 && key_len != AES_192_KEYSIZE_WSALT &&
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
case AES_192_KEYSIZE:
|
||||
aes_icm_192.ref_count--;
|
||||
break;
|
||||
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)
|
||||
{
|
||||
/*
|
||||
* 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);
|
||||
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 || c->key_size == AES_192_KEYSIZE) {
|
||||
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 = (v128_t*)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;
|
||||
case AES_192_KEYSIZE:
|
||||
evp = EVP_aes_192_ctr();
|
||||
break;
|
||||
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, (int*)&len)) {
|
||||
return err_status_cipher_fail;
|
||||
}
|
||||
*enc_len += len;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abstraction layer for encrypt.
|
||||
*/
|
||||
err_status_t aes_icm_output (aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output)
|
||||
{
|
||||
unsigned int len = num_octets_to_output;
|
||||
|
||||
/* zeroize the buffer */
|
||||
octet_string_set_to_zero(buffer, num_octets_to_output);
|
||||
|
||||
/* exor keystream into buffer */
|
||||
return aes_icm_openssl_encrypt(c, buffer, &len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Name of this crypto engine
|
||||
*/
|
||||
char aes_icm_openssl_description[] = "AES-128 counter mode using openssl";
|
||||
char aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
|
||||
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,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 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,
|
||||
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
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
|
|
@ -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
|
||||
|
@ -45,6 +45,7 @@
|
|||
*/
|
||||
|
||||
#include "cipher.h"
|
||||
#include "crypto_types.h"
|
||||
#include "rand_source.h" /* used in invertibiltiy tests */
|
||||
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
|
||||
|
||||
|
@ -87,6 +88,7 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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,7 +107,6 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
* encryption and decryption functions
|
||||
*/
|
||||
while (test_case != NULL) {
|
||||
|
||||
/* allocate cipher */
|
||||
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
|
||||
if (status)
|
||||
|
@ -117,7 +118,7 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +137,30 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +169,18 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +215,7 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +234,27 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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);
|
||||
|
@ -297,19 +343,34 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +378,17 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
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 +396,30 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
* 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 +430,9 @@ cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
|||
octet_string_hex_string(buffer, length));
|
||||
|
||||
/* compare the resulting plaintext with the original one */
|
||||
if (length != (unsigned int)plaintext_len)
|
||||
if (length != (unsigned int)plaintext_len) {
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
status = err_status_ok;
|
||||
for (i=0; i < plaintext_len; i++)
|
||||
if (buffer[i] != buffer2[i]) {
|
||||
|
@ -405,7 +492,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;
|
||||
|
|
|
@ -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
|
||||
|
@ -130,6 +130,8 @@ null_cipher_test_0 = {
|
|||
NULL, /* plaintext */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
@ -142,9 +144,11 @@ 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,
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hmac.h"
|
||||
#include "alloc.h"
|
||||
#include <openssl/evp.h>
|
||||
|
||||
/* 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 > 20) {
|
||||
return err_status_bad_param;
|
||||
}
|
||||
|
||||
/* check output length - should be less than 20 bytes */
|
||||
if (out_len > 20) {
|
||||
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 > 20) {
|
||||
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 < 64; i++) {
|
||||
ipad[i] = 0x36;
|
||||
((uint8_t*)state->opad)[i] = 0x5c;
|
||||
}
|
||||
|
||||
debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
|
||||
|
||||
/* initialize sha1 context */
|
||||
sha1_init(&state->init_ctx);
|
||||
state->init_ctx_initialized = 1;
|
||||
|
||||
/* hash ipad ^ key */
|
||||
sha1_update(&state->init_ctx, ipad, 64);
|
||||
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 > 20) {
|
||||
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, 20));
|
||||
|
||||
/* re-initialize hash context */
|
||||
sha1_init(&state->ctx);
|
||||
|
||||
/* hash opad ^ key */
|
||||
sha1_update(&state->ctx, (uint8_t*)state->opad, 64);
|
||||
|
||||
/* hash the result of the inner hash */
|
||||
sha1_update(&state->ctx, (uint8_t*)H, 20);
|
||||
|
||||
/* 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[20] = {
|
||||
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[20] = {
|
||||
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 = {
|
||||
20, /* octets in key */
|
||||
hmac_test_case_0_key, /* key */
|
||||
8, /* octets in data */
|
||||
hmac_test_case_0_data, /* data */
|
||||
20, /* 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
|
||||
};
|
||||
|
|
@ -17,6 +17,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 +33,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,
|
||||
int key_len, 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,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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 <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 */
|
||||
|
|
@ -29,7 +29,7 @@ aes_icm_context_init(aes_icm_ctx_t *c,
|
|||
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,
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
#define SALT_SIZE 14
|
||||
#define AES_128_KEYSIZE AES_BLOCK_SIZE
|
||||
#define AES_192_KEYSIZE AES_BLOCK_SIZE + AES_BLOCK_SIZE / 2
|
||||
#define AES_256_KEYSIZE AES_BLOCK_SIZE * 2
|
||||
#define AES_128_KEYSIZE_WSALT AES_128_KEYSIZE + SALT_SIZE
|
||||
#define AES_192_KEYSIZE_WSALT AES_192_KEYSIZE + SALT_SIZE
|
||||
#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);
|
||||
|
||||
|
||||
#endif /* AES_ICM_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
|
||||
|
@ -84,11 +84,10 @@ typedef err_status_t (*cipher_alloc_func_t)
|
|||
|
||||
/*
|
||||
* 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, int key_len, cipher_direction_t dir);
|
||||
(void *state, const uint8_t *key, int key_len);
|
||||
|
||||
/* a cipher_dealloc_func_t de-allocates a cipher_t */
|
||||
|
||||
|
@ -99,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)
|
||||
|
@ -114,7 +120,15 @@ typedef err_status_t (*cipher_decrypt_func_t)
|
|||
*/
|
||||
|
||||
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,
|
||||
|
@ -132,6 +146,8 @@ typedef struct cipher_test_case_t {
|
|||
uint8_t *plaintext; /* plaintext */
|
||||
int ciphertext_length_octets; /* octets in plaintext */
|
||||
uint8_t *ciphertext; /* ciphertext */
|
||||
int aad_length_octets; /* octets in AAD */
|
||||
uint8_t *aad; /* AAD */
|
||||
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */
|
||||
} cipher_test_case_t;
|
||||
|
||||
|
@ -141,9 +157,11 @@ 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;
|
||||
|
@ -160,9 +178,7 @@ 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 */
|
||||
|
@ -171,16 +187,23 @@ typedef struct cipher_t {
|
|||
|
||||
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
|
||||
|
||||
#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), ((c)->key_len), (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
|
||||
|
|
|
@ -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
|
||||
|
@ -141,6 +141,34 @@
|
|||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -48,6 +48,43 @@
|
|||
#define SHA1_H
|
||||
|
||||
#include "err.h"
|
||||
#ifdef OPENSSL
|
||||
#include <openssl/evp.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.
|
||||
*
|
||||
*/
|
||||
|
||||
void inline sha1_init (sha1_ctx_t *ctx)
|
||||
{
|
||||
EVP_MD_CTX_init(ctx);
|
||||
EVP_DigestInit(ctx, EVP_sha1());
|
||||
}
|
||||
|
||||
void inline sha1_update (sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg)
|
||||
{
|
||||
EVP_DigestUpdate(ctx, M, octets_in_msg);
|
||||
}
|
||||
|
||||
void inline 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 +141,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 */
|
||||
|
|
|
@ -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
|
||||
|
@ -69,7 +69,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 +142,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,6 +152,7 @@ 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);
|
||||
|
@ -154,9 +161,20 @@ crypto_kernel_init() {
|
|||
status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
|
||||
if (status)
|
||||
return status;
|
||||
#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);
|
||||
|
@ -567,7 +585,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;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,11 @@ ctr_prng_init(rand_source_func_t random_source) {
|
|||
return status;
|
||||
|
||||
/* initialize aes ctr context with random 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;
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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
|
||||
|
@ -48,7 +48,12 @@
|
|||
#include <string.h> /* for memset() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#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,7 +119,14 @@ 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
|
||||
extern cipher_type_t aes_icm_192;
|
||||
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[]) {
|
||||
|
@ -171,6 +183,7 @@ 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);
|
||||
|
||||
|
@ -179,19 +192,41 @@ main(int argc, char *argv[]) {
|
|||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher);
|
||||
#else
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_icm_192, 38, num_cipher);
|
||||
|
||||
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, 30, num_cipher);
|
||||
}
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) {
|
||||
cipher_driver_test_array_throughput(&aes_gcm_256_openssl, 46, 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
|
||||
cipher_driver_self_test(&aes_icm_192);
|
||||
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);
|
||||
check_status(status);
|
||||
|
||||
status = cipher_init(c, NULL, direction_encrypt);
|
||||
status = cipher_init(c, NULL);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
|
@ -211,7 +246,7 @@ main(int argc, char *argv[]) {
|
|||
exit(status);
|
||||
}
|
||||
|
||||
status = cipher_init(c, test_key, direction_encrypt);
|
||||
status = cipher_init(c, test_key);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
|
@ -226,13 +261,17 @@ main(int argc, char *argv[]) {
|
|||
check_status(status);
|
||||
|
||||
/* repeat the tests with 256-bit keys */
|
||||
#ifndef OPENSSL
|
||||
status = cipher_type_alloc(&aes_icm, &c, 46);
|
||||
#else
|
||||
status = cipher_type_alloc(&aes_icm_256, &c, 46);
|
||||
#endif
|
||||
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)
|
||||
|
@ -245,8 +284,48 @@ main(int argc, char *argv[]) {
|
|||
|
||||
status = cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef OPENSSL
|
||||
/* run the throughput test on the aes_gcm_128_openssl cipher */
|
||||
status = cipher_type_alloc(&aes_gcm_128_openssl, &c, 30);
|
||||
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, 46);
|
||||
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
|
||||
|
@ -306,7 +385,7 @@ cipher_driver_test_buffering(cipher_t *c) {
|
|||
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;
|
||||
|
||||
|
@ -316,7 +395,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;
|
||||
|
||||
|
@ -409,7 +488,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
key[j] = (uint8_t) rand();
|
||||
for (; j < klen_pad; j++)
|
||||
key[j] = 0;
|
||||
status = cipher_init(*cipher_array, key, direction_encrypt);
|
||||
status = cipher_init(*cipher_array, key);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -476,7 +555,7 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
|
|||
unsigned octets_to_encrypt = octets_in_buffer;
|
||||
|
||||
/* encrypt buffer with cipher */
|
||||
cipher_set_iv(cipher_array[cipher_index], &nonce);
|
||||
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*/
|
||||
|
|
|
@ -80,6 +80,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 +91,7 @@ main(void) {
|
|||
if (strcmp("", str) == 0) {
|
||||
err_count++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err_count)
|
||||
printf("warning: configuration is probably in error "
|
||||
|
|
|
@ -32,10 +32,14 @@ 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[46] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
|
@ -73,8 +77,8 @@ main (int argc, char *argv[]) {
|
|||
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_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));
|
||||
|
@ -89,7 +93,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++;
|
||||
|
@ -107,8 +111,8 @@ main (int argc, char *argv[]) {
|
|||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
err_check(cipher_type_alloc(&aes_icm, &c, 46));
|
||||
err_check(cipher_init(c, key, direction_encrypt));
|
||||
err_check(cipher_set_iv(c, &nonce));
|
||||
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));
|
||||
|
@ -123,13 +127,75 @@ 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++;
|
||||
}
|
||||
}
|
||||
|
||||
#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, 30));
|
||||
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, 46));
|
||||
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");
|
||||
|
|
|
@ -88,6 +88,13 @@ extern "C" {
|
|||
*/
|
||||
#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN
|
||||
|
||||
/*
|
||||
* SRTP_AEAD_SALT_LEN is the length of the SALT values used with
|
||||
* GCM mode. GCM mode requires an IV. The SALT value is used
|
||||
* as part of the IV formation logic applied to each RTP packet.
|
||||
*/
|
||||
#define SRTP_AEAD_SALT_LEN 12
|
||||
|
||||
/*
|
||||
* nota bene: since libSRTP doesn't support the use of the MKI, the
|
||||
* SRTP_MAX_TRAILER_LEN value is just the maximum tag length
|
||||
|
@ -663,6 +670,130 @@ void crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p);
|
|||
void
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_cm_256_null_auth() sets a crypto
|
||||
* policy structure to an encryption-only policy
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_cm_256_null_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
* (AES-256 Counter Mode), but to use no authentication method. This
|
||||
* policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5
|
||||
* of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @warning This policy is NOT RECOMMENDED for SRTP unless it is
|
||||
* unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see
|
||||
* Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
void
|
||||
crypto_policy_set_aes_cm_256_null_auth(crypto_policy_t *p);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_gcm_128_8_auth() sets a crypto
|
||||
* policy structure to an AEAD encryption policy.
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_gcm_128_8_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
* (AES-128 Galois Counter Mode) with 8 octet auth tag. This
|
||||
* policy applies confidentiality and authentication to both the
|
||||
* RTP and RTCP packets.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
void
|
||||
crypto_policy_set_aes_gcm_128_8_auth(crypto_policy_t *p);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_gcm_256_8_auth() sets a crypto
|
||||
* policy structure to an AEAD encryption policy
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_gcm_256_8_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
* (AES-256 Galois Counter Mode) with 8 octet auth tag. This
|
||||
* policy applies confidentiality and authentication to both the
|
||||
* RTP and RTCP packets.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
void
|
||||
crypto_policy_set_aes_gcm_256_8_auth(crypto_policy_t *p);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_gcm_128_8_only_auth() sets a crypto
|
||||
* policy structure to an AEAD authentication-only policy
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_gcm_128_8_only_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
* (AES-128 Galois Counter Mode) with 8 octet auth tag. This policy
|
||||
* applies confidentiality and authentication to the RTP packets,
|
||||
* but only authentication to the RTCP packets.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
void
|
||||
crypto_policy_set_aes_gcm_128_8_only_auth(crypto_policy_t *p);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_gcm_256_8_only_auth() sets a crypto
|
||||
* policy structure to an AEAD authentication-only policy
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_gcm_256_8_only_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
* (AES-256 Galois Counter Mode) with 8 octet auth tag. This policy
|
||||
* applies confidentiality and authentication to the RTP packets,
|
||||
* but only authentication to the RTCP packets.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
void
|
||||
crypto_policy_set_aes_gcm_256_8_only_auth(crypto_policy_t *p);
|
||||
|
||||
|
||||
/**
|
||||
* @brief srtp_dealloc() deallocates storage for an SRTP session
|
||||
|
|
|
@ -77,7 +77,7 @@ typedef struct {
|
|||
unsigned m:1; /* marker bit */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#else /* BIG_ENDIAN */
|
||||
|
@ -91,7 +91,7 @@ typedef struct {
|
|||
unsigned pt:7; /* payload type */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#endif
|
||||
|
@ -117,7 +117,7 @@ typedef struct {
|
|||
unsigned version:2; /* protocol version */
|
||||
unsigned pt:8; /* payload type */
|
||||
unsigned len:16; /* length */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
} srtcp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -220,6 +220,8 @@ typedef struct srtp_stream_ctx_t {
|
|||
direction_t direction;
|
||||
int allow_repeat_tx;
|
||||
ekt_stream_t ekt;
|
||||
uint8_t salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTP */
|
||||
uint8_t c_salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTCP */
|
||||
struct srtp_stream_ctx_t *next; /* linked list of streams */
|
||||
} srtp_stream_ctx_t;
|
||||
|
||||
|
|
|
@ -149,10 +149,13 @@ ekt_stream_init_from_policy(ekt_stream_t stream_data, ekt_policy_t policy) {
|
|||
|
||||
void
|
||||
aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len) {
|
||||
#ifndef OPENSSL
|
||||
//FIXME: need to get this working through the crypto module interface
|
||||
aes_expanded_key_t expanded_key;
|
||||
|
||||
aes_expand_decryption_key(key, key_len, &expanded_key);
|
||||
aes_decrypt(ciphertext, &expanded_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -90,8 +90,7 @@
|
|||
#define USEC_RATE (5e5)
|
||||
#define MAX_WORD_LEN 128
|
||||
#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
|
||||
#define MAX_KEY_LEN 64
|
||||
#define MASTER_KEY_LEN 30
|
||||
#define MAX_KEY_LEN 96
|
||||
|
||||
|
||||
#ifndef HAVE_USLEEP
|
||||
|
@ -153,6 +152,8 @@ main (int argc, char *argv[]) {
|
|||
sec_serv_t sec_servs = sec_serv_none;
|
||||
unsigned char ttl = 5;
|
||||
int c;
|
||||
int key_size = 128;
|
||||
int gcm_on = 0;
|
||||
char *input_key = NULL;
|
||||
char *address = NULL;
|
||||
char key[MAX_KEY_LEN];
|
||||
|
@ -187,7 +188,7 @@ main (int argc, char *argv[]) {
|
|||
|
||||
/* check args */
|
||||
while (1) {
|
||||
c = getopt_s(argc, argv, "k:rsaeld:");
|
||||
c = getopt_s(argc, argv, "k:rsgae:ld:");
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
@ -196,11 +197,20 @@ main (int argc, char *argv[]) {
|
|||
input_key = optarg_s;
|
||||
break;
|
||||
case 'e':
|
||||
key_size = atoi(optarg_s);
|
||||
if (key_size != 128 && key_size != 256) {
|
||||
printf("error: encryption key size must be 128 or 256 (%d)\n", key_size);
|
||||
exit(1);
|
||||
}
|
||||
sec_servs |= sec_serv_conf;
|
||||
break;
|
||||
case 'a':
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'g':
|
||||
gcm_on = 1;
|
||||
sec_servs |= sec_serv_auth;
|
||||
break;
|
||||
case 'r':
|
||||
prog_type = receiver;
|
||||
break;
|
||||
|
@ -331,16 +341,73 @@ main (int argc, char *argv[]) {
|
|||
*/
|
||||
switch (sec_servs) {
|
||||
case sec_serv_conf_and_auth:
|
||||
crypto_policy_set_rtp_default(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
if (gcm_on) {
|
||||
#ifdef OPENSSL
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
|
||||
crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
|
||||
crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
crypto_policy_set_rtp_default(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_conf:
|
||||
crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
if (gcm_on) {
|
||||
printf("error: GCM mode must always be used with auth enabled\n");
|
||||
return -1;
|
||||
} else {
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sec_serv_auth:
|
||||
crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
if (gcm_on) {
|
||||
#ifdef OPENSSL
|
||||
switch (key_size) {
|
||||
case 128:
|
||||
crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
|
||||
crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
|
||||
break;
|
||||
case 256:
|
||||
crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
|
||||
crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("error: unknown security service requested\n");
|
||||
|
@ -359,21 +426,21 @@ main (int argc, char *argv[]) {
|
|||
/*
|
||||
* read key from hexadecimal on command line into an octet string
|
||||
*/
|
||||
len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2);
|
||||
len = hex_string_to_octet_string(key, input_key, policy.rtp.cipher_key_len*2);
|
||||
|
||||
/* check that hex string is the right length */
|
||||
if (len < MASTER_KEY_LEN*2) {
|
||||
if (len < policy.rtp.cipher_key_len*2) {
|
||||
fprintf(stderr,
|
||||
"error: too few digits in key/salt "
|
||||
"(should be %d hexadecimal digits, found %d)\n",
|
||||
MASTER_KEY_LEN*2, len);
|
||||
policy.rtp.cipher_key_len*2, len);
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(input_key) > MASTER_KEY_LEN*2) {
|
||||
if (strlen(input_key) > policy.rtp.cipher_key_len*2) {
|
||||
fprintf(stderr,
|
||||
"error: too many digits in key/salt "
|
||||
"(should be %d hexadecimal digits, found %u)\n",
|
||||
MASTER_KEY_LEN*2, (unsigned)strlen(input_key));
|
||||
policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -541,7 +608,8 @@ usage(char *string) {
|
|||
"[-s | -r] dest_ip dest_port\n"
|
||||
"or %s -l\n"
|
||||
"where -a use message authentication\n"
|
||||
" -e use encryption\n"
|
||||
" -e <key size> use encryption (use 128 or 256 for key size)\n"
|
||||
" -g Use AES-GCM mode (must be used with -e)\n"
|
||||
" -k <key> sets the srtp master key\n"
|
||||
" -s act as rtp sender\n"
|
||||
" -r act as rtp receiver\n"
|
||||
|
|
|
@ -10,7 +10,7 @@ DURATION=3
|
|||
|
||||
key=2b2edc5034f61a72345ca5986d7bfd0189aa6dc2ecab32fd9af74df6dfc6
|
||||
|
||||
ARGS="-k $key -ae"
|
||||
ARGS="-k $key -a -e 128"
|
||||
|
||||
# First, we run "killall" to get rid of all existing rtpw processes.
|
||||
# This step also enables this script to clean up after itself; if this
|
||||
|
@ -66,6 +66,55 @@ kill $sender_pid
|
|||
wait $receiver_pid
|
||||
wait $sender_pid
|
||||
|
||||
|
||||
key=033490ba9e82994fc21013395739038992b2edc5034f61a72345ca598d7bfd0189aa6dc2ecab32fd9af74df6dfc6
|
||||
|
||||
ARGS="-k $key -a -e 256"
|
||||
|
||||
echo $0 ": starting rtpw receiver process... "
|
||||
|
||||
$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting rtpw sender process..."
|
||||
|
||||
$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid
|
||||
wait $sender_pid
|
||||
|
||||
echo $0 ": done (test passed)"
|
||||
|
||||
else
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# usage: rtpw_test <rtpw_commands>
|
||||
#
|
||||
# tests the rtpw sender and receiver functions
|
||||
|
||||
RTPW=./rtpw
|
||||
DEST_PORT=9999
|
||||
DURATION=3
|
||||
|
||||
# First, we run "killall" to get rid of all existing rtpw processes.
|
||||
# This step also enables this script to clean up after itself; if this
|
||||
# script is interrupted after the rtpw processes are started but before
|
||||
# they are killed, those processes will linger. Re-running the script
|
||||
# will get rid of them.
|
||||
|
||||
killall rtpw 2>/dev/null
|
||||
|
||||
if test -x $RTPW; then
|
||||
|
||||
GCMARGS128="-k 012345678901234567890123456789012345678901234567890123456789 -g -e 128"
|
||||
echo $0 ": starting GCM mode 128-bit rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 128-bit rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
|
||||
|
||||
GCMARGS256="-k 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901 -g -e 256"
|
||||
echo $0 ": starting GCM mode 256-bit rtpw receiver process... "
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting GCM 256-bit rtpw sender process..."
|
||||
|
||||
exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
|
||||
echo $0 ": done (test passed)"
|
||||
|
||||
else
|
||||
|
||||
echo "error: can't find executable" $RTPW
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
# EOF
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
|
|||
double
|
||||
mips_estimate(int num_trials, int *ignore);
|
||||
|
||||
extern uint8_t test_key[30];
|
||||
extern uint8_t test_key[46];
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
|
@ -288,6 +288,8 @@ main (int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
//FIXME: need to get this working with the OpenSSL AES module
|
||||
#ifndef OPENSSL
|
||||
/*
|
||||
* run validation test against the reference packets for
|
||||
* AES-256
|
||||
|
@ -300,6 +302,7 @@ main (int argc, char *argv[]) {
|
|||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* test the function srtp_remove_stream()
|
||||
|
@ -1527,10 +1530,12 @@ srtp_test_remove_stream() {
|
|||
* srtp policy definitions - these definitions are used above
|
||||
*/
|
||||
|
||||
unsigned char test_key[30] = {
|
||||
unsigned char test_key[46] = {
|
||||
0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
|
||||
0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
|
||||
0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
|
||||
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
|
||||
0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
|
||||
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
|
||||
};
|
||||
|
||||
|
@ -1660,6 +1665,108 @@ const srtp_policy_t hmac_only_policy = {
|
|||
NULL
|
||||
};
|
||||
|
||||
#ifdef OPENSSL
|
||||
const srtp_policy_t aes128_gcm_8_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{ /* SRTP policy */
|
||||
AES_128_GCM, /* cipher type */
|
||||
30, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
{ /* SRTCP policy */
|
||||
AES_128_GCM, /* cipher type */
|
||||
30, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
const srtp_policy_t aes128_gcm_8_cauth_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{ /* SRTP policy */
|
||||
AES_128_GCM, /* cipher type */
|
||||
30, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
{ /* SRTCP policy */
|
||||
AES_128_GCM, /* cipher type */
|
||||
30, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
const srtp_policy_t aes256_gcm_8_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{ /* SRTP policy */
|
||||
AES_256_GCM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
{ /* SRTCP policy */
|
||||
AES_256_GCM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
const srtp_policy_t aes256_gcm_8_cauth_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{ /* SRTP policy */
|
||||
AES_256_GCM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
{ /* SRTCP policy */
|
||||
AES_256_GCM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
NULL_AUTH, /* authentication func type */
|
||||
0, /* auth key length in octets */
|
||||
8, /* auth tag length in octets */
|
||||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
const srtp_policy_t null_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{
|
||||
|
@ -1783,6 +1890,12 @@ policy_array[] = {
|
|||
&aes_tmmh_policy,
|
||||
#endif
|
||||
&default_policy,
|
||||
#ifdef OPENSSL
|
||||
&aes128_gcm_8_policy,
|
||||
&aes128_gcm_8_cauth_policy,
|
||||
&aes256_gcm_8_policy,
|
||||
&aes256_gcm_8_cauth_policy,
|
||||
#endif
|
||||
&null_policy,
|
||||
&aes_256_hmac_policy,
|
||||
&hmac_only_with_ekt_policy,
|
||||
|
|
Loading…
Reference in New Issue