]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Build-System] Update libsrtp to 2.3.0 libsrtp 215/head
authorAndrey Volk <andywolk@gmail.com>
Thu, 9 Jan 2020 13:17:45 +0000 (17:17 +0400)
committerAndrey Volk <andywolk@gmail.com>
Fri, 13 Mar 2020 13:18:41 +0000 (17:18 +0400)
43 files changed:
libs/srtp/Makefile.am
libs/srtp/configure.ac
libs/srtp/crypto/Makefile.in
libs/srtp/crypto/cipher/aes_gcm_nss.c [new file with mode: 0644]
libs/srtp/crypto/cipher/aes_gcm_ossl.c
libs/srtp/crypto/cipher/aes_icm_nss.c [new file with mode: 0644]
libs/srtp/crypto/cipher/aes_icm_ossl.c
libs/srtp/crypto/cipher/cipher.c
libs/srtp/crypto/cipher/null_cipher.c
libs/srtp/crypto/hash/sha1.c
libs/srtp/crypto/include/aes_gcm.h [moved from libs/srtp/crypto/include/aes_gcm_ossl.h with 80% similarity]
libs/srtp/crypto/include/aes_icm_ext.h [moved from libs/srtp/crypto/include/aes_icm_ossl.h with 87% similarity]
libs/srtp/crypto/include/cipher_priv.h [new file with mode: 0644]
libs/srtp/crypto/include/cipher_types.h
libs/srtp/crypto/include/datatypes.h
libs/srtp/crypto/include/err.h
libs/srtp/crypto/kernel/alloc.c
libs/srtp/crypto/kernel/crypto_kernel.c
libs/srtp/crypto/kernel/err.c
libs/srtp/crypto/math/datatypes.c
libs/srtp/crypto/math/stat.c
libs/srtp/crypto/replay/ut_sim.c
libs/srtp/crypto/test/cipher_driver.c
libs/srtp/crypto/test/datatypes_driver.c
libs/srtp/crypto/test/stat_driver.c
libs/srtp/include/srtp.h
libs/srtp/include/srtp_priv.h
libs/srtp/libsrtp.2017.vcxproj
libs/srtp/srtp/ekt.c
libs/srtp/srtp/srtp.c
libs/srtp/test/getopt_s.c
libs/srtp/test/rdbx_driver.c
libs/srtp/test/replay_driver.c
libs/srtp/test/roc_driver.c
libs/srtp/test/rtp.c
libs/srtp/test/rtp_decoder.c
libs/srtp/test/rtp_decoder.h
libs/srtp/test/rtpw.c
libs/srtp/test/rtpw_test.sh
libs/srtp/test/rtpw_test_gcm.sh
libs/srtp/test/srtp_driver.c
libs/srtp/test/test_srtp.c
libs/srtp/test/util.c

index caff627c76e3e9d7410c2f086d07654129e9a1db..3525e2c48a14e43bf220fff3513d4bd0a2c2a533 100644 (file)
@@ -17,7 +17,7 @@ libsrtp_la_SOURCES =    srtp/srtp.c srtp/ekt.c crypto/cipher/cipher.c crypto/cip
                        crypto/kernel/err.c \
                        crypto/replay/rdb.c crypto/replay/rdbx.c crypto/replay/ut_sim.c 
 
-libsrtp_la_LDFLAGS =   -version-info 1:42:1
+libsrtp_la_LDFLAGS =   -version-info 2:3:0
 
 EXTRA_DIST=
 
@@ -29,10 +29,6 @@ libsrtp_la_SOURCES += crypto/hash/sha1.c crypto/hash/hmac.c
 libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c
 endif
 
-if GDOI
-libsrtp_la_SOURCES += gdoi/srtp+gdoi.c
-endif
-
 library_includedir =  $(prefix)/include/srtp
 library_include_HEADERS = include/srtp.h include/ut_sim.h crypto/include/auth.h \
           crypto/include/cipher_types.h \
index 288d0e970a400547ac8c45b76abd68462463473d..021ceeebc56afad7a4f290d357d11a8b7ca5845d 100644 (file)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.59)
-AC_INIT(srtp, 1.4.2, mcgrew@cisco.com)
+AC_INIT(srtp, 2.3.0, mcgrew@cisco.com)
 AC_CONFIG_AUX_DIR(build)
 AM_INIT_AUTOMAKE
 
@@ -11,161 +11,155 @@ LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS"
 AC_LANG_C
 # Checks for programs.
 AC_PROG_CC
-AC_PROG_AWK
-AC_PROG_MAKE_SET
+AC_PROG_CPP
+AC_PROG_CXX
+AC_ARG_VAR(
+  [EXTRA_CFLAGS],
+  [C compiler flags appended to the regular C compiler flags instead of overriding them])
+AM_PROG_AR
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
-AX_COMPILER_VENDOR
+AC_PROG_SED
 
-# Optimization
-AC_ARG_ENABLE(optimization,
-[AC_HELP_STRING([--enable-optimization],[Set if you want us to add max optimising compiler flags])],[enable_optimizer="$enableval"],[enable_optimizer="no"])
-
-if test "${enable_optimizer}" = "yes" ; then
-        AC_DEFINE([OPTIMZER],[],[Enable Optimization.])
-        AX_CC_MAXOPT
-fi
-
-#  Enable debugging
-AC_ARG_ENABLE(debug,
-[AC_HELP_STRING([--enable-debug],[build with debug information])],[enable_debug="$enable_debug"],[enable_debug="yes"])
-
-if test "${enable_debug}" = "yes"; then
-        AC_DEFINE([DEBUG],[],[Enable extra debugging.])
-        AX_CFLAGS_WARN_ALL_ANSI
-fi
+dnl Check the byte order
+AC_C_BIGENDIAN
 
+AC_CANONICAL_HOST
 
-AM_CONDITIONAL([WANT_DEBUG],[test "${enable_debug}" = "yes"])
-
-IN_LINE=inline
-
-case "$host" in
-                *-solaris2*)
-                        if test "x${ax_cv_c_compiler_vendor}"  = "xsun" ; then
-                                SOLINK="-Bdynamic -dy -G"
-                                new_AM_CFLAGS="-KPIC -DPIC"
-                                new_AM_LDFLAGS="-R${prefix}/lib"
-                                FUNC_DEF=__func__
-                                IN_LINE=""
-                        elif test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
-                                SOLINK="-Bdynamic -dy -G"
-                                new_AM_CFLAGS="-fPIC -Wall -O4 -fexpensive-optimizations -funroll-loops"
-                                new_AM_LDFLAGS=""
-                                IN_LINE=inline
-                        fi
-                ;;
-                *-darwin*)
-                        if test "x${ax_cv_c_compiler_vendor}"="xgnu" ; then
-                                SOLINK="-dynamic -bundle -force-flat-namespace"
-                                new_AM_CFLAGS="-DMACOSX"
-                                new_AM_LDFLAGS=""
-                        fi
-                ;;
-                x86_64-*-linux-gnu)
-                        if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
-                                SOLINK="-Bdynamic -dy -G"
-                                new_AM_CFLAGS="-KPIC -DPIC"
-                                new_AM_LDFLAGS="-R${prefix}/lib"
-                                FUNC_DEF=__func__
-                        elif test "x${ax_cv_c_compiler_vendor}"="xgnu" ; then
-                               SOLINK="-shared -Xlinker -x"
-                                new_AM_CFLAGS="-fPIC -Wall -O4 -fexpensive-optimizations -funroll-loops"
-                                new_AM_LDFLAGS=""
-                        fi
-                ;;
-                i*6-*-linux-gnu)
-                        if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then
-                                SOLINK="-Bdynamic -dy -G"
-                                new_AM_CFLAGS="-KPIC -DPIC"
-                                new_AM_LDFLAGS="-R${prefix}/lib"
-                                FUNC_DEF=__func__
-                        elif test "x${ax_cv_c_compiler_vendor}"="xgnu" ; then
-                                SOLINK="-shared -Xlinker -x"
-                                new_AM_CFLAGS="-fpic -Wall -O4 -fexpensive-optimizations -funroll-loops"
-                                new_AM_LDFLAGS=""
-                        fi
-                ;;
-               i*6*-*-freebsd*)
-                        SOLINK="-shared -Xlinker -x"
-                        new_AM_CFLAGS="-fPIC -Wall -O4 -fexpensive-optimizations -funroll-loops"
-                        new_AM_LDFLAGS=""
-               ;;
-               x86_64-*-freebsd*|amd64-*-freebsd*)
-                        SOLINK="-shared -Xlinker -x"
-                        new_AM_CFLAGS="-fPIC -Wall -O4 -fexpensive-optimizations -funroll-loops"
-                        new_AM_LDFLAGS=""
-               ;;
+dnl check host_cpu type, set defines appropriately
+case $host_cpu in
+  i*86 | x86_64 )
+    AC_DEFINE([CPU_CISC], [1], [Define if building for a CISC machine (e.g. Intel).])
+    AC_DEFINE([HAVE_X86], [1], [Define to use X86 inlined assembly code])
+    ;;
+  * )
+    AC_DEFINE([CPU_RISC], [1], [Define if building for a RISC machine (assume slow byte access).])
+    ;;
 esac
 
-#  Enable 64 bit build
-AC_ARG_ENABLE(64,
-[AC_HELP_STRING([--enable-64],[build with 64 bit support])],[enable_64="$enable_64"],[enable_64="no"])
+dnl Check if we are on a Windows platform.
+case $host_os in
+  *cygwin*|*mingw* )
+    EXE=.exe
+    ;;
+  * )
+    EXE=""
+    ;;
+esac
+AC_SUBST([EXE])   # define executable suffix; this is needed for `make clean'
 
-if test "x${ax_cv_c_compiler_vendor}"  =  "xsun" ; then
-    if test "${enable_64}" = "yes"; then
-        new_AM_CFLAGS="$new_AM_CFLAGS -m64"
-    fi
+dnl Checks for supported compiler flags.
+supported_cflags=""
+if test "$EMPTY_CFLAGS" = "no"; then
+  supported_cflags="$CFLAGS"
 fi
 
-AC_SUBST(new_AM_CFLAGS)
-AC_SUBST(new_AM_LDFLAGS)
-AC_SUBST(SOLINK)
-if test "x$FUNC_DEF" != "x"; then
-   AC_DEFINE_UNQUOTED([__FUNCTION__],[$FUNC_DEF],[define it the right way ;)])
-fi
-AC_DEFINE_UNQUOTED([inline],[$IN_LINE],[sunpro is bad at inline])
-
-
-AC_ARG_ENABLE(kernel-linux,
-  [AS_HELP_STRING([--enable-kernel-linux],
-                 [build library to run in Linux kernel context])],
-  [], enable_kernel_linux=no)
-AC_MSG_CHECKING(whether to build for Linux kernel context)
-if test "$enable_kernel_linux" = "yes"; then
-   AC_DEFINE(SRTP_KERNEL, 1,
-       [Define to compile for kernel contexts.])
-   AC_DEFINE(SRTP_KERNEL_LINUX, 1,
-       [Define to compile for Linux kernel context.])
+dnl For accurate detection, we need warnings as errors.
+dnl I.e. Clang will issue a warning about unsupported flags.
+dnl For the compilation to fail, those warnings needs to be upgraded to errors.
+dnl This will be removed again once the tests are complete (see below).
+WERROR=""
+for w in -Werror -errwarn; do
+  if test "x$WERROR" = "x"; then
+    AC_MSG_CHECKING([whether ${CC-c} accepts $w])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$w"], [CFLAGS="$CFLAGS $w"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [WERROR="$w"
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  fi
+done
+
+dnl Note that -fPIC is not explicitly added to LDFLAGS.
+dnl Since the compiler is used as the link driver, CFLAGS will be part of the
+dnl link line as well and the linker will get the flag from there.
+dnl Adding it to LDFLAGS explicitly would duplicate the flag on the link line,
+dnl but otherwise do no harm.
+AC_MSG_CHECKING([whether ${CC-c} accepts -fPIC])
+save_cflags="$CFLAGS"
+AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="-fPIC"], [CFLAGS="$CFLAGS -fPIC"])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+  [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="-fPIC"], [supported_cflags="$supported_cflags -fPIC"])
+   AC_MSG_RESULT([yes])],
+  [CFLAGS="$save_cflags"
+   AC_MSG_RESULT([no])])
+
+if test "$EMPTY_CFLAGS" = "yes"; then
+  for f in -Wall -pedantic -Wstrict-prototypes; do
+    AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  done
+
+  OOPT=""
+  for f in -O4 -O3; do
+    if test "x$OOPT" = "x"; then
+      AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+      save_cflags="$CFLAGS"
+      AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+        [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+         OOPT="$f"
+         AC_MSG_RESULT([yes])],
+        [CFLAGS="$save_cflags"
+         AC_MSG_RESULT([no])])
+    fi
+  done
+
+  for f in -fexpensive-optimizations -funroll-loops; do
+    AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  done
 fi
-AC_MSG_RESULT($enable_kernel_linux)
 
-dnl Check for /dev/urandom
-AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom,
-   [AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])
+dnl When turning off warnigns, we're expecting unrecognized command line option errors if they're not
+dnl supported. However, the -Wno-<warning> form isn't consulted unless a warning is triggered.
+dnl At least that's the case for GCC. So to check which warnings we can turn off, we need to check
+dnl if they can be turned on, thereby forcing GCC to take the argument into account right away.
+for f in -Wno-language-extension-token; do
+  AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+  save_cflags="$CFLAGS"
+  testf=$(echo "$f" | $SED 's|-Wno-\(.*\)|-W\1|g')
+  AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$testf"], [CFLAGS="$CFLAGS $testf"])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+    [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+     AC_MSG_RESULT([yes])],
+    [CFLAGS="$save_cflags"
+     AC_MSG_RESULT([no])])
+done
+
+dnl Remowing -Werror again
+CFLAGS="$supported_cflags"
 
 dnl Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS(stdlib.h)
-AC_CHECK_HEADERS(unistd.h)
-AC_CHECK_HEADERS(stdint.h)
-AC_CHECK_HEADERS(sys/uio.h)
-AC_CHECK_HEADERS(inttypes.h)
-AC_CHECK_HEADERS(sys/types.h)
-AC_CHECK_HEADERS(machine/types.h)
-AC_CHECK_HEADERS(sys/int_types.h)
-
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
-#include <inttypes.h>
-#include <byteswap.h>
-]],[[
-uint64_t y = 0x1122334455667788LL;
-bswap_64(y);
-]])],byteswap_cv_bswap_64_usable=yes,byteswap_cv_bswap_64_usable=no)
-
-if test "x${byteswap_cv_bswap_64_usable}" = "xyes" ; then
-AC_DEFINE([HAVE_BYTESWAP_H],1,[define if you have a usable bswap_64 in byteswap.h])
-fi
+AC_CHECK_HEADERS(
+    [unistd.h byteswap.h stdint.h sys/uio.h inttypes.h sys/types.h machine/types.h sys/int_types.h],
+    [], [], [AC_INCLUDES_DEFAULT])
 
 dnl socket() and friends
-AC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h)
-AC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)])
-
-AC_CHECK_HEADERS(syslog.h)
+AC_CHECK_HEADERS([sys/socket.h netinet/in.h arpa/inet.h], [], [], [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS(
+    [windows.h],
+    [AC_CHECK_HEADERS([winsock2.h], [], [], [AC_INCLUDES_DEFAULT])],
+    [], [AC_INCLUDES_DEFAULT])
 
-AC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t])
-AC_CHECK_SIZEOF(unsigned long)
-AC_CHECK_SIZEOF(unsigned long long)
+AC_CHECK_TYPES([int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, uint64_t])
+AC_CHECK_SIZEOF([unsigned long])
+AC_CHECK_SIZEOF([unsigned long long])
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -173,176 +167,267 @@ AC_C_INLINE
 AC_TYPE_SIZE_T
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(socket inet_aton usleep sigaction)
+AC_CHECK_FUNCS([socket inet_aton usleep sigaction])
 
 dnl Find socket function if not found yet.
 if test "x$ac_cv_func_socket" = "xno"; then
-  AC_CHECK_LIB(socket, socket)
+  AC_CHECK_LIB([socket], [socket])
   AC_MSG_CHECKING([for socket in -lwsock32])
   SAVELIBS="$LIBS"
   LIBS="$LIBS -lwsock32"
-  AC_TRY_LINK([
+  AC_LINK_IFELSE(
+    [AC_LANG_SOURCE([
 #include <winsock2.h>
-],[
-socket(0, 0, 0);
-],
-    ac_cv_func_socket=yes
-    AC_MSG_RESULT(yes),
-    LIBS="$SAVELIBS"
-    AC_MSG_RESULT(no))
+int main(void)
+{
+    int fd = socket(0, 0, 0);
+    if (fd < 0)
+      return -1;
+    else
+      return 0;
+}
+    ])],
+    [ac_cv_func_socket=yes
+     AC_MSG_RESULT([yes])],
+    [LIBS="$SAVELIBS"
+     AC_MSG_RESULT([no])])
 fi
 
-dnl Check the byte order
-AC_C_BIGENDIAN
+AC_MSG_CHECKING([whether to enable debug logging in all modules])
+AC_ARG_ENABLE([debug-logging],
+  [AS_HELP_STRING([--enable-debug-logging], [Enable debug logging in all modules])],
+  [], enable_debug_logging=no)
+if test "$enable_debug_logging" = "yes"; then
+   AC_DEFINE([ENABLE_DEBUG_LOGGING], [1], [Define to enabled debug logging for all mudules.])
+fi
+AC_MSG_RESULT([$enable_debug_logging])
 
+PKG_PROG_PKG_CONFIG
+AS_IF([test "x$PKG_CONFIG" != "x"], [PKG_CONFIG="$PKG_CONFIG --static"])
 
-dnl check host_cpu type, set defines appropriately
-case $host_cpu in
-     i*86 | x86_64 )
-       AC_DEFINE(CPU_CISC, 1,
-          [Define if building for a CISC machine (e.g. Intel).])
-       # Do not enable use of asm for MACOSX
-        if test "x$new_AM_CFLAGS" != "x-DMACOSX"; then 
-         AC_DEFINE(HAVE_X86, 1,
-          [Define to use X86 inlined assembly code]) 
-       fi
-       ;;
-       * )
-       # CPU_RISC is only supported for big endian machines.
-       if test "$ac_cv_c_bigendian" = "yes"; then
-          AC_DEFINE(CPU_RISC, 1,
-           [Define if building for a RISC machine (assume slow byte access).])
-       else
-          AC_DEFINE(CPU_CISC, 1)
-       fi
-       ;;
-esac   
-
-dnl Check if we're on a Windows platform.
-case $host_os in
-  *cygwin*|*mingw* ) 
-             EXE=.exe;;
-         * )  EXE="";;
-esac
-
-AC_SUBST(EXE)   # define executable suffix; this is needed for `make clean'
+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])
+AC_MSG_RESULT([$enable_openssl])
 
-AC_MSG_CHECKING(whether to compile in debugging)
-AC_ARG_ENABLE(debug,
-  [AS_HELP_STRING([--disable-debug],
-                 [do not compile in dynamic debugging system])],
-  [], enable_debug=yes)
-if test "$enable_debug" = "yes"; then
-   AC_DEFINE(ENABLE_DEBUGGING, 1,
-      [Define to compile in dynamic debugging system.])
-fi
-AC_MSG_RESULT($enable_debug)
-
-AC_MSG_CHECKING(whether to use ISMAcryp code)
-AC_ARG_ENABLE(generic-aesicm,
-  [AS_HELP_STRING([--enable-generic-aesicm],
-                 [compile in changes for ISMAcryp])],
-  [], enable_generic_aesicm=no)
-if test "$enable_generic_aesicm" = "yes"; then
-   AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.])
-fi
-AC_MSG_RESULT($enable_generic_aesicm)
+AC_MSG_CHECKING([whether to leverage NSS crypto])
+AC_ARG_ENABLE([nss],
+  [AS_HELP_STRING([--enable-nss], [compile in NSS crypto engine])],
+  [], [enable_nss=no])
+AC_MSG_RESULT([$enable_nss])
 
-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.])
+   AC_MSG_CHECKING([for user specified OpenSSL directory])
+   AC_ARG_WITH([openssl-dir],
+      [AS_HELP_STRING([--with-openssl-dir], [Location of OpenSSL installation])],
+      [if test "x$PKG_CONFIG" != "x" && test -f $with_openssl_dir/lib/pkgconfig/libcrypto.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         AC_MSG_RESULT([$with_openssl_dir])
+       elif test -d $with_openssl_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_openssl_dir/include"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_openssl_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_openssl_dir/lib"
+         fi
+         AC_MSG_RESULT([$with_openssl_dir])
+       else
+         AC_MSG_RESULT([invalid])
+         AC_MSG_FAILURE([Invalid OpenSSL location: $with_openssl_dir])
+       fi],
+      [AC_MSG_RESULT([no])])
+
+   if test "x$PKG_CONFIG" != "x"; then
+     PKG_CHECK_MODULES([crypto], [libcrypto >= 1.0.1],
+       [CFLAGS="$CFLAGS $crypto_CFLAGS"
+        LIBS="$crypto_LIBS $LIBS"])
+   else
+     AC_CHECK_LIB([dl], [dlopen], [], [AC_MSG_WARN([can't find libdl])])
+     AC_CHECK_LIB([z], [inflate], [], [AC_MSG_WARN([can't find libz])])
+   fi
+
+   AC_SEARCH_LIBS([EVP_EncryptInit], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+   AC_SEARCH_LIBS([EVP_aes_128_ctr], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+   AC_SEARCH_LIBS([EVP_aes_128_gcm], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+
+   AC_DEFINE([GCM], [1], [Define this to use AES-GCM.])
+   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"
    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
-      AC_MSG_RESULT([Linux kernel builtin])
+   AC_SUBST([USE_EXTERNAL_CRYPTO], [1])
+
+   AC_MSG_CHECKING([if OPENSSL_cleanse is broken])
+   AC_RUN_IFELSE([AC_LANG_PROGRAM([
+     #include <stdio.h>
+     #include <openssl/crypto.h>
+   ], [
+     #define BUFFER_SIZE (16)
+     char buffer[[BUFFER_SIZE]];
+     int i;
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       buffer[[i]] = i & 0xff;
+     }
+     OPENSSL_cleanse(buffer, BUFFER_SIZE);
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       if (buffer[[i]]) {
+         printf("Buffer contents not zero at position %d (is %d)\n", i,
+             buffer[[i]]);
+         return 1;
+       }
+     }
+   ])], [openssl_cleanse_broken=no], [
+     openssl_cleanse_broken=yes
+     AC_DEFINE([OPENSSL_CLEANSE_BROKEN], [1], [Define this if OPENSSL_cleanse is broken.])
+   ])
+   AC_MSG_RESULT([$openssl_cleanse_broken])
+
+   AC_MSG_CHECKING([whether to leverage OpenSSL KDF algorithm])
+   AC_ARG_ENABLE([openssl-kdf],
+      [AS_HELP_STRING([--enable-openssl-kdf], [Use OpenSSL KDF algorithm])],
+      [], [enable_openssl_kdf=no])
+   AC_MSG_RESULT([$enable_openssl_kdf])
+   if test "$enable_openssl_kdf" = "yes"; then
+     AC_SEARCH_LIBS([kdf_srtp], [crypto],
+       [], [AC_MSG_FAILURE([can't find openssl KDF lib])])
+     AC_DEFINE([OPENSSL_KDF], [1], [Define this to use OpenSSL KDF for SRTP.])
+   fi
+elif test "$enable_nss" = "yes"; then
+   AC_MSG_CHECKING([for user specified NSS directory])
+   AC_ARG_WITH([nss-dir],
+      [AS_HELP_STRING([--with-nss-dir], [Location of NSS installation])],
+      [if test "x$PKG_CONFIG" != "x" && test -f $with_nss_dir/lib/pkgconfig/nss.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         AC_MSG_RESULT([$with_nss_dir])
+       elif test -d $with_nss_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_nss_dir/include"
+         CFLAGS="$CFLAGS -I$with_nss_dir/../public/nss"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_nss_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_nss_dir/lib"
+         fi
+         nss_skip_pkg_config=yes
+         AC_MSG_RESULT([$with_nss_dir])
+       else
+         AC_MSG_RESULT([invalid])
+         AC_MSG_FAILURE([Invalid NSS location: $with_nss_dir])
+       fi
+       AC_SUBST([CRYPTO_LIBDIR], [$with_nss_dir/lib])],
+      [AC_MSG_RESULT([no])])
+
+   if test "x$PKG_CONFIG" != "x" && test "$nss_skip_pkg_config" != "yes"; then
+     PKG_CHECK_MODULES([nss], [nss],
+       [CFLAGS="$CFLAGS $nss_CFLAGS"
+         LIBS="$nss_LIBS $LIBS"])
    else
-      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
+     AC_CHECK_HEADERS(
+       [nss.h],
+       [], [AC_MSG_FAILURE([can't find useable NSS headers])],
+       [AC_INCLUDES_DEFAULT])
+     AC_CHECK_LIB(
+       [nspr4], [PR_GetError],
+       [], [AC_MSG_WARN([can't find libnspr4])])
+     AC_CHECK_LIB(
+       [nss3], [NSS_NoDB_Init],
+       [], [AC_MSG_FAILURE([can't find useable libnss3])])
    fi
+
+   AC_DEFINE([GCM], [1], [Define this to use AES-GCM.])
+   AC_DEFINE([NSS], [1], [Define this to use NSS crypto.])
+   AES_ICM_OBJS="crypto/cipher/aes_icm_nss.o crypto/cipher/aes_gcm_nss.o"
+
+   # TODO(RLB): Use NSS for HMAC
+   HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
+
+   # TODO(RLB): Use NSS for KDF
+
+   AC_SUBST([USE_EXTERNAL_CRYPTO], [1])
+else
+   AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o"
    HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
 fi
 AM_CONDITIONAL([ENABLE_OPENSSL],[test "${enable_openssl}" = "yes"])
 
-AC_SUBST(AES_ICM_OBJS)                              
-AC_SUBST(HMAC_OBJS)
+AC_SUBST([AES_ICM_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])],
-  [], enable_syslog=no)
-if test "$enable_syslog" = "yes"; then
-   AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.])
+dnl Checking for PCAP
+
+PCAP_LIB=""
+AC_ARG_ENABLE([pcap], AS_HELP_STRING([--disable-pcap], [Build without `pcap' library (-lpcap)]))
+AS_IF([test "x$enable_pcap" != "xno"], [
+  AC_CHECK_LIB([pcap], [pcap_create],
+    [PCAP_LIB="-lpcap"
+     AC_DEFINE([HAVE_PCAP], [1], [Define to 1 if you have the `pcap' library (-lpcap)])
+     AC_SUBST([HAVE_PCAP], [1])])
+
+  AC_CHECK_LIB([wpcap], [pcap_create],
+    [PCAP_LIB="-lwpcap"
+     AC_DEFINE([HAVE_PCAP], [1], [Define to 1 if you have the `winpcap' library (-lwpcap)])
+     AC_SUBST([HAVE_PCAP], [1])])
+])
+AC_SUBST([PCAP_LIB])
+   
+AC_MSG_CHECKING([whether to redirect logging to stdout])
+AC_ARG_ENABLE([log-stdout],
+  [AS_HELP_STRING([--enable-log-stdout], [redirecting logging to stdout])],
+  [], [enable_log_stdout=no])
+if test "$enable_log_stdout" = "yes"; then
+   AC_DEFINE([ERR_REPORTING_STDOUT], [1], [Define to redirect logging to stdout.])
 fi
-AC_MSG_RESULT($enable_syslog)
-
-AC_MSG_CHECKING(whether to use stdout for error reporting)
-AC_ARG_ENABLE(stdout,
-  [AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])],
-  [], enable_stdout=yes)
-if test "$enable_stdout" = "yes"; then
-   AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.])
-fi
-AC_MSG_RESULT($enable_stdout)
-
-AC_MSG_CHECKING(whether to use /dev/console for error reporting)
-AC_ARG_ENABLE(console,
-  [AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])],
-  [], enable_console=no)
-if test "$enable_console" = "yes"; then
-   AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file])
-   AC_DEFINE(ERR_REPORTING_FILE, "/dev/console", [Report errors to this file.])
-fi
-AC_MSG_RESULT($enable_console)
-
-AC_MSG_CHECKING(whether to use GDOI key management)
-AC_ARG_ENABLE(gdoi,
-  [AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])],
-  [], enable_gdoi=no)
-if test "$enable_gdoi" = "yes"; then
-   AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.])
-   GDOI_OBJS=gdoi/srtp+gdoi.o
-   AC_SUBST(GDOI_OBJS)                              
-fi
-AC_MSG_RESULT($enable_gdoi)
-AM_CONDITIONAL([GDOI],[test "SRTP_GDOI" = "1"])
-
-AC_CONFIG_HEADERS(crypto/include/config.h:config_in.h)
-
-AC_OUTPUT(Makefile crypto/Makefile doc/Makefile test/Makefile libsrtp2.pc)
+AC_MSG_RESULT([$enable_log_stdout])
+
+AC_MSG_CHECKING([wheather to use a file for logging])
+AC_ARG_WITH([log-file],
+  [AS_HELP_STRING([--with-log-file], [Use file for logging])],
+  [AS_CASE([x$with_log_file],
+     [x], [valid_with_log_file="no"],
+     [xyes], [valid_with_log_file="no"],
+     [valid_with_error_file="yes"])
+   AS_IF([test "$valid_with_log_file" = "no"],
+     [AC_MSG_RESULT([invalid])
+      AC_MSG_FAILURE([Invalid value for --with-log-file: "$with_log_file"])],
+     [AC_DEFINE_UNQUOTED([ERR_REPORTING_FILE], ["$with_log_file"], [Logging statments will be writen to this file.])
+      AC_MSG_RESULT([using log file: "$with_log_file"])])],
+  [AC_MSG_RESULT([no])])
+
+AS_IF(
+  [test "$enable_log_stdout" = "yes" && test "x$with_log_file" != "x"],
+  [AC_MSG_FAILURE([Can only use one of --enable-log-stdout and --with-log-file; they are mutually exclusive])])
+
+dnl Appending EXTRA_CFLAGS, if given
+AC_MSG_CHECKING([for extra C compiler flags])
+AS_IF([test "x$EXTRA_CFLAGS" != "x"],
+   [AS_IF([test "x$CFLAGS" = "x"],
+      [CFLAGS="$EXTRA_CFLAGS"], [CFLAGS="$CFLAGS $EXTRA_CFLAGS"])
+    AC_MSG_RESULT([$EXTRA_CFLAGS])],
+   [AC_MSG_RESULT(no)])
+
+AC_CONFIG_HEADERS([crypto/include/config.h:config_in.h])
+
+AC_CONFIG_FILES([Makefile crypto/Makefile doc/Makefile test/Makefile libsrtp2.pc])
+AC_OUTPUT
 
 # This is needed when building outside the source dir.
-AS_MKDIR_P(crypto/cipher)
-AS_MKDIR_P(crypto/hash)
-AS_MKDIR_P(crypto/kernel)
-AS_MKDIR_P(crypto/math)
-AS_MKDIR_P(crypto/replay)
-AS_MKDIR_P(crypto/test)
-AS_MKDIR_P(doc)
-AS_MKDIR_P(srtp)
-AS_MKDIR_P(tables)
-AS_MKDIR_P(test)
+AS_MKDIR_P([crypto/cipher])
+AS_MKDIR_P([crypto/hash])
+AS_MKDIR_P([crypto/kernel])
+AS_MKDIR_P([crypto/math])
+AS_MKDIR_P([crypto/replay])
+AS_MKDIR_P([crypto/test])
+AS_MKDIR_P([doc])
+AS_MKDIR_P([srtp])
+AS_MKDIR_P([test])
index faaa991a09fa5976bc1ee5974974c21fcc202b4c..44f29ad2cf1e17737a53e4d1dfefb707aef1bcbb 100644 (file)
@@ -17,15 +17,34 @@ LIBS        = @LIBS@
 LDFLAGS        = @LDFLAGS@ -L. -L..
 COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
 CRYPTOLIB = -lsrtp2
+CRYPTO_LIBDIR = @CRYPTO_LIBDIR@
 
 RANLIB = @RANLIB@
 
+# Specify how tests should find shared libraries on macOS and Linux
+#
+# macOS purges DYLD_LIBRARY_PATH when spawning subprocesses, so it's
+# not possible to pass this in from the outside; we have to specify
+# it for any subprocesses we call. No support for dynamic linked
+# tests on Windows.
+ifneq ($(strip $(CRYPTO_LIBDIR)),)
+       ifneq ($(OS),Windows_NT)
+               UNAME_S = $(shell uname -s)
+               ifeq ($(UNAME_S),Linux)
+                       FIND_LIBRARIES = LD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+               endif
+               ifeq ($(UNAME_S),Darwin)
+                       FIND_LIBRARIES = DYLD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+               endif
+       endif
+endif
+
 # EXE defines the suffix on executables - it's .exe for cygwin, and
 # null on linux, bsd, and OS X and other OSes.  we define this so that
 # `make clean` will work on the cygwin platform
 EXE = @EXE@
 # Random source.
-USE_OPENSSL = @USE_OPENSSL@
+USE_EXTERNAL_CRYPTO = @USE_EXTERNAL_CRYPTO@
 
 ifdef ARCH
   DEFS += -D$(ARCH)=1
@@ -40,7 +59,7 @@ endif
 dummy : all runtest
 
 # test applications
-ifneq (1, $(USE_OPENSSL))
+ifneq (1, $(USE_EXTERNAL_CRYPTO))
 AES_CALC = test/aes_calc$(EXE)
 endif
 
@@ -62,17 +81,17 @@ c256=8ea2b7ca516745bfeafc49904b496089
 
 
 runtest: $(testapp)
-       test/env$(EXE) # print out information on the build environment
+       $(FIND_LIBRARIES) test/env$(EXE) # print out information on the build environment
        @echo "running crypto test applications..."
-ifneq (1, $(USE_OPENSSL))
-       test `test/aes_calc $(k128) $(p128)` = $(c128)
-       test `test/aes_calc $(k256) $(p256)` = $(c256)
+ifneq (1, $(USE_EXTERNAL_CRYPTO))
+       $(FIND_LIBRARIES) test `test/aes_calc $(k128) $(p128)` = $(c128)
+       $(FIND_LIBRARIES) 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
+       $(FIND_LIBRARIES) test/cipher_driver$(EXE) -v >/dev/null
+       $(FIND_LIBRARIES) test/datatypes_driver$(EXE) -v >/dev/null
+       $(FIND_LIBRARIES) test/stat_driver$(EXE) >/dev/null
+       $(FIND_LIBRARIES) test/sha1_driver$(EXE) -v >/dev/null
+       $(FIND_LIBRARIES) test/kernel_driver$(EXE) -v >/dev/null
        @echo "crypto test applications passed."
 
 
diff --git a/libs/srtp/crypto/cipher/aes_gcm_nss.c b/libs/srtp/crypto/cipher/aes_gcm_nss.c
new file mode 100644 (file)
index 0000000..54547cd
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * aes_gcm_nss.c
+ *
+ * AES Galois Counter Mode
+ *
+ * Richard L. Barnes
+ * Cisco Systems, Inc.
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "aes_gcm.h"
+#include "alloc.h"
+#include "err.h" /* for srtp_debug */
+#include "crypto_types.h"
+#include "cipher_types.h"
+#include <secerr.h>
+#include <nspr.h>
+
+srtp_debug_module_t srtp_mod_aes_gcm = {
+    0,            /* debugging is off by default */
+    "aes gcm nss" /* printable module name       */
+};
+
+/*
+ * For now we only support 8 and 16 octet tags.  The spec allows for
+ * optional 12 byte tag, which may be supported in the future.
+ */
+#define GCM_IV_LEN 12
+#define GCM_AUTH_TAG_LEN 16
+#define GCM_AUTH_TAG_LEN_8 8
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 28 or 44 for
+ * AES-128-GCM or AES-256-GCM respectively.  Note that the
+ * key length includes the 14 byte salt value that is used when
+ * initializing the KDF.
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_alloc(srtp_cipher_t **c,
+                                                int key_len,
+                                                int tlen)
+{
+    srtp_aes_gcm_ctx_t *gcm;
+    NSSInitContext *nss;
+
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d",
+                key_len);
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
+
+    /*
+     * Verify the key_len is valid for one of: AES-128/256
+     */
+    if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
+        return (srtp_err_status_bad_param);
+    }
+
+    if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
+        return (srtp_err_status_bad_param);
+    }
+
+    /* Initialize NSS equiv of NSS_NoDB_Init(NULL) */
+    nss = NSS_InitContext("", "", "", "", NULL,
+                          NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
+                              NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
+                              NSS_INIT_OPTIMIZESPACE);
+    if (!nss) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* allocate memory a cipher of type aes_gcm */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        NSS_ShutdownContext(nss);
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
+    if (gcm == NULL) {
+        NSS_ShutdownContext(nss);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm->nss = nss;
+
+    /* set pointers */
+    (*c)->state = gcm;
+
+    /* setup cipher attributes */
+    switch (key_len) {
+    case SRTP_AES_GCM_128_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_128;
+        (*c)->algorithm = SRTP_AES_GCM_128;
+        gcm->key_size = SRTP_AES_128_KEY_LEN;
+        gcm->tag_size = tlen;
+        gcm->params.ulTagBits = 8 * tlen;
+        break;
+    case SRTP_AES_GCM_256_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_256;
+        (*c)->algorithm = SRTP_AES_GCM_256;
+        gcm->key_size = SRTP_AES_256_KEY_LEN;
+        gcm->tag_size = tlen;
+        gcm->params.ulTagBits = 8 * tlen;
+        break;
+    default:
+        /* this should never hit, but to be sure... */
+        return (srtp_err_status_bad_param);
+    }
+
+    /* set key size and tag size*/
+    (*c)->key_len = key_len;
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function deallocates a GCM session
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_gcm_ctx_t *ctx;
+
+    ctx = (srtp_aes_gcm_ctx_t *)c->state;
+    if (ctx) {
+        /* release NSS resources */
+        if (ctx->key) {
+            PK11_FreeSymKey(ctx->key);
+        }
+
+        if (ctx->nss) {
+            NSS_ShutdownContext(ctx->nss);
+            ctx->nss = NULL;
+        }
+
+        /* zeroize the key material */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_nss_context_init(...) initializes the aes_gcm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_context_init(void *cv,
+                                                       const uint8_t *key)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    c->dir = srtp_direction_any;
+
+    debug_print(srtp_mod_aes_gcm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+
+    if (c->key) {
+        PK11_FreeSymKey(c->key);
+        c->key = NULL;
+    }
+
+    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_AES_GCM, NULL);
+    if (!slot) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    SECItem key_item = { siBuffer, (unsigned char *)key, c->key_size };
+    c->key = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
+                               CKA_ENCRYPT, &key_item, NULL);
+    PK11_FreeSlot(slot);
+
+    if (!c->key) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_nss_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_set_iv(
+    void *cv,
+    uint8_t *iv,
+    srtp_cipher_direction_t direction)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    if (direction != srtp_direction_encrypt &&
+        direction != srtp_direction_decrypt) {
+        return (srtp_err_status_bad_param);
+    }
+    c->dir = direction;
+
+    debug_print(srtp_mod_aes_gcm, "setting iv: %s",
+                srtp_octet_string_hex_string(iv, GCM_IV_LEN));
+
+    memcpy(c->iv, iv, GCM_IV_LEN);
+
+    return (srtp_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
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_set_aad(void *cv,
+                                                  const uint8_t *aad,
+                                                  uint32_t aad_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
+                srtp_octet_string_hex_string(aad, aad_len));
+
+    if (aad_len + c->aad_size > MAX_AD_SIZE) {
+        return srtp_err_status_bad_param;
+    }
+
+    memcpy(c->aad + c->aad_size, aad, aad_len);
+    c->aad_size += aad_len;
+
+    return (srtp_err_status_ok);
+}
+
+static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv,
+                                                    int encrypt,
+                                                    unsigned char *buf,
+                                                    unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    c->params.pIv = c->iv;
+    c->params.ulIvLen = GCM_IV_LEN;
+    c->params.pAAD = c->aad;
+    c->params.ulAADLen = c->aad_size;
+
+    // Reset AAD
+    c->aad_size = 0;
+
+    int rv;
+    SECItem param = { siBuffer, (unsigned char *)&c->params,
+                      sizeof(CK_GCM_PARAMS) };
+    if (encrypt) {
+        rv = PK11_Encrypt(c->key, CKM_AES_GCM, &param, buf, enc_len,
+                          *enc_len + 16, buf, *enc_len);
+    } else {
+        rv = PK11_Decrypt(c->key, CKM_AES_GCM, &param, buf, enc_len, *enc_len,
+                          buf, *enc_len);
+    }
+
+    srtp_err_status_t status = (srtp_err_status_ok);
+    if (rv != SECSuccess) {
+        status = (srtp_err_status_cipher_fail);
+    }
+
+    return status;
+}
+
+/*
+ * This function encrypts a buffer using AES GCM mode
+ *
+ * XXX(rlb@ipv.sx): We're required to break off and cache the tag
+ * here, because the get_tag() method is separate and the tests expect
+ * encrypt() not to change the size of the plaintext.  It might be
+ * good to update the calling API so that this is cleaner.
+ *
+ * Parameters:
+ *     c       Crypto context
+ *     buf     data to encrypt
+ *     enc_len length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_encrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    // When we get a non-NULL buffer, we know that the caller is
+    // prepared to also take the tag.  When we get a NULL buffer,
+    // even though there's no data, we need to give NSS a buffer
+    // where it can write the tag.  We can't just use c->tag because
+    // memcpy has undefined behavior on overlapping ranges.
+    unsigned char tagbuf[16];
+    unsigned char *non_null_buf = buf;
+    if (!non_null_buf && (*enc_len == 0)) {
+        non_null_buf = tagbuf;
+    } else if (!non_null_buf) {
+        return srtp_err_status_bad_param;
+    }
+
+    srtp_err_status_t status =
+        srtp_aes_gcm_nss_do_crypto(cv, 1, non_null_buf, enc_len);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    memcpy(c->tag, non_null_buf + (*enc_len - c->tag_size), c->tag_size);
+    *enc_len -= c->tag_size;
+    return srtp_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
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_get_tag(void *cv,
+                                                  uint8_t *buf,
+                                                  uint32_t *len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    *len = c->tag_size;
+    memcpy(buf, c->tag, c->tag_size);
+    return (srtp_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
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_decrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_err_status_t status = srtp_aes_gcm_nss_do_crypto(cv, 0, buf, enc_len);
+    if (status != srtp_err_status_ok) {
+        int err = PR_GetError();
+        if (err == SEC_ERROR_BAD_DATA) {
+            status = srtp_err_status_auth_fail;
+        }
+    }
+
+    return status;
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_gcm_128_nss_description[] = "AES-128 GCM using NSS";
+static const char srtp_aes_gcm_256_nss_description[] = "AES-256 GCM using NSS";
+
+/*
+ * KAT values for AES self-test.  These
+ * values we're derived from independent test code
+ * using OpenSSL.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_key[SRTP_AES_GCM_128_KEY_LEN_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,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_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
+};
+
+/* clang-format off */
+static const uint8_t srtp_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+    0x3d, 0x58, 0xe0, 0x91,
+    /* the last 16 bytes are the tag */
+    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_0a           /* pointer to next testcase */
+};
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_key[SRTP_AES_GCM_256_KEY_LEN_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,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
+    0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
+    0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
+    0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
+    0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
+    0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
+    0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
+    0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
+    0x09, 0xc9, 0x86, 0xc1,
+    /* the last 16 bytes are the tag */
+    0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
+    0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_1a           /* pointer to next testcase */
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+/* clang-format off */
+const srtp_cipher_type_t srtp_aes_gcm_128 = {
+    srtp_aes_gcm_nss_alloc,
+    srtp_aes_gcm_nss_dealloc,
+    srtp_aes_gcm_nss_context_init,
+    srtp_aes_gcm_nss_set_aad,
+    srtp_aes_gcm_nss_encrypt,
+    srtp_aes_gcm_nss_decrypt,
+    srtp_aes_gcm_nss_set_iv,
+    srtp_aes_gcm_nss_get_tag,
+    srtp_aes_gcm_128_nss_description,
+    &srtp_aes_gcm_test_case_0,
+    SRTP_AES_GCM_128
+};
+/* clang-format on */
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+/* clang-format off */
+const srtp_cipher_type_t srtp_aes_gcm_256 = {
+    srtp_aes_gcm_nss_alloc,
+    srtp_aes_gcm_nss_dealloc,
+    srtp_aes_gcm_nss_context_init,
+    srtp_aes_gcm_nss_set_aad,
+    srtp_aes_gcm_nss_encrypt,
+    srtp_aes_gcm_nss_decrypt,
+    srtp_aes_gcm_nss_set_iv,
+    srtp_aes_gcm_nss_get_tag,
+    srtp_aes_gcm_256_nss_description,
+    &srtp_aes_gcm_test_case_1,
+    SRTP_AES_GCM_256
+};
+/* clang-format on */
index ef13a782404837757df5b5b147fe0a796dab5836..90d5e3b4e1dc029e66ada9d7e2ce16541a2d2b93 100644 (file)
@@ -49,8 +49,7 @@
 #endif
 
 #include <openssl/evp.h>
-#include "aes_icm_ossl.h"
-#include "aes_gcm_ossl.h"
+#include "aes_gcm.h"
 #include "alloc.h"
 #include "err.h" /* for srtp_debug */
 #include "crypto_types.h"
@@ -124,13 +123,13 @@ static srtp_err_status_t srtp_aes_gcm_openssl_alloc(srtp_cipher_t **c,
     /* setup cipher attributes */
     switch (key_len) {
     case SRTP_AES_GCM_128_KEY_LEN_WSALT:
-        (*c)->type = &srtp_aes_gcm_128_openssl;
+        (*c)->type = &srtp_aes_gcm_128;
         (*c)->algorithm = SRTP_AES_GCM_128;
         gcm->key_size = SRTP_AES_128_KEY_LEN;
         gcm->tag_len = tlen;
         break;
     case SRTP_AES_GCM_256_KEY_LEN_WSALT:
-        (*c)->type = &srtp_aes_gcm_256_openssl;
+        (*c)->type = &srtp_aes_gcm_256;
         (*c)->algorithm = SRTP_AES_GCM_256;
         gcm->key_size = SRTP_AES_256_KEY_LEN;
         gcm->tag_len = tlen;
@@ -193,6 +192,7 @@ static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv,
         break;
     }
 
+    EVP_CIPHER_CTX_cleanup(c->ctx);
     if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) {
         return (srtp_err_status_init_fail);
     }
@@ -218,7 +218,7 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_iv(
     c->dir = direction;
 
     debug_print(srtp_mod_aes_gcm, "setting iv: %s",
-                v128_hex_string((v128_t *)iv));
+                srtp_octet_string_hex_string(iv, 12));
 
     if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
         return (srtp_err_status_init_fail);
@@ -247,6 +247,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_aad(void *cv,
     srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
     int rv;
 
+    debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
+                srtp_octet_string_hex_string(aad, aad_len));
+
     /*
      * Set dummy tag, OpenSSL requires the Tag to be set before
      * processing AAD
@@ -548,7 +551,7 @@ static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
 /*
  * This is the vector function table for this crypto engine.
  */
-const srtp_cipher_type_t srtp_aes_gcm_128_openssl = {
+const srtp_cipher_type_t srtp_aes_gcm_128 = {
     srtp_aes_gcm_openssl_alloc,
     srtp_aes_gcm_openssl_dealloc,
     srtp_aes_gcm_openssl_context_init,
@@ -565,7 +568,7 @@ const srtp_cipher_type_t srtp_aes_gcm_128_openssl = {
 /*
  * This is the vector function table for this crypto engine.
  */
-const srtp_cipher_type_t srtp_aes_gcm_256_openssl = {
+const srtp_cipher_type_t srtp_aes_gcm_256 = {
     srtp_aes_gcm_openssl_alloc,
     srtp_aes_gcm_openssl_dealloc,
     srtp_aes_gcm_openssl_context_init,
diff --git a/libs/srtp/crypto/cipher/aes_icm_nss.c b/libs/srtp/crypto/cipher/aes_icm_nss.c
new file mode 100644 (file)
index 0000000..d161b8f
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * aes_icm_nss.c
+ *
+ * AES Integer Counter Mode
+ *
+ * Richard L. Barnes
+ * Cisco Systems, Inc.
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "aes_icm_ext.h"
+#include "crypto_types.h"
+#include "err.h" /* for srtp_debug */
+#include "alloc.h"
+#include "cipher_types.h"
+
+srtp_debug_module_t srtp_mod_aes_icm = {
+    0,            /* debugging is off by default */
+    "aes icm nss" /* printable module name       */
+};
+
+/*
+ * integer counter mode works as follows:
+ *
+ * 16 bits
+ * <----->
+ * +------+------+------+------+------+------+------+------+
+ * |           nonce           |    packet index    |  ctr |---+
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   v
+ * |                      salt                      |000000|->(+)
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ *                                                        +---------+
+ *                                                        | encrypt |
+ *                                                        +---------+
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   |
+ * |                    keystream block                    |<--+
+ * +------+------+------+------+------+------+------+------+
+ *
+ * All fields are big-endian
+ *
+ * ctr is the block counter, which increments from zero for
+ * each packet (16 bits wide)
+ *
+ * packet index is distinct for each packet (48 bits wide)
+ *
+ * nonce can be distinct across many uses of the same key, or
+ * can be a fixed value per key, or can be per-packet randomness
+ * (64 bits)
+ *
+ */
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 30, 38, or 46 for
+ * AES-128, AES-192, and AES-256 respectively.  Note, this key_len
+ * value is inflated, as it also accounts for the 112 bit salt
+ * value.  The tlen argument is for the AEAD tag length, which
+ * isn't used in counter mode.
+ */
+static srtp_err_status_t srtp_aes_icm_nss_alloc(srtp_cipher_t **c,
+                                                int key_len,
+                                                int tlen)
+{
+    srtp_aes_icm_ctx_t *icm;
+    NSSInitContext *nss;
+
+    debug_print(srtp_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 != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* Initialize NSS equiv of NSS_NoDB_Init(NULL) */
+    nss = NSS_InitContext("", "", "", "", NULL,
+                          NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
+                              NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
+                              NSS_INIT_OPTIMIZESPACE);
+    if (!nss) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* allocate memory a cipher of type aes_icm */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        NSS_ShutdownContext(nss);
+        return srtp_err_status_alloc_fail;
+    }
+
+    icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
+    if (icm == NULL) {
+        NSS_ShutdownContext(nss);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    icm->key = NULL;
+    icm->ctx = NULL;
+    icm->nss = nss;
+
+    /* set pointers */
+    (*c)->state = icm;
+
+    /* setup cipher parameters */
+    switch (key_len) {
+    case SRTP_AES_ICM_128_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_128;
+        (*c)->type = &srtp_aes_icm_128;
+        icm->key_size = SRTP_AES_128_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_192_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_192;
+        (*c)->type = &srtp_aes_icm_192;
+        icm->key_size = SRTP_AES_192_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_256_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_256;
+        (*c)->type = &srtp_aes_icm_256;
+        icm->key_size = SRTP_AES_256_KEY_LEN;
+        break;
+    }
+
+    /* set key size        */
+    (*c)->key_len = key_len;
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * This function deallocates an instance of this engine
+ */
+static srtp_err_status_t srtp_aes_icm_nss_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_icm_ctx_t *ctx;
+
+    ctx = (srtp_aes_icm_ctx_t *)c->state;
+    if (ctx) {
+        /* free any PK11 values that have been created */
+        if (ctx->key) {
+            PK11_FreeSymKey(ctx->key);
+            ctx->key = NULL;
+        }
+
+        if (ctx->ctx) {
+            PK11_DestroyContext(ctx->ctx, PR_TRUE);
+            ctx->ctx = NULL;
+        }
+
+        if (ctx->nss) {
+            NSS_ShutdownContext(ctx->nss);
+            ctx->nss = NULL;
+        }
+
+        /* zeroize everything */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_icm_nss_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
+ */
+static srtp_err_status_t srtp_aes_icm_nss_context_init(void *cv,
+                                                       const uint8_t *key)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+
+    /*
+     * 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, SRTP_SALT_LEN);
+    memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
+
+    /* force last two octets of the offset to zero (for srtp compatibility) */
+    c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
+    c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
+
+    debug_print(srtp_mod_aes_icm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+    debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
+
+    if (c->key) {
+        PK11_FreeSymKey(c->key);
+        c->key = NULL;
+    }
+
+    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_AES_CTR, NULL);
+    if (!slot) {
+        return srtp_err_status_bad_param;
+    }
+
+    SECItem keyItem = { siBuffer, (unsigned char *)key, c->key_size };
+    c->key = PK11_ImportSymKey(slot, CKM_AES_CTR, PK11_OriginUnwrap,
+                               CKA_ENCRYPT, &keyItem, NULL);
+    PK11_FreeSlot(slot);
+
+    if (!c->key) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+static srtp_err_status_t srtp_aes_icm_nss_set_iv(void *cv,
+                                                 uint8_t *iv,
+                                                 srtp_cipher_direction_t dir)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    v128_t nonce;
+
+    /* set nonce (for alignment) */
+    v128_copy_octet_string(&nonce, iv);
+
+    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
+
+    v128_xor(&c->counter, &c->offset, &nonce);
+
+    debug_print(srtp_mod_aes_icm, "set_counter: %s",
+                v128_hex_string(&c->counter));
+
+    /* set up the PK11 context now that we have all the info */
+    CK_AES_CTR_PARAMS param;
+    param.ulCounterBits = 16;
+    memcpy(param.cb, &c->counter, 16);
+
+    if (!c->key) {
+        return srtp_err_status_bad_param;
+    }
+
+    if (c->ctx) {
+        PK11_DestroyContext(c->ctx, PR_TRUE);
+    }
+
+    SECItem paramItem = { siBuffer, (unsigned char *)&param,
+                          sizeof(CK_AES_CTR_PARAMS) };
+    c->ctx = PK11_CreateContextBySymKey(CKM_AES_CTR, CKA_ENCRYPT, c->key,
+                                        &paramItem);
+    if (!c->ctx) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    return srtp_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
+ */
+static srtp_err_status_t srtp_aes_icm_nss_encrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+
+    if (!c->ctx) {
+        return srtp_err_status_bad_param;
+    }
+
+    int rv =
+        PK11_CipherOp(c->ctx, buf, (int *)enc_len, *enc_len, buf, *enc_len);
+
+    srtp_err_status_t status = (srtp_err_status_ok);
+    if (rv != SECSuccess) {
+        status = (srtp_err_status_cipher_fail);
+    }
+
+    return status;
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_icm_128_nss_description[] =
+    "AES-128 counter mode using NSS";
+static const char srtp_aes_icm_192_nss_description[] =
+    "AES-192 counter mode using NSS";
+static const char srtp_aes_icm_256_nss_description[] =
+    "AES-256 counter mode using NSS";
+
+/*
+ * KAT values for AES self-test.  These
+ * values came from the legacy libsrtp code.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_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,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_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
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
+    SRTP_AES_ICM_128_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_128_test_case_0_key,        /* key                      */
+    srtp_aes_icm_128_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_128_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-192-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_192_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_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,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_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
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
+    SRTP_AES_ICM_192_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_192_test_case_0_key,        /* key                      */
+    srtp_aes_icm_192_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_192_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-256-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_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
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_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,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_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
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
+    SRTP_AES_ICM_256_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_256_test_case_0_key,        /* key                      */
+    srtp_aes_icm_256_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_256_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_128 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_128_nss_description, /* */
+    &srtp_aes_icm_128_test_case_0,    /* */
+    SRTP_AES_ICM_128                  /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_192 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_192_nss_description, /* */
+    &srtp_aes_icm_192_test_case_0,    /* */
+    SRTP_AES_ICM_192                  /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_256 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_256_nss_description, /* */
+    &srtp_aes_icm_256_test_case_0,    /* */
+    SRTP_AES_ICM_256                  /* */
+};
index b591897623bb167b1b9a935ae86cc2edd86bee15..451cd18c0d8c4b76a5e33e0d3018155571f249f4 100644 (file)
@@ -53,7 +53,7 @@
 #endif
 
 #include <openssl/evp.h>
-#include "aes_icm_ossl.h"
+#include "aes_icm_ext.h"
 #include "crypto_types.h"
 #include "err.h" /* for srtp_debug */
 #include "alloc.h"
@@ -78,9 +78,9 @@ srtp_debug_module_t srtp_mod_aes_icm = {
  * +------+------+------+------+------+------+------+------+   |
  *                                                             |
  *                                                        +---------+
- *                                                       | encrypt |
- *                                                       +---------+
- *                                                            |
+ *                                                        | encrypt |
+ *                                                        +---------+
+ *                                                             |
  * +------+------+------+------+------+------+------+------+   |
  * |                    keystream block                    |<--+
  * +------+------+------+------+------+------+------+------+
@@ -248,6 +248,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv,
         break;
     }
 
+    EVP_CIPHER_CTX_cleanup(c->ctx);
     if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) {
         return srtp_err_status_fail;
     } else {
@@ -308,7 +309,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv,
     }
     *enc_len = len;
 
-    if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
+    if (!EVP_EncryptFinal_ex(c->ctx, buf + len, &len)) {
         return srtp_err_status_cipher_fail;
     }
     *enc_len += len;
index 19f00abc55be66d6075863dc9ce50d2e4863e45c..de93bc90d8f303ba205e0a593badf20b6e4a89e7 100644 (file)
@@ -49,6 +49,7 @@
 #endif
 
 #include "cipher.h"
+#include "cipher_priv.h"
 #include "crypto_types.h"
 #include "err.h"   /* for srtp_debug */
 #include "alloc.h" /* for crypto_alloc(), crypto_free()  */
@@ -165,24 +166,11 @@ int srtp_cipher_get_key_length(const srtp_cipher_t *c)
 }
 
 /*
- * A trivial platform independent random source.  The random
- * data is used for some of the cipher self-tests.
+ * A trivial platform independent random source.
+ * For use in test only.
  */
-static srtp_err_status_t srtp_cipher_rand(void *dest, uint32_t len)
+void srtp_cipher_rand_for_tests(void *dest, uint32_t len)
 {
-#if defined(HAVE_RAND_S)
-    uint8_t *dst = (uint8_t *)dest;
-    while (len) {
-        unsigned int val;
-        errno_t err = rand_s(&val);
-
-        if (err != 0)
-            return srtp_err_status_fail;
-
-        *dst++ = val & 0xff;
-        len--;
-    }
-#else
     /* Generic C-library (rand()) version */
     /* This is a random source of last resort */
     uint8_t *dst = (uint8_t *)dest;
@@ -194,8 +182,17 @@ static srtp_err_status_t srtp_cipher_rand(void *dest, uint32_t len)
         *dst++ = val & 0xff;
         len--;
     }
-#endif
-    return srtp_err_status_ok;
+}
+
+/*
+ * A trivial platform independent 32 bit random number.
+ * For use in test only.
+ */
+uint32_t srtp_cipher_rand_u32_for_tests(void)
+{
+    uint32_t r;
+    srtp_cipher_rand_for_tests(&r, sizeof(r));
+    return r;
 }
 
 #define SELF_TEST_BUF_OCTETS 128
@@ -246,7 +243,7 @@ srtp_err_status_t srtp_cipher_type_test(
         /*
          * test the encrypt function
          */
-        debug_print(srtp_mod_cipher, "testing encryption", NULL);
+        debug_print0(srtp_mod_cipher, "testing encryption");
 
         /* initialize cipher */
         status = srtp_cipher_init(c, test_case->key);
@@ -350,7 +347,7 @@ srtp_err_status_t srtp_cipher_type_test(
         /*
          * test the decrypt function
          */
-        debug_print(srtp_mod_cipher, "testing decryption", NULL);
+        debug_print0(srtp_mod_cipher, "testing decryption");
 
         /* re-initialize cipher for decryption */
         status = srtp_cipher_init(c, test_case->key);
@@ -465,13 +462,9 @@ srtp_err_status_t srtp_cipher_type_test(
         uint8_t iv[MAX_KEY_LEN];
 
         /* choose a length at random (leaving room for IV and padding) */
-        length = rand() % (SELF_TEST_BUF_OCTETS - 64);
+        length = srtp_cipher_rand_u32_for_tests() % (SELF_TEST_BUF_OCTETS - 64);
         debug_print(srtp_mod_cipher, "random plaintext length %d\n", length);
-        status = srtp_cipher_rand(buffer, length);
-        if (status) {
-            srtp_cipher_dealloc(c);
-            return status;
-        }
+        srtp_cipher_rand_for_tests(buffer, length);
 
         debug_print(srtp_mod_cipher, "plaintext:    %s",
                     srtp_octet_string_hex_string(buffer, length));
@@ -486,18 +479,10 @@ srtp_err_status_t srtp_cipher_type_test(
             srtp_cipher_dealloc(c);
             return srtp_err_status_cant_check;
         }
-        status = srtp_cipher_rand(key, test_case->key_length_octets);
-        if (status) {
-            srtp_cipher_dealloc(c);
-            return status;
-        }
+        srtp_cipher_rand_for_tests(key, test_case->key_length_octets);
 
         /* chose a random initialization vector */
-        status = srtp_cipher_rand(iv, MAX_KEY_LEN);
-        if (status) {
-            srtp_cipher_dealloc(c);
-            return status;
-        }
+        srtp_cipher_rand_for_tests(iv, MAX_KEY_LEN);
 
         /* initialize cipher */
         status = srtp_cipher_init(c, key);
index 659add0d476d46b3a3aff5e0295c1c32218e9b4d..969724611c42a7a7b0ca0f35967a84c1b4deee55 100644 (file)
@@ -97,7 +97,7 @@ static srtp_err_status_t srtp_null_cipher_init(void *cv, const uint8_t *key)
 {
     /* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
 
-    debug_print(srtp_mod_cipher, "initializing null cipher", NULL);
+    debug_print0(srtp_mod_cipher, "initializing null cipher");
 
     return srtp_err_status_ok;
 }
index afd63815424c739c25c38829bfbef263029ccc5f..36c049ef81696ed804a932a966a9d986a340f9f2 100644 (file)
@@ -261,14 +261,13 @@ void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
 
             /* process a whole block */
 
-            debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()",
-                        NULL);
+            debug_print0(srtp_mod_sha1, "(update) running srtp_sha1_core()");
 
             srtp_sha1_core(ctx->M, ctx->H);
 
         } else {
-            debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()",
-                        NULL);
+            debug_print0(srtp_mod_sha1,
+                         "(update) not running srtp_sha1_core()");
 
             for (i = ctx->octets_in_buffer;
                  i < (ctx->octets_in_buffer + octets_in_msg); i++) {
@@ -391,11 +390,10 @@ void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
         ctx->H[4] += E;
     }
 
-    debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
+    debug_print0(srtp_mod_sha1, "(final) running srtp_sha1_core()");
 
     if (ctx->octets_in_buffer >= 56) {
-        debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again",
-                    NULL);
+        debug_print0(srtp_mod_sha1, "(final) running srtp_sha1_core() again");
 
         /* we need to do one final run of the compression algo */
 
similarity index 80%
rename from libs/srtp/crypto/include/aes_gcm_ossl.h
rename to libs/srtp/crypto/include/aes_gcm.h
index d5b83eeeb07fa7f870871e592cd9dc09e70d00a1..4d6031f4bd879de129ec4dcf940af24e396b7b63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * aes_gcm_ossl.h
+ * aes_gcm.h
  *
  * Header for AES Galois Counter Mode.
  *
  *
  */
 
-#ifndef AES_GCM_OSSL_H
-#define AES_GCM_OSSL_H
+#ifndef AES_GCM_H
+#define AES_GCM_H
 
 #include "cipher.h"
 #include "srtp.h"
 #include "datatypes.h"
+
+#ifdef OPENSSL
+
 #include <openssl/evp.h>
 #include <openssl/aes.h>
 
@@ -59,4 +62,28 @@ typedef struct {
     srtp_cipher_direction_t dir;
 } srtp_aes_gcm_ctx_t;
 
-#endif /* AES_GCM_OSSL_H */
+#endif /* OPENSSL */
+
+#ifdef NSS
+
+#include <nss.h>
+#include <pk11pub.h>
+
+#define MAX_AD_SIZE 2048
+
+typedef struct {
+    int key_size;
+    int tag_size;
+    srtp_cipher_direction_t dir;
+    NSSInitContext *nss;
+    PK11SymKey *key;
+    uint8_t iv[12];
+    uint8_t aad[MAX_AD_SIZE];
+    int aad_size;
+    CK_GCM_PARAMS params;
+    uint8_t tag[16];
+} srtp_aes_gcm_ctx_t;
+
+#endif /* NSS */
+
+#endif /* AES_GCM_H */
similarity index 87%
rename from libs/srtp/crypto/include/aes_icm_ossl.h
rename to libs/srtp/crypto/include/aes_icm_ext.h
index c4aae376e6d73c6ec4cd724b98a24accfe1d1cc1..ad306ddca5b39df340b2d61aea7dbc9c50f2e387 100644 (file)
@@ -48,6 +48,9 @@
 
 #include "cipher.h"
 #include "datatypes.h"
+
+#ifdef OPENSSL
+
 #include <openssl/evp.h>
 #include <openssl/aes.h>
 
@@ -58,4 +61,23 @@ typedef struct {
     EVP_CIPHER_CTX *ctx;
 } srtp_aes_icm_ctx_t;
 
+#endif /* OPENSSL */
+
+#ifdef NSS
+
+#include <nss.h>
+#include <pk11pub.h>
+
+typedef struct {
+    v128_t counter;
+    v128_t offset;
+    int key_size;
+    uint8_t iv[16];
+    NSSInitContext *nss;
+    PK11SymKey *key;
+    PK11Context *ctx;
+} srtp_aes_icm_ctx_t;
+
+#endif /* NSS */
+
 #endif /* AES_ICM_H */
diff --git a/libs/srtp/crypto/include/cipher_priv.h b/libs/srtp/crypto/include/cipher_priv.h
new file mode 100644 (file)
index 0000000..46848ea
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright(c) 2001-2017 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 SRTP_CIHPER_PRIV_H
+#define SRTP_CIHPER_PRIV_H
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A trivial platform independent random source.
+ * For use in test only.
+ */
+void srtp_cipher_rand_for_tests(void *dest, uint32_t len);
+
+/*
+ * A trivial platform independent 32 bit random number.
+ * For use in test only.
+ */
+uint32_t srtp_cipher_rand_u32_for_tests(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_CIPHER_PRIV_H */
index a543b5478ba2d65a6b1d2b002332d9124ea1a90c..18f0328fbb6cff8fa9cf5cd9d236957bea3be80c 100644 (file)
 extern const srtp_cipher_type_t srtp_null_cipher;
 extern const srtp_cipher_type_t srtp_aes_icm_128;
 extern const srtp_cipher_type_t srtp_aes_icm_256;
-#ifdef OPENSSL
+#ifdef GCM
 extern const srtp_cipher_type_t srtp_aes_icm_192;
-extern const srtp_cipher_type_t srtp_aes_gcm_128_openssl;
-extern const srtp_cipher_type_t srtp_aes_gcm_256_openssl;
+extern const srtp_cipher_type_t srtp_aes_gcm_128;
+extern const srtp_cipher_type_t srtp_aes_gcm_256;
 #endif
 
 /*
@@ -74,6 +74,9 @@ extern srtp_debug_module_t srtp_mod_aes_icm;
 #ifdef OPENSSL
 extern srtp_debug_module_t srtp_mod_aes_gcm;
 #endif
+#ifdef NSS
+extern srtp_debug_module_t srtp_mod_aes_gcm;
+#endif
 
 /* debug modules for auth types */
 extern srtp_debug_module_t srtp_mod_hmac;
index 182cca25b9d1bf76019861e540b53e9e3f9c3fbd..6a588d0e92d3a8d33bdf5af23f9259b983d5c23b 100644 (file)
@@ -241,13 +241,13 @@ void v128_set_bit_to(v128_t *x, int i, int y);
 #endif /* DATATYPES_USE_MACROS */
 
 /*
- * octet_string_is_eq(a, b, len) returns 1 if the length len strings a
- * and b are not equal. It returns 0 otherwise. The running time of the
+ * srtp_octet_string_is_eq(a, b, len) returns 1 if the length len strings
+ * a and b are not equal. It returns 0 otherwise. The running time of the
  * comparison depends only on len, making this safe to use for (e.g.)
  * verifying authentication tags.
  */
 
-int octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
+int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
 
 /*
  * A portable way to zero out memory as recommended by
index 66a1023ec8691dca3f180ff05f0c13f8195bf85c..326f5e96b77cd8776f0b4a4d53ba878c3fe52fb1 100644 (file)
@@ -109,6 +109,8 @@ typedef struct {
 
 #ifdef ENABLE_DEBUG_LOGGING
 
+#define debug_print0(mod, format)                                              \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name)
 #define debug_print(mod, format, arg)                                          \
     srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
 #define debug_print2(mod, format, arg1, arg2)                                  \
@@ -117,6 +119,9 @@ typedef struct {
 
 #else
 
+#define debug_print0(mod, format)                                              \
+    if (mod.on)                                                                \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name)
 #define debug_print(mod, format, arg)                                          \
     if (mod.on)                                                                \
     srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
index dbe58266f43a6849ed965ac7f787affd0e2a8221..3ebc31525911ae9d3b09a622bfb8ae5756e1f32e 100644 (file)
@@ -80,7 +80,7 @@ void *srtp_crypto_alloc(size_t size)
     if (ptr) {
         debug_print(srtp_mod_alloc, "(location: %p) allocated", ptr);
     } else {
-        debug_print(srtp_mod_alloc, "allocation failed (asked for %d bytes)\n",
+        debug_print(srtp_mod_alloc, "allocation failed (asked for %zu bytes)\n",
                     size);
     }
 
index ab4492e8a6447808d2b55e0b87ffb14b81ca2e63..df6af7da889f68c7b56647c975904c9438b417c3 100644 (file)
@@ -130,18 +130,18 @@ srtp_err_status_t srtp_crypto_kernel_init()
     if (status) {
         return status;
     }
-#ifdef OPENSSL
+#ifdef GCM
     status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_192,
                                                  SRTP_AES_ICM_192);
     if (status) {
         return status;
     }
-    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128_openssl,
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128,
                                                  SRTP_AES_GCM_128);
     if (status) {
         return status;
     }
-    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256_openssl,
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256,
                                                  SRTP_AES_GCM_256);
     if (status) {
         return status;
index f443549e5a44136ef2a014189ae67d0f06d3e7cf..9db5bfb4327688358c72b6e4b7324dc57c4d5bcc 100644 (file)
@@ -80,6 +80,7 @@ srtp_err_status_t srtp_install_err_report_handler(
 
 void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...)
 {
+    char msg[512];
     va_list args;
     if (srtp_err_file != NULL) {
         va_start(args, format);
@@ -88,7 +89,6 @@ void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...)
     }
     if (srtp_err_report_handler != NULL) {
         va_start(args, format);
-        char msg[512];
         if (vsnprintf(msg, sizeof(msg), format, args) > 0) {
             /* strip trailing \n, callback should not have one */
             size_t l = strlen(msg);
index c0dfece659d774bbdd8d0648483ebbf214fce821..001584c1bf0311f4055625e9a03642b16061d30e 100644 (file)
@@ -410,7 +410,7 @@ void bitvector_left_shift(bitvector_t *x, int shift)
         x->word[i] = 0;
 }
 
-int octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
+int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
 {
     uint8_t *end = b + len;
     uint8_t accumulator = 0;
@@ -436,7 +436,7 @@ void srtp_cleanse(void *s, size_t len)
 
 void octet_string_set_to_zero(void *s, size_t len)
 {
-#ifdef OPENSSL
+#if defined(OPENSSL) && !defined(OPENSSL_CLEANSE_BROKEN)
     OPENSSL_cleanse(s, len);
 #else
     srtp_cleanse(s, len);
index 6dd332b0cf536c53a14e3e7cb6e26fd62a40b76b..d30045357b4a4e289e85065fb181dd0616e536d8 100644 (file)
@@ -196,7 +196,7 @@ srtp_err_status_t stat_test_runs(uint8_t *data)
     }
 
     if (srtp_mod_stat.on) {
-        debug_print(srtp_mod_stat, "runs test", NULL);
+        debug_print0(srtp_mod_stat, "runs test");
         for (i = 0; i < 6; i++)
             debug_print(srtp_mod_stat, "  runs[]: %d", runs[i]);
         for (i = 0; i < 6; i++)
index c621c0e9f2259c1540817b0ddf7c17df903b5292..2825b68df91428f8b7baa597ccc87a1480189f76 100644 (file)
 #endif
 
 #include "ut_sim.h"
+#include "cipher_priv.h"
 
 int ut_compar(const void *a, const void *b)
 {
-    return rand() > (RAND_MAX / 2) ? -1 : 1;
+    uint8_t r;
+    srtp_cipher_rand_for_tests(&r, sizeof(r));
+    return r > (UINT8_MAX / 2) ? -1 : 1;
 }
 
 void ut_init(ut_connection *utc)
index e28f5f264f8da365cab6fd6ce96c6964923cf9f3..8219a0618063006a922fc1b4febae3e770e7ad3c 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdio.h>  /* for printf() */
-#include <stdlib.h> /* for rand() */
+#include <stdio.h> /* for printf() */
 #include "getopt_s.h"
 #include "cipher.h"
-#ifdef OPENSSL
-#include "aes_icm_ossl.h"
-#include "aes_gcm_ossl.h"
+#include "cipher_priv.h"
+#ifdef GCM
+#include "aes_icm_ext.h"
+#include "aes_gcm.h"
 #else
 #include "aes_icm.h"
 #endif
@@ -118,10 +118,10 @@ void check_status(srtp_err_status_t s)
 extern srtp_cipher_type_t srtp_null_cipher;
 extern srtp_cipher_type_t srtp_aes_icm_128;
 extern srtp_cipher_type_t srtp_aes_icm_256;
-#ifdef OPENSSL
+#ifdef GCM
 extern srtp_cipher_type_t srtp_aes_icm_192;
-extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
-extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
+extern srtp_cipher_type_t srtp_aes_gcm_128;
+extern srtp_cipher_type_t srtp_aes_gcm_256;
 #endif
 
 int main(int argc, char *argv[])
@@ -187,21 +187,19 @@ int main(int argc, char *argv[])
             cipher_driver_test_array_throughput(
                 &srtp_aes_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
 
-#ifdef OPENSSL
+#ifdef GCM
         for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
             cipher_driver_test_array_throughput(
                 &srtp_aes_icm_192, SRTP_AES_ICM_192_KEY_LEN_WSALT, num_cipher);
 
         for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
-            cipher_driver_test_array_throughput(&srtp_aes_gcm_128_openssl,
-                                                SRTP_AES_GCM_128_KEY_LEN_WSALT,
-                                                num_cipher);
+            cipher_driver_test_array_throughput(
+                &srtp_aes_gcm_128, SRTP_AES_GCM_128_KEY_LEN_WSALT, num_cipher);
         }
 
         for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
-            cipher_driver_test_array_throughput(&srtp_aes_gcm_256_openssl,
-                                                SRTP_AES_GCM_256_KEY_LEN_WSALT,
-                                                num_cipher);
+            cipher_driver_test_array_throughput(
+                &srtp_aes_gcm_256, SRTP_AES_GCM_256_KEY_LEN_WSALT, num_cipher);
         }
 #endif
     }
@@ -210,10 +208,10 @@ int main(int argc, char *argv[])
         cipher_driver_self_test(&srtp_null_cipher);
         cipher_driver_self_test(&srtp_aes_icm_128);
         cipher_driver_self_test(&srtp_aes_icm_256);
-#ifdef OPENSSL
+#ifdef GCM
         cipher_driver_self_test(&srtp_aes_icm_192);
-        cipher_driver_self_test(&srtp_aes_gcm_128_openssl);
-        cipher_driver_self_test(&srtp_aes_gcm_256_openssl);
+        cipher_driver_self_test(&srtp_aes_gcm_128);
+        cipher_driver_self_test(&srtp_aes_gcm_256);
 #endif
     }
 
@@ -277,9 +275,9 @@ int main(int argc, char *argv[])
     status = srtp_cipher_dealloc(c);
     check_status(status);
 
-#ifdef OPENSSL
-    /* run the throughput test on the aes_gcm_128_openssl cipher */
-    status = srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c,
+#ifdef GCM
+    /* run the throughput test on the aes_gcm_128 cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_128, &c,
                                     SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
     if (status) {
         fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
@@ -291,15 +289,13 @@ int main(int argc, char *argv[])
         cipher_driver_test_throughput(c);
     }
 
-    if (do_validation) {
-        status = cipher_driver_test_buffering(c);
-        check_status(status);
-    }
+    // GCM ciphers don't do buffering; they're "one shot"
+
     status = srtp_cipher_dealloc(c);
     check_status(status);
 
-    /* run the throughput test on the aes_gcm_256_openssl cipher */
-    status = srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
+    /* run the throughput test on the aes_gcm_256 cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_256, &c,
                                     SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
     if (status) {
         fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
@@ -311,10 +307,8 @@ int main(int argc, char *argv[])
         cipher_driver_test_throughput(c);
     }
 
-    if (do_validation) {
-        status = cipher_driver_test_buffering(c);
-        check_status(status);
-    }
+    // GCM ciphers don't do buffering; they're "one shot"
+
     status = srtp_cipher_dealloc(c);
     check_status(status);
 #endif
@@ -396,7 +390,7 @@ srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c)
         end = buffer1 + buflen;
         while (current < end) {
             /* choose a short length */
-            len = rand() & 0x01f;
+            len = srtp_cipher_rand_u32_for_tests() & 0x01f;
 
             /* make sure that len doesn't cause us to overreach the buffer */
             if (current + len > end)
@@ -479,9 +473,8 @@ srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***ca,
             return status;
 
         /* generate random key and initialize cipher */
-        for (j = 0; j < klen; j++)
-            key[j] = (uint8_t)rand();
-        for (; j < klen_pad; j++)
+        srtp_cipher_rand_for_tests(key, klen);
+        for (j = klen; j < klen_pad; j++)
             key[j] = 0;
         status = srtp_cipher_init(*cipher_array, key);
         if (status)
@@ -535,7 +528,7 @@ uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
     v128_t nonce;
     clock_t timer;
     unsigned char *enc_buf;
-    int cipher_index = rand() % num_cipher;
+    int cipher_index = srtp_cipher_rand_u32_for_tests() % num_cipher;
 
     /* Over-alloc, for NIST CBC padding */
     enc_buf = srtp_crypto_alloc(octets_in_buffer + 17);
index 2f78903eb8eb133e622dea5cd1d0a9ee2157d27d..96379befe15d0fc15eb71859200117794fdc8bc9 100644 (file)
@@ -60,6 +60,8 @@ void print_string(char *s);
 
 void test_bswap(void);
 
+void test_set_to_zero(void);
+
 int main(void)
 {
     /*
@@ -135,6 +137,7 @@ int main(void)
     printf(" } \n");
 
     test_bswap();
+    test_set_to_zero();
 
     return 0;
 }
@@ -228,3 +231,26 @@ void test_bswap(void)
     printf("bswapped octet string: %s\n",
            octet_string_hex_string((uint8_t *)&y, 8));
 }
+
+void test_set_to_zero(void)
+{
+#define BUFFER_SIZE (16)
+    uint8_t buffer[BUFFER_SIZE];
+    size_t i;
+
+    for (i = 0; i < BUFFER_SIZE; i++) {
+        buffer[i] = i & 0xff;
+    }
+    printf("Buffer before: %s\n", octet_string_hex_string(buffer, BUFFER_SIZE));
+    octet_string_set_to_zero(buffer, BUFFER_SIZE);
+    printf("Buffer after: %s\n", octet_string_hex_string(buffer, BUFFER_SIZE));
+    for (i = 0; i < BUFFER_SIZE; i++) {
+        if (buffer[i]) {
+            fprintf(stderr,
+                    "Buffer contents not zero at position %zu (is %d)\n", i,
+                    buffer[i]);
+            abort();
+        }
+    }
+#undef BUFFER_SIZE
+}
index 4149447f748165996e3972329de067197f10547e..9a3d918aa1cfb423821f6172f5eb7b9f76ccab15 100644 (file)
 #include "srtp.h"
 
 #include "cipher.h"
-
-typedef struct {
-    void *state;
-} random_source_t;
-
-srtp_err_status_t random_source_alloc(void);
+#include "cipher_priv.h"
 
 void err_check(srtp_err_status_t s)
 {
@@ -76,9 +71,9 @@ int main(int argc, char *argv[])
     int i, j;
     extern srtp_cipher_type_t srtp_aes_icm_128;
     extern srtp_cipher_type_t srtp_aes_icm_256;
-#ifdef OPENSSL
-    extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
-    extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
+#ifdef GCM
+    extern srtp_cipher_type_t srtp_aes_gcm_128;
+    extern srtp_cipher_type_t srtp_aes_gcm_256;
 #endif
     srtp_cipher_t *c;
     /* clang-format off */
@@ -107,8 +102,7 @@ int main(int argc, char *argv[])
     printf("poker   %d\n", stat_test_poker(buffer));
     printf("runs    %d\n", stat_test_runs(buffer));
 
-    for (i = 0; i < 2500; i++)
-        buffer[i] = rand();
+    srtp_cipher_rand_for_tests(buffer, 2500);
     printf("running stat_tests on rand(), expecting success\n");
     printf("monobit %d\n", stat_test_monobit(buffer));
     printf("poker   %d\n", stat_test_poker(buffer));
@@ -180,14 +174,14 @@ int main(int argc, char *argv[])
         }
     }
 
-#ifdef OPENSSL
+#ifdef GCM
     {
         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(srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c,
+        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128, &c,
                                          SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
         err_check(srtp_cipher_init(c, key));
         err_check(
@@ -219,7 +213,7 @@ int main(int argc, char *argv[])
         for (i = 0; i < 2500; i++) {
             buffer[i] = 0;
         }
-        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
+        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256, &c,
                                          SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
         err_check(srtp_cipher_init(c, key));
         err_check(
index 1fdd6c3affd835cd4223dd9ccc777045f88dbd7f..c86b9ee7473e48f44efeaca5a1e77f25a10bb8f7 100644 (file)
@@ -682,14 +682,14 @@ srtp_err_status_t srtp_update_stream(srtp_t session,
  *
  * @param p is a pointer to the policy structure to be set
  *
- * The function call crypto_policy_set_rtp_default(&p) sets the
- * crypto_policy_t at location p to the SRTP default policy for RTP
+ * The function call srtp_crypto_policy_set_rtp_default(&p) sets the
+ * srtp_crypto_policy_t at location p to the SRTP default policy for RTP
  * protection, as defined in the specification.  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.
+ * elements in the srtp_crypto_policy_t datatype.
  *
  * @return void.
  *
@@ -934,7 +934,7 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p);
  * @param p is a pointer to the policy structure to be set
  *
  * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&p)
- * sets the crypto_policy_t at location p to use policy
+ * sets the srtp_crypto_policy_t at location p to use policy
  * AES_CM_192_HMAC_SHA1_80 as defined in RFC 6188.  This policy uses AES-192
  * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit
  * authentication tag.
@@ -943,7 +943,7 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p);
  * 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.
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
  * @return void.
  *
@@ -958,7 +958,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p);
  * @param p is a pointer to the policy structure to be set
  *
  * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&p)
- * sets the crypto_policy_t at location p to use policy
+ * sets the srtp_crypto_policy_t at location p to use policy
  * AES_CM_192_HMAC_SHA1_32 as defined in RFC 6188.  This policy uses AES-192
  * Counter Mode encryption and HMAC-SHA1 authentication, with an
  * authentication tag that is only 32 bits long.  This length is
@@ -970,7 +970,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p);
  * 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.
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
  * @warning This crypto policy is intended for use in SRTP, but not in
  * SRTCP.  It is recommended that a policy that uses longer
@@ -989,7 +989,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p);
  * @param p is a pointer to the policy structure to be set
  *
  * The function call srtp_crypto_policy_set_aes_cm_192_null_auth(&p) sets
- * the crypto_policy_t at location p to use the SRTP default cipher
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
  * (AES-192 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).
@@ -998,7 +998,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p);
  * 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.
+ * include more elements in the srtp_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
index 661a7f94ab9f3e6fa58ddf91a9eb2ad2af30fa33..f89915e09a839df93ae931d01b373f60edc88681 100644 (file)
@@ -219,7 +219,7 @@ typedef struct {
  * srtcp_hdr_t represents a secure rtcp header
  *
  * in this implementation, an srtcp header is assumed to be 32-bit
- * alinged
+ * aligned
  */
 
 #ifndef WORDS_BIGENDIAN
index db7e71a8e31faff9044540ed92360056d0c7fba4..e6e06d9a73dc649a71d2388b771ae8f3a7d8d620 100644 (file)
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'">$(Platform)\$(Configuration)\</IntDir>
   </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>GCM;HAVE_INTTYPES_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <PreBuildEvent>
       <Message>Creating config.h from config.hw</Message>
index b54ecf64eb445ee5941425a22f46a16cfde7f4c9..24af93bd997bc86d6750de3b2a8c8ee563d3216f 100644 (file)
@@ -151,7 +151,7 @@ srtp_err_status_t srtp_ekt_stream_init_from_policy(
 
 void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len)
 {
-#ifndef OPENSSL
+#ifndef GCM
     // FIXME: need to get this working through the crypto module interface
     srtp_aes_expanded_key_t expanded_key;
 
@@ -218,7 +218,7 @@ void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
 
     /* if the pointer ekt is NULL, then EKT is not in effect */
     if (!ekt) {
-        debug_print(mod_srtp, "EKT not in use", NULL);
+        debug_print0(mod_srtp, "EKT not in use");
         return;
     }
 
index 966757e7ade43e53450a36b4fe0ca0f6a83d464a..1887d7bc82438c877d1c2f6cc29ed91c7264827e 100644 (file)
 #include "ekt.h"   /* for SRTP Encrypted Key Transport */
 #include "alloc.h" /* for srtp_crypto_alloc() */
 
-#ifdef OPENSSL
-#include "aes_gcm_ossl.h" /* for AES GCM mode */
+#ifdef GCM
+#include "aes_gcm.h" /* for AES GCM mode */
+#endif
+
 #ifdef OPENSSL_KDF
 #include <openssl/kdf.h>
-#include "aes_icm_ossl.h" /* for AES GCM mode */
-#endif
+#include "aes_icm_ext.h"
 #endif
 
 #include <limits.h>
@@ -81,13 +82,14 @@ srtp_debug_module_t mod_srtp = {
 static srtp_err_status_t srtp_validate_rtp_header(void *rtp_hdr,
                                                   int *pkt_octet_len)
 {
+    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
+    int rtp_header_len;
+
     if (*pkt_octet_len < octets_in_rtp_header)
         return srtp_err_status_bad_param;
 
-    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
-
     /* Check RTP header length */
-    int rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
+    rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
     if (hdr->x == 1)
         rtp_header_len += octets_in_rtp_extn_hdr;
 
@@ -677,6 +679,8 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
                                        int key_len)
 {
     srtp_cipher_type_id_t cipher_id;
+    srtp_err_status_t stat;
+
     switch (key_len) {
     case SRTP_AES_ICM_256_KEY_LEN_WSALT:
         cipher_id = SRTP_AES_ICM_256;
@@ -692,7 +696,6 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
         break;
     }
 
-    srtp_err_status_t stat;
     stat = srtp_crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, key_len, 0);
     if (stat)
         return stat;
@@ -959,7 +962,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
      * to generate the salt value
      */
     if (rtp_salt_len > 0) {
-        debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
+        debug_print0(mod_srtp, "found rtp_salt_len > 0, generating salt");
 
         /* generate encryption salt, put after encryption key */
         stat = srtp_kdf_generate(&kdf, label_rtp_salt,
@@ -1067,9 +1070,8 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
          * to generate the salt value
          */
         if (rtp_xtn_hdr_salt_len > 0) {
-            debug_print(mod_srtp,
-                        "found rtp_xtn_hdr_salt_len > 0, generating salt",
-                        NULL);
+            debug_print0(mod_srtp,
+                         "found rtp_xtn_hdr_salt_len > 0, generating salt");
 
             /* generate encryption salt, put after encryption key */
             stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt,
@@ -1150,8 +1152,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
      * to generate the salt value
      */
     if (rtcp_salt_len > 0) {
-        debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
-                    NULL);
+        debug_print0(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt");
 
         /* generate encryption salt, put after encryption key */
         stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
@@ -1667,7 +1668,7 @@ static srtp_err_status_t srtp_get_est_pkt_index(srtp_hdr_t *hdr,
     debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(*est),
                  low32(*est));
 #else
-    debug_print(mod_srtp, "estimated u_packet index: %016llx", *est);
+    debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, *est);
 #endif
     return result;
 }
@@ -1697,7 +1698,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx,
     unsigned int mki_size = 0;
     uint8_t *mki_location = NULL;
 
-    debug_print(mod_srtp, "function srtp_protect_aead", NULL);
+    debug_print0(mod_srtp, "function srtp_protect_aead");
 
     /*
      * update the key usage limit, and check it to make sure that we
@@ -1756,7 +1757,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx,
     debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
                  low32(est));
 #else
-    debug_print(mod_srtp, "estimated packet index: %016llx", est);
+    debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
 #endif
 
     /*
@@ -1858,13 +1859,13 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx,
     unsigned int aad_len;
     srtp_hdr_xtnd_t *xtn_hdr = NULL;
 
-    debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
+    debug_print0(mod_srtp, "function srtp_unprotect_aead");
 
 #ifdef NO_64BIT_MATH
     debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
                  low32(est));
 #else
-    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
+    debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est);
 #endif
 
     /* get tag length from stream */
@@ -2059,7 +2060,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
     uint8_t *mki_location = NULL;
     int advance_packet_index = 0;
 
-    debug_print(mod_srtp, "function srtp_protect", NULL);
+    debug_print0(mod_srtp, "function srtp_protect");
 
     /* we assume the hdr is 32-bit aligned to start */
 
@@ -2230,7 +2231,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
     debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
                  low32(est));
 #else
-    debug_print(mod_srtp, "estimated packet index: %016llx", est);
+    debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
 #endif
 
     /*
@@ -2336,7 +2337,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
             return status;
 
         /* run auth func over ROC, put result into auth_tag */
-        debug_print(mod_srtp, "estimated packet index: %016llx", est);
+        debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est);
         status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4,
                                    auth_tag);
         debug_print(mod_srtp, "srtp auth tag:    %s",
@@ -2389,7 +2390,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
     uint32_t roc_to_set = 0;
     uint16_t seq_to_set = 0;
 
-    debug_print(mod_srtp, "function srtp_unprotect", NULL);
+    debug_print0(mod_srtp, "function srtp_unprotect");
 
     /* we assume the hdr is 32-bit aligned to start */
 
@@ -2458,7 +2459,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
     debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
                  low32(est));
 #else
-    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
+    debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est);
 #endif
 
     /* Determine if MKI is being used and what session keys should be used */
@@ -2614,7 +2615,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
         if (status)
             return srtp_err_status_auth_fail;
 
-        if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
+        if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len))
             return srtp_err_status_auth_fail;
     }
 
@@ -3285,7 +3286,6 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p)
     p->sec_serv = sec_serv_conf;
 }
 
-#ifdef OPENSSL
 void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p)
 {
     /*
@@ -3407,8 +3407,6 @@ void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p)
     p->sec_serv = sec_serv_conf_and_auth;
 }
 
-#endif
-
 /*
  * secure rtcp functions
  */
@@ -3496,7 +3494,8 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
 {
     srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
     uint32_t *enc_start;            /* pointer to start of encrypted portion  */
-    uint32_t *trailer;              /* pointer to start of trailer            */
+    uint32_t *trailer_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
     unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
     uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
     srtp_err_status_t status;
@@ -3519,18 +3518,15 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
     /* NOTE: hdr->length is not usable - it refers to only the first
      * RTCP report in the compound packet!
      */
-    /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-     * multiples of 32-bits (RFC 3550 6.1)
-     */
-    trailer = (uint32_t *)((char *)enc_start + enc_octet_len + tag_len);
+    trailer_p = (uint32_t *)((char *)enc_start + enc_octet_len + tag_len);
 
     if (stream->rtcp_services & sec_serv_conf) {
-        *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
+        trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
     } else {
         enc_start = NULL;
         enc_octet_len = 0;
         /* 0 is network-order independant */
-        *trailer = 0x00000000; /* set encrypt bit */
+        trailer = 0x00000000; /* set encrypt bit */
     }
 
     mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len + tag_len +
@@ -3554,9 +3550,11 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
         return status;
     }
     seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
-    *trailer |= htonl(seq_num);
+    trailer |= htonl(seq_num);
     debug_print(mod_srtp, "srtcp index: %x", seq_num);
 
+    memcpy(trailer_p, &trailer, sizeof(trailer));
+
     /*
      * Calculate and set the IV
      */
@@ -3598,7 +3596,7 @@ static srtp_err_status_t srtp_protect_rtcp_aead(
     /*
      * Process the sequence# as AAD
      */
-    tseq = *trailer;
+    tseq = trailer;
     status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
                                  sizeof(srtcp_trailer_t));
     if (status) {
@@ -3667,7 +3665,8 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
 {
     srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
     uint32_t *enc_start;            /* pointer to start of encrypted portion  */
-    uint32_t *trailer;              /* pointer to start of trailer            */
+    uint32_t *trailer_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
     unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
     uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
     srtp_err_status_t status;
@@ -3693,12 +3692,10 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
      */
     /* This should point trailer to the word past the end of the normal data. */
     /* This would need to be modified for optional mikey data */
-    /*
-     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-     *   multiples of 32-bits (RFC 3550 6.1)
-     */
-    trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
-                           sizeof(srtcp_trailer_t) - mki_size);
+    trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                             sizeof(srtcp_trailer_t) - mki_size);
+    memcpy(&trailer, trailer_p, sizeof(trailer));
+
     /*
      * We pass the tag down to the cipher when doing GCM mode
      */
@@ -3707,7 +3704,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
     auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len - mki_size -
                sizeof(srtcp_trailer_t);
 
-    if (*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) {
+    if (*((unsigned char *)trailer_p) & SRTCP_E_BYTE_BIT) {
         enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
     } else {
         enc_octet_len = 0;
@@ -3718,7 +3715,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
      * check the sequence number for replays
      */
     /* this is easier than dealing with bitfield access */
-    seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
+    seq_num = ntohl(trailer) & SRTCP_INDEX_MASK;
     debug_print(mod_srtp, "srtcp index: %x", seq_num);
     status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
     if (status) {
@@ -3768,7 +3765,7 @@ static srtp_err_status_t srtp_unprotect_rtcp_aead(
     /*
      * Process the sequence# as AAD
      */
-    tseq = *trailer;
+    tseq = trailer;
     status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
                                  sizeof(srtcp_trailer_t));
     if (status) {
@@ -3866,7 +3863,8 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
     srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
     uint32_t *enc_start;            /* pointer to start of encrypted portion  */
     uint32_t *auth_start;           /* pointer to start of auth. portion      */
-    uint32_t *trailer;              /* pointer to start of trailer            */
+    uint32_t *trailer_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
     unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
     uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
     srtp_err_status_t status;
@@ -3959,19 +3957,15 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
      * NOTE: hdr->length is not usable - it refers to only the first RTCP report
      * in the compound packet!
      */
-    /*
-     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-     * multiples of 32-bits (RFC 3550 6.1)
-     */
-    trailer = (uint32_t *)((char *)enc_start + enc_octet_len);
+    trailer_p = (uint32_t *)((char *)enc_start + enc_octet_len);
 
     if (stream->rtcp_services & sec_serv_conf) {
-        *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
+        trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
     } else {
         enc_start = NULL;
         enc_octet_len = 0;
         /* 0 is network-order independant */
-        *trailer = 0x00000000; /* set encrypt bit */
+        trailer = 0x00000000; /* set encrypt bit */
     }
 
     mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len +
@@ -3999,9 +3993,11 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
     if (status)
         return status;
     seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
-    *trailer |= htonl(seq_num);
+    trailer |= htonl(seq_num);
     debug_print(mod_srtp, "srtcp index: %x", seq_num);
 
+    memcpy(trailer_p, &trailer, sizeof(trailer));
+
     /*
      * if we're using rindael counter mode, set nonce and seq
      */
@@ -4097,7 +4093,8 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
     srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
     uint32_t *enc_start;            /* pointer to start of encrypted portion  */
     uint32_t *auth_start;           /* pointer to start of auth. portion      */
-    uint32_t *trailer;              /* pointer to start of trailer            */
+    uint32_t *trailer_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
     unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
     uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
     uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
@@ -4215,14 +4212,12 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
      */
     /* This should point trailer to the word past the end of the normal data. */
     /* This would need to be modified for optional mikey data */
-    /*
-     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-     *   multiples of 32-bits (RFC 3550 6.1)
-     */
-    trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
-                           (tag_len + mki_size + sizeof(srtcp_trailer_t)));
+    trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                             (tag_len + mki_size + sizeof(srtcp_trailer_t)));
+    memcpy(&trailer, trailer_p, sizeof(trailer));
+
     e_bit_in_packet =
-        (*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
+        (*((unsigned char *)trailer_p) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
     if (e_bit_in_packet != sec_serv_confidentiality) {
         return srtp_err_status_cant_check;
     }
@@ -4266,7 +4261,7 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
      * check the sequence number for replays
      */
     /* this is easier than dealing with bitfield access */
-    seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
+    seq_num = ntohl(trailer) & SRTCP_INDEX_MASK;
     debug_print(mod_srtp, "srtcp index: %x", seq_num);
     status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
     if (status)
@@ -4315,7 +4310,7 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
     /* compare the tag just computed with the one in the packet */
     debug_print(mod_srtp, "srtcp tag from packet:    %s",
                 srtp_octet_string_hex_string(auth_tag, tag_len));
-    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
+    if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len))
         return srtp_err_status_auth_fail;
 
     /*
@@ -4437,7 +4432,7 @@ srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
     case srtp_profile_null_sha1_80:
         srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
         break;
-#if defined(OPENSSL)
+#ifdef GCM
     case srtp_profile_aead_aes_128_gcm:
         srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
         break;
@@ -4471,7 +4466,7 @@ srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtcp(
     case srtp_profile_null_sha1_80:
         srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
         break;
-#if defined(OPENSSL)
+#ifdef GCM
     case srtp_profile_aead_aes_128_gcm:
         srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
         break;
@@ -4552,10 +4547,10 @@ srtp_err_status_t stream_get_protect_trailer_length(srtp_stream_ctx_t *stream,
                                                     uint32_t mki_index,
                                                     uint32_t *length)
 {
-    *length = 0;
-
     srtp_session_keys_t *session_key;
 
+    *length = 0;
+
     if (use_mki) {
         if (mki_index >= stream->num_master_keys) {
             return srtp_err_status_bad_mki;
index ab631878a4050a1567230c60e086acc9a9915678..e0bd7f77ed73bfd28449d02ee535c6a9770c6fec 100644 (file)
@@ -58,8 +58,9 @@ static int getopt_check_character(char c, const char *string)
 
     while (*string != 0) {
         if (max_string_len == 0) {
-            return '?';
+            return GETOPT_NOT_FOUND;
         }
+        max_string_len--;
         if (*string++ == c) {
             if (*string == ':') {
                 return GETOPT_FOUND_WITH_ARGUMENT;
index 609ce9c8e48a275cc199b3a1e8dab4b890a9ab7d..df434a02245cf71f00d6073ca6163fe16a015969 100644 (file)
@@ -50,6 +50,7 @@
 #include "getopt_s.h" /* for local getopt()    */
 
 #include "rdbx.h"
+#include "cipher_priv.h"
 
 #ifdef ROC_TEST
 #error "srtp_rdbx_t won't work with ROC_TEST - bitmask same size as seq_median"
@@ -305,7 +306,7 @@ srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
      */
     printf("\ttesting insertion with large gaps...");
     for (idx = 0, ircvd = 0; (int)idx < num_trials;
-         idx++, ircvd += (1 << (rand() % 12))) {
+         idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 12))) {
         status = rdbx_check_add(&rdbx, ircvd);
         if (status)
             return status;
@@ -320,8 +321,7 @@ srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
     return srtp_err_status_ok;
 }
 
-#include <time.h>   /* for clock()  */
-#include <stdlib.h> /* for random() */
+#include <time.h> /* for clock()  */
 
 double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
 {
@@ -348,6 +348,9 @@ double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
             ++failures;
     }
     timer = clock() - timer;
+    if (timer < 1) {
+        timer = 1;
+    }
 
     printf("number of failures: %d \n", failures);
 
index a88224684f6a411ce15aeb530b33a0c8c58e55a3..e0808b685a7918fa367c4020890848c96d8b5c6a 100644 (file)
@@ -52,6 +52,8 @@
 #include "rdb.h"
 #include "ut_sim.h"
 
+#include "cipher_priv.h"
+
 /*
  * num_trials defines the number of trials that are used in the
  * validation functions below
@@ -189,7 +191,7 @@ srtp_err_status_t test_rdb_db()
 
     /* test insertion with large gaps */
     for (idx = 0, ircvd = 0; idx < num_trials;
-         idx++, ircvd += (1 << (rand() % 10))) {
+         idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 10))) {
         err = rdb_check_add(&rdb, ircvd);
         if (err)
             return err;
index d61ba8ef24ea22f66bb983773aa6662f47f4fb37..439862039a462f63c6e02133fa2bdd935550b74a 100644 (file)
@@ -97,7 +97,7 @@ srtp_err_status_t roc_test(int num_trials)
 
     printf("\n\ttesting sequential insertion...");
     for (i = 0; i < 2048; i++) {
-        delta = srtp_index_guess(&local, &est, (uint16_t)ref);
+        srtp_index_guess(&local, &est, (uint16_t)ref);
 #if ROC_VERBOSE
         printf("%lld, %lld, %d\n", ref, est, i);
 #endif
index f60a9b11b28850e6025800dc9583caaa4108648c..70248ee2b5a1cc17a9fde78dd8904edf39459cb5 100644 (file)
@@ -53,6 +53,8 @@
 #include <sys/socket.h>
 #endif
 
+#include "cipher_priv.h"
+
 #define PRINT_DEBUG 0   /* set to 1 to print out debugging data */
 #define VERBOSE_DEBUG 0 /* set to 1 to print out more data      */
 
@@ -148,7 +150,7 @@ int rtp_sender_init(rtp_sender_t sender,
     /* set header values */
     sender->message.header.ssrc = htonl(ssrc);
     sender->message.header.ts = 0;
-    sender->message.header.seq = (uint16_t)rand();
+    sender->message.header.seq = (uint16_t)srtp_cipher_rand_u32_for_tests();
     sender->message.header.m = 0;
     sender->message.header.pt = 0x1;
     sender->message.header.version = 2;
index d718a2b3ad18e831e471ee77b44bc2624f374dfd..8c89a2c10179d9c4cef93f1bf72bc53bac25f797 100644 (file)
 
 #define MAX_KEY_LEN 96
 #define MAX_FILTER 256
+#define MAX_FILE 255
 
 struct srtp_crypto_suite {
     const char *can_name;
+    int gcm_on;
     int key_size;
     int tag_size;
 };
 
 static struct srtp_crypto_suite srtp_crypto_suites[] = {
-    {.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
 #if 0
-  {.can_name = "F8_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4},
+  {.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
 #endif
-    {.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
-    {.can_name = "AES_CM_128_HMAC_SHA1_80", .key_size = 128, .tag_size = 10 },
+    {.can_name = "AES_CM_128_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 128,
+     .tag_size = 4 },
+    {.can_name = "AES_CM_128_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 128,
+     .tag_size = 10 },
+    {.can_name = "AES_192_CM_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 192,
+     .tag_size = 4 },
+    {.can_name = "AES_192_CM_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 192,
+     .tag_size = 10 },
+    {.can_name = "AES_256_CM_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 256,
+     .tag_size = 4 },
+    {.can_name = "AES_256_CM_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 256,
+     .tag_size = 10 },
+    {.can_name = "AEAD_AES_128_GCM",
+     .gcm_on = 1,
+     .key_size = 128,
+     .tag_size = 16 },
+    {.can_name = "AEAD_AES_256_GCM",
+     .gcm_on = 1,
+     .key_size = 256,
+     .tag_size = 16 },
     {.can_name = NULL }
 };
 
+void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
+                                  const char *msg,
+                                  void *data)
+{
+    char level_char = '?';
+    switch (level) {
+    case srtp_log_level_error:
+        level_char = 'e';
+        break;
+    case srtp_log_level_warning:
+        level_char = 'w';
+        break;
+    case srtp_log_level_info:
+        level_char = 'i';
+        break;
+    case srtp_log_level_debug:
+        level_char = 'd';
+        break;
+    }
+    fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
+}
+
 int main(int argc, char *argv[])
 {
     char errbuf[PCAP_ERRBUF_SIZE];
@@ -112,15 +165,18 @@ int main(int argc, char *argv[])
     int c;
     struct srtp_crypto_suite scs, *i_scsp;
     scs.key_size = 128;
-    scs.tag_size = 8;
+    scs.tag_size = 0;
     int gcm_on = 0;
     char *input_key = NULL;
     int b64_input = 0;
     char key[MAX_KEY_LEN];
     struct bpf_program fp;
     char filter_exp[MAX_FILTER] = "";
+    char pcap_file[MAX_FILE] = "-";
+    int rtp_packet_offset = DEFAULT_RTP_OFFSET;
     rtp_decoder_t dec;
-    srtp_policy_t policy;
+    srtp_policy_t policy = { { 0 } };
+    rtp_decoder_mode_t mode = mode_rtp;
     srtp_err_status_t status;
     int len;
     int expected_len;
@@ -138,9 +194,15 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
+    status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
+    if (status) {
+        fprintf(stderr, "error: install log handler failed\n");
+        exit(1);
+    }
+
     /* check args */
     while (1) {
-        c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:");
+        c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:");
         if (c == -1) {
             break;
         }
@@ -153,10 +215,12 @@ int main(int argc, char *argv[])
             break;
         case 'e':
             scs.key_size = atoi(optarg_s);
-            if (scs.key_size != 128 && scs.key_size != 256) {
-                fprintf(stderr,
-                        "error: encryption key size must be 128 or 256 (%d)\n",
-                        scs.key_size);
+            if (scs.key_size != 128 && scs.key_size != 192 &&
+                scs.key_size != 256) {
+                fprintf(
+                    stderr,
+                    "error: encryption key size must be 128, 192 or 256 (%d)\n",
+                    scs.key_size);
                 exit(1);
             }
             input_key = malloc(scs.key_size);
@@ -173,7 +237,7 @@ int main(int argc, char *argv[])
             sec_servs |= sec_serv_auth;
             break;
         case 'd':
-            status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
+            status = srtp_set_debug_module(optarg_s, 1);
             if (status) {
                 fprintf(stderr, "error: set debug module (%s) failed\n",
                         optarg_s);
@@ -207,20 +271,59 @@ int main(int argc, char *argv[])
             scs = *i_scsp;
             input_key = malloc(scs.key_size);
             sec_servs |= sec_serv_conf | sec_serv_auth;
+            gcm_on = scs.gcm_on;
+            break;
+        case 'm':
+            if (strcasecmp("rtp", optarg_s) == 0) {
+                mode = mode_rtp;
+            } else if (strcasecmp("rtcp", optarg_s) == 0) {
+                mode = mode_rtcp;
+            } else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
+                mode = mode_rtcp_mux;
+            } else {
+                fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
+                exit(1);
+            }
+            break;
+        case 'p':
+            if (strlen(optarg_s) > MAX_FILE) {
+                fprintf(stderr,
+                        "error: pcap file path bigger than %d characters\n",
+                        MAX_FILE);
+                exit(1);
+            }
+            strcpy(pcap_file, optarg_s);
+            break;
+        case 'o':
+            rtp_packet_offset = atoi(optarg_s);
             break;
         default:
             usage(argv[0]);
         }
     }
 
+    if (scs.tag_size == 0) {
+        if (gcm_on) {
+            scs.tag_size = 16;
+        } else {
+            scs.tag_size = 10;
+        }
+    }
+
     if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
         fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
                 scs.tag_size);
-        // exit(1);
+        exit(1);
+    }
+
+    if (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
+        fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
+                scs.tag_size);
+        exit(1);
     }
 
     if (do_list_mods) {
-        status = srtp_crypto_kernel_list_debug_modules();
+        status = srtp_list_debug_modules();
         if (status) {
             fprintf(stderr, "error: list of debug modules failed\n");
             exit(1);
@@ -266,12 +369,24 @@ int main(int argc, char *argv[])
 #ifdef OPENSSL
                 switch (scs.key_size) {
                 case 128:
-                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
-                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+                    if (scs.tag_size == 16) {
+                        srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_128_16_auth(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+                    }
                     break;
                 case 256:
-                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
-                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
+                    if (scs.tag_size == 16) {
+                        srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_256_16_auth(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
+                    }
                     break;
                 }
 #else
@@ -282,12 +397,51 @@ int main(int argc, char *argv[])
             } else {
                 switch (scs.key_size) {
                 case 128:
-                    srtp_crypto_policy_set_rtp_default(&policy.rtp);
-                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtcp);
+                    }
+                    break;
+                case 192:
+#ifdef OPENSSL
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtcp);
+                    }
+#else
+                    fprintf(stderr,
+                            "error: AES 192 mode only supported when using the "
+                            "OpenSSL crypto engine.\n");
+                    return 0;
+
+#endif
                     break;
                 case 256:
-                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
-                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &policy.rtcp);
+                    }
                     break;
                 }
             }
@@ -302,11 +456,26 @@ int main(int argc, char *argv[])
                 switch (scs.key_size) {
                 case 128:
                     srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
-                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                        &policy.rtcp);
+                    break;
+                case 192:
+#ifdef OPENSSL
+                    srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                        &policy.rtcp);
+#else
+                    fprintf(stderr,
+                            "error: AES 192 mode only supported when using the "
+                            "OpenSSL crypto engine.\n");
+                    return 0;
+
+#endif
                     break;
                 case 256:
                     srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
-                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                        &policy.rtcp);
                     break;
                 }
             }
@@ -353,7 +522,7 @@ int main(int argc, char *argv[])
         policy.rtp.auth_tag_len = scs.tag_size;
 
         if (gcm_on && scs.tag_size != 8) {
-            fprintf(stderr, "setted tag len %d\n", scs.tag_size);
+            fprintf(stderr, "set tag len %d\n", scs.tag_size);
             policy.rtp.auth_tag_len = scs.tag_size;
         }
 
@@ -365,11 +534,7 @@ int main(int argc, char *argv[])
             int pad;
             expected_len = policy.rtp.cipher_key_len * 4 / 3;
             len = base64_string_to_octet_string(key, &pad, input_key,
-                                                expected_len);
-            if (pad != 0) {
-                fprintf(stderr, "error: padding in base64 unexpected\n");
-                exit(1);
-            }
+                                                strlen(input_key));
         } else {
             expected_len = policy.rtp.cipher_key_len * 2;
             len = hex_string_to_octet_string(key, input_key, expected_len);
@@ -388,17 +553,20 @@ int main(int argc, char *argv[])
             exit(1);
         }
 
+        int key_octets = (scs.key_size / 8);
+        int salt_octets = policy.rtp.cipher_key_len - key_octets;
         fprintf(stderr, "set master key/salt to %s/",
-                octet_string_hex_string(key, 16));
-        fprintf(stderr, "%s\n", octet_string_hex_string(key + 16, 14));
+                octet_string_hex_string(key, key_octets));
+        fprintf(stderr, "%s\n",
+                octet_string_hex_string(key + key_octets, salt_octets));
 
     } else {
         fprintf(stderr,
-                "error: neither encryption or authentication were selected");
+                "error: neither encryption or authentication were selected\n");
         exit(1);
     }
 
-    pcap_handle = pcap_open_offline("-", errbuf);
+    pcap_handle = pcap_open_offline(pcap_file, errbuf);
 
     if (!pcap_handle) {
         fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
@@ -421,11 +589,22 @@ int main(int argc, char *argv[])
         exit(1);
     }
     fprintf(stderr, "Starting decoder\n");
-    rtp_decoder_init(dec, policy);
+    if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) {
+        fprintf(stderr, "error: init failed\n");
+        exit(1);
+    }
 
     pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
 
-    rtp_decoder_deinit_srtp(dec);
+    if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
+        fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
+    }
+    if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
+        fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
+    }
+    fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);
+
+    rtp_decoder_deinit(dec);
     rtp_decoder_dealloc(dec);
 
     status = srtp_shutdown();
@@ -442,7 +621,8 @@ void usage(char *string)
 {
     fprintf(
         stderr,
-        "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
+        "usage: %s [-d <debug>]* [[-k][-b] <key>] [-a][-t][-e] [-s "
+        "<srtp-crypto-suite>] [-m <mode>]\n"
         "or     %s -l\n"
         "where  -a use message authentication\n"
         "       -e <key size> use encryption (use 128 or 256 for key size)\n"
@@ -454,7 +634,10 @@ void usage(char *string)
         "       -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
         "       -d <debug> turn on debugging for module <debug>\n"
         "       -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
-        "          on RFC4568-style crypto suite specification\n",
+        "          on RFC4568-style crypto suite specification\n"
+        "       -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\n"
+        "       -p <pcap file> path to pcap file (defaults to stdin)\n"
+        "       -o byte offset of RTP packet in capture (defaults to 42)\n",
         string, string);
     exit(1);
 }
@@ -469,27 +652,34 @@ void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
     free(rtp_ctx);
 }
 
-srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
-                                        unsigned int ssrc)
-{
-    decoder->policy.ssrc.value = htonl(ssrc);
-    return srtp_create(&decoder->srtp_ctx, &decoder->policy);
-}
-
-int rtp_decoder_deinit_srtp(rtp_decoder_t decoder)
+int rtp_decoder_deinit(rtp_decoder_t decoder)
 {
-    return srtp_dealloc(decoder->srtp_ctx);
+    if (decoder->srtp_ctx) {
+        return srtp_dealloc(decoder->srtp_ctx);
+    }
+    return 0;
 }
 
-int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy)
+int rtp_decoder_init(rtp_decoder_t dcdr,
+                     srtp_policy_t policy,
+                     rtp_decoder_mode_t mode,
+                     int rtp_packet_offset)
 {
-    dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
+    dcdr->rtp_offset = rtp_packet_offset;
     dcdr->srtp_ctx = NULL;
     dcdr->start_tv.tv_usec = 0;
     dcdr->start_tv.tv_sec = 0;
     dcdr->frame_nr = -1;
+    dcdr->error_cnt = 0;
+    dcdr->rtp_cnt = 0;
+    dcdr->rtcp_cnt = 0;
+    dcdr->mode = mode;
     dcdr->policy = policy;
-    dcdr->policy.ssrc.type = ssrc_specific;
+    dcdr->policy.ssrc.type = ssrc_any_inbound;
+
+    if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
+        return 1;
+    }
     return 0;
 }
 
@@ -516,6 +706,8 @@ void rtp_decoder_handle_pkt(u_char *arg,
                             const u_char *bytes)
 {
     rtp_decoder_t dcdr = (rtp_decoder_t)arg;
+    rtp_msg_t message;
+    int rtp;
     int pktsize;
     struct timeval delta;
     int octets_recvd;
@@ -531,7 +723,7 @@ void rtp_decoder_handle_pkt(u_char *arg,
     }
     const void *rtp_packet = bytes + dcdr->rtp_offset;
 
-    memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
+    memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
     pktsize = hdr->caplen - dcdr->rtp_offset;
     octets_recvd = pktsize;
 
@@ -539,24 +731,43 @@ void rtp_decoder_handle_pkt(u_char *arg,
         return;
     }
 
-    /* verify rtp header */
-    if (dcdr->message.header.version != 2) {
-        return;
+    if (dcdr->mode == mode_rtp) {
+        rtp = 1;
+    } else if (dcdr->mode == mode_rtcp) {
+        rtp = 0;
+    } else {
+        rtp = 1;
+        if (octets_recvd >= 2) {
+            /* rfc5761 */
+            u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
+            rtp = payload_type < 64 || payload_type > 95;
+        }
     }
-    if (dcdr->srtp_ctx == NULL) {
-        status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
+
+    if (rtp) {
+        /* verify rtp header */
+        if (message.header.version != 2) {
+            return;
+        }
+
+        status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
         if (status) {
-            exit(1);
+            dcdr->error_cnt++;
+            return;
         }
-    }
-    status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
-    if (status) {
-        return;
+        dcdr->rtp_cnt++;
+    } else {
+        status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
+        if (status) {
+            dcdr->error_cnt++;
+            return;
+        }
+        dcdr->rtcp_cnt++;
     }
     timersub(&hdr->ts, &dcdr->start_tv, &delta);
     fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
             (long)delta.tv_usec);
-    hexdump(&dcdr->message, octets_recvd);
+    hexdump(&message, octets_recvd);
 }
 
 void rtp_print_error(srtp_err_status_t status, char *message)
index c8c31dd77337beff8f305f707c4ae3e16d492b0d..27e8880f2c80033179ac74917af426ba63612082 100644 (file)
 
 #define DEFAULT_RTP_OFFSET 42
 
+typedef enum {
+    mode_rtp = 0,
+    mode_rtcp,
+    mode_rtcp_mux,
+} rtp_decoder_mode_t;
+
 typedef struct rtp_decoder_ctx_t {
     srtp_policy_t policy;
     srtp_ctx_t *srtp_ctx;
+    rtp_decoder_mode_t mode;
     int rtp_offset;
     struct timeval start_tv;
     int frame_nr;
-    rtp_msg_t message;
+    int error_cnt;
+    int rtp_cnt;
+    int rtcp_cnt;
 } rtp_decoder_ctx_t;
 
 typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
@@ -95,11 +104,19 @@ rtp_decoder_t rtp_decoder_alloc(void);
 
 void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx);
 
-int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy);
+int rtp_decoder_init(rtp_decoder_t dcdr,
+                     srtp_policy_t policy,
+                     rtp_decoder_mode_t mode,
+                     int rtp_packet_offset);
+
+int rtp_decoder_deinit(rtp_decoder_t decoder);
 
-srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
-                                        unsigned int ssrc);
+void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
+                                  const char *msg,
+                                  void *data);
 
-int rtp_decoder_deinit_srtp(rtp_decoder_t decoder);
+void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
+                                  const char *msg,
+                                  void *data);
 
 #endif /* RTP_DECODER_H */
index 6e7416c7f524d86e689a4fc80f210d86c8e237ce..901816e46da47b391a4459c13088291612af079e 100644 (file)
@@ -317,6 +317,7 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
+    memset(&name, 0, sizeof(struct sockaddr_in));
     name.sin_addr = rcvr_addr;
     name.sin_family = PF_INET;
     name.sin_port = htons(port);
@@ -364,7 +365,7 @@ int main(int argc, char *argv[])
         switch (sec_servs) {
         case sec_serv_conf_and_auth:
             if (gcm_on) {
-#ifdef OPENSSL
+#ifdef GCM
                 switch (key_size) {
                 case 128:
                     srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
@@ -377,7 +378,7 @@ int main(int argc, char *argv[])
                 }
 #else
                 printf("error: GCM mode only supported when using the OpenSSL "
-                       "crypto engine.\n");
+                       "or NSS crypto engine.\n");
                 return 0;
 #endif
             } else {
@@ -413,7 +414,7 @@ int main(int argc, char *argv[])
             break;
         case sec_serv_auth:
             if (gcm_on) {
-#ifdef OPENSSL
+#ifdef GCM
                 switch (key_size) {
                 case 128:
                     srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
index 238ec93c5d45e26f691107fc4471db1ec163ab40..158a39312d8dc7c155c0b1305290abb51c917aaf 100755 (executable)
@@ -41,8 +41,13 @@ case $(uname -s) in
     *CYGWIN*|*MINGW*)
         EXE=".exe"
         ;;
-    *)
+    *Linux*)
         EXE=""
+        export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+    *Darwin*)
+        EXE=""
+        export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
         ;;
 esac
 
index 773400562cd5da516c4fea64677e68b73c017a9a..644255e1a172911e6a51107208049a6ea420ae48 100755 (executable)
@@ -41,8 +41,13 @@ case $(uname -s) in
     *CYGWIN*|*MINGW*)
         EXE=".exe"
         ;;
-    *)
+    *Linux*)
         EXE=""
+        export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+    *Darwin*)
+        EXE=""
+        export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
         ;;
 esac
 
index 4ea8fe5302c1be34929f9b0d9f27710bb13ccbce..1335540609e9d2cd6eb26d7d07f110359539c0de 100644 (file)
 
 srtp_err_status_t srtp_validate(void);
 
-#ifdef OPENSSL
+#ifdef GCM
 srtp_err_status_t srtp_validate_gcm(void);
 #endif
 
 srtp_err_status_t srtp_validate_encrypted_extensions_headers(void);
 
-#ifdef OPENSSL
+#ifdef GCM
 srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm(void);
 #endif
 
@@ -79,7 +79,7 @@ srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list);
 
 srtp_err_status_t srtp_test_empty_payload(void);
 
-#ifdef OPENSSL
+#ifdef GCM
 srtp_err_status_t srtp_test_empty_payload_gcm(void);
 #endif
 
@@ -422,7 +422,7 @@ int main(int argc, char *argv[])
             exit(1);
         }
 
-#ifdef OPENSSL
+#ifdef GCM
         printf("testing srtp_protect and srtp_unprotect against "
                "reference packet using GCM\n");
         if (srtp_validate_gcm() == srtp_err_status_ok) {
@@ -442,7 +442,7 @@ int main(int argc, char *argv[])
             exit(1);
         }
 
-#ifdef OPENSSL
+#ifdef GCM
         printf("testing srtp_protect and srtp_unprotect against "
                "reference packet with encrypted extension headers (GCM)\n");
         if (srtp_validate_encrypted_extensions_headers_gcm() ==
@@ -478,7 +478,7 @@ int main(int argc, char *argv[])
             printf("failed\n");
             exit(1);
         }
-#ifdef OPENSSL
+#ifdef GCM
         printf("testing srtp_protect and srtp_unprotect against "
                "packet with empty payload (GCM)\n");
         if (srtp_test_empty_payload_gcm() == srtp_err_status_ok) {
@@ -1341,6 +1341,8 @@ srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index)
      */
     rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
     if (rcvr_policy == NULL) {
+        free(hdr);
+        free(hdr2);
         return srtp_err_status_alloc_fail;
     }
     memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
@@ -1606,6 +1608,9 @@ double mips_estimate(int num_trials, int *ignore)
         sum += i;
     }
     t = clock() - t;
+    if (t < 1) {
+        t = 1;
+    }
 
     /*   printf("%d\n", sum); */
     *ignore = sum;
@@ -1702,7 +1707,7 @@ srtp_err_status_t srtp_validate()
     debug_print(mod_driver, "ciphertext reference:\n  %s",
                 octet_string_hex_string(srtp_ciphertext, len));
 
-    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
+    if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1720,7 +1725,7 @@ srtp_err_status_t srtp_validate()
     debug_print(mod_driver, "srtcp ciphertext reference:\n  %s",
                 octet_string_hex_string(srtcp_ciphertext, len));
 
-    if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
+    if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1742,7 +1747,7 @@ srtp_err_status_t srtp_validate()
         return status;
     }
 
-    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
+    if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1755,7 +1760,7 @@ srtp_err_status_t srtp_validate()
         return status;
     }
 
-    if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
+    if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1772,7 +1777,7 @@ srtp_err_status_t srtp_validate()
     return srtp_err_status_ok;
 }
 
-#ifdef OPENSSL
+#ifdef GCM
 /*
  * srtp_validate_gcm() verifies the correctness of libsrtp by comparing
  * an computed packet against the known ciphertext for the plaintext.
@@ -1870,7 +1875,7 @@ srtp_err_status_t srtp_validate_gcm()
     debug_print(mod_driver, "srtp ciphertext reference:\n  %s",
                 octet_string_hex_string(srtp_ciphertext, len));
 
-    if (octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
+    if (srtp_octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1888,7 +1893,7 @@ srtp_err_status_t srtp_validate_gcm()
     debug_print(mod_driver, "srtcp ciphertext reference:\n  %s",
                 octet_string_hex_string(srtcp_ciphertext, len));
 
-    if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
+    if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1911,7 +1916,7 @@ srtp_err_status_t srtp_validate_gcm()
         return status;
     }
 
-    if (octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
+    if (srtp_octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
         return srtp_err_status_fail;
     }
 
@@ -1924,7 +1929,7 @@ srtp_err_status_t srtp_validate_gcm()
         return status;
     }
 
-    if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
+    if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
         return srtp_err_status_fail;
     }
 
@@ -2027,7 +2032,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers()
     debug_print(mod_driver, "ciphertext reference:\n  %s",
                 srtp_octet_string_hex_string(srtp_ciphertext, len));
 
-    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+    if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
         return srtp_err_status_fail;
 
     /*
@@ -2049,7 +2054,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers()
         return srtp_err_status_fail;
     }
 
-    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+    if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
         return srtp_err_status_fail;
 
     status = srtp_dealloc(srtp_snd);
@@ -2063,7 +2068,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers()
     return srtp_err_status_ok;
 }
 
-#ifdef OPENSSL
+#ifdef GCM
 
 /*
  * Headers of test vectors taken from RFC 6904, Appendix A
@@ -2148,7 +2153,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm()
     debug_print(mod_driver, "ciphertext reference:\n  %s",
                 srtp_octet_string_hex_string(srtp_ciphertext, len));
 
-    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+    if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
         return srtp_err_status_fail;
 
     /*
@@ -2170,7 +2175,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm()
         return srtp_err_status_fail;
     }
 
-    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+    if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
         return srtp_err_status_fail;
 
     status = srtp_dealloc(srtp_snd);
@@ -2264,7 +2269,7 @@ srtp_err_status_t srtp_validate_aes_256()
     debug_print(mod_driver, "ciphertext reference:\n  %s",
                 octet_string_hex_string(srtp_ciphertext, len));
 
-    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
+    if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
         return srtp_err_status_fail;
     }
 
@@ -2286,7 +2291,7 @@ srtp_err_status_t srtp_validate_aes_256()
         return status;
     }
 
-    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
+    if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
         return srtp_err_status_fail;
     }
 
@@ -2424,7 +2429,7 @@ srtp_err_status_t srtp_test_empty_payload()
     return srtp_err_status_ok;
 }
 
-#ifdef OPENSSL
+#ifdef GCM
 srtp_err_status_t srtp_test_empty_payload_gcm()
 {
     srtp_t srtp_snd, srtp_recv;
@@ -2499,7 +2504,7 @@ srtp_err_status_t srtp_test_empty_payload_gcm()
 
     return srtp_err_status_ok;
 }
-#endif // OPENSSL
+#endif // GCM
 
 srtp_err_status_t srtp_test_remove_stream()
 {
@@ -2783,10 +2788,10 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams(
     srtp_policy_t policy;
     srtp_policy_t policy_mki;
 
-#ifdef OPENSSL
+#ifdef GCM
     srtp_policy_t policy_aes_gcm;
     srtp_policy_t policy_aes_gcm_mki;
-#endif // OPENSSL
+#endif // GCM
 
     memset(&policy, 0, sizeof(policy));
     srtp_crypto_policy_set_rtp_default(&policy.rtp);
@@ -2810,7 +2815,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams(
     policy_mki.keys = test_keys;
     policy_mki.num_master_keys = 2;
 
-#ifdef OPENSSL
+#ifdef GCM
     memset(&policy_aes_gcm, 0, sizeof(policy_aes_gcm));
     srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtp);
     srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtcp);
@@ -2832,7 +2837,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams(
     policy_aes_gcm_mki.key = NULL;
     policy_aes_gcm_mki.keys = test_keys;
     policy_aes_gcm_mki.num_master_keys = 2;
-#endif
+#endif // GCM
 
     /* create a send ctx with defualt profile and test_key */
     status = srtp_create(srtp_send, &policy);
@@ -2843,7 +2848,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams(
     if (status)
         return status;
 
-#ifdef OPENSSL
+#ifdef GCM
     status = srtp_create(srtp_send_aes_gcm, &policy_aes_gcm);
     if (status)
         return status;
@@ -2851,7 +2856,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams(
     status = srtp_create(srtp_send_aes_gcm_mki, &policy_aes_gcm_mki);
     if (status)
         return status;
-#endif // OPENSSL
+#endif // GCM
 
     return srtp_err_status_ok;
 }
@@ -2884,7 +2889,7 @@ srtp_err_status_t srtp_test_protect_trailer_length()
     if (length != 14)
         return srtp_err_status_fail;
 
-#ifdef OPENSSL
+#ifdef GCM
     status = srtp_get_protect_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
     if (status)
         return status;
@@ -2901,11 +2906,11 @@ srtp_err_status_t srtp_test_protect_trailer_length()
     /*  TAG Length: 16 bytes + MKI length: 4 bytes*/
     if (length != 20)
         return srtp_err_status_fail;
-#endif // OPENSSL
+#endif // GCM
 
     srtp_dealloc(srtp_send);
     srtp_dealloc(srtp_send_mki);
-#ifdef OPENSSL
+#ifdef GCM
     srtp_dealloc(srtp_send_aes_gcm);
     srtp_dealloc(srtp_send_aes_gcm_mki);
 #endif
@@ -2941,7 +2946,7 @@ srtp_err_status_t srtp_test_protect_rtcp_trailer_length()
     if (length != 18)
         return srtp_err_status_fail;
 
-#ifdef OPENSSL
+#ifdef GCM
     status =
         srtp_get_protect_rtcp_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
     if (status)
@@ -2959,11 +2964,11 @@ srtp_err_status_t srtp_test_protect_rtcp_trailer_length()
     /*  TAG Length: 16 bytes + SRTCP Trailer 4 bytes + MKI 4 bytes*/
     if (length != 24)
         return srtp_err_status_fail;
-#endif // OPENSSL
+#endif // GCM
 
     srtp_dealloc(srtp_send);
     srtp_dealloc(srtp_send_mki);
-#ifdef OPENSSL
+#ifdef GCM
     srtp_dealloc(srtp_send_aes_gcm);
     srtp_dealloc(srtp_send_aes_gcm_mki);
 #endif
@@ -3088,6 +3093,7 @@ static srtp_err_status_t test_set_receiver_roc(uint32_t packets,
         if (status) {
             return status;
         }
+
         seq++;
         ts++;
     }
@@ -3500,7 +3506,7 @@ const srtp_policy_t hmac_only_policy = {
     NULL
 };
 
-#ifdef OPENSSL
+#ifdef GCM
 const srtp_policy_t aes128_gcm_8_policy = {
     { ssrc_any_outbound, 0 }, /* SSRC */
     {
@@ -3786,7 +3792,7 @@ const srtp_policy_t *policy_array[] = {
     &hmac_only_policy,
     &aes_only_policy,
     &default_policy,
-#ifdef OPENSSL
+#ifdef GCM
     &aes128_gcm_8_policy,
     &aes128_gcm_8_cauth_policy,
     &aes256_gcm_8_policy,
index cdc9b5d5b7628786082222d3824dca5a12d3f0dd..0cea1f3c3742d93fb87e48ac4fcde7ed0331cf3e 100644 (file)
  */
 
 /*
- * Test specific.
+ * libSRTP specific.
  */
-#include "cutest.h"
+#include "../srtp/srtp.c" // Get access to static functions
 
 /*
- * libSRTP specific.
+ * Test specific.
  */
-#include "../srtp/srtp.c" // Get access to static functions
+#include "cutest.h"
 
 /*
  * Standard library.
@@ -152,14 +152,15 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
     srtp_session_keys_t session_keys;
     srtcp_hdr_t header;
     v128_t output_iv[SAMPLE_COUNT];
-    memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
     uint32_t sequence_num[SAMPLE_COUNT];
+    v128_t final_iv[SAMPLE_COUNT];
+    size_t i = 0;
+    memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
     sequence_num[0] = 0xFF;
     sequence_num[1] = 0xFF00;
     sequence_num[2] = 0xFF0000;
 
     // Postconditions
-    v128_t final_iv[SAMPLE_COUNT];
     memset(&final_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
     final_iv[0].v8[11] = 0xFF;
     final_iv[1].v8[10] = 0xFF;
@@ -170,7 +171,6 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
     memset(&header, 0, sizeof(srtcp_hdr_t));
 
     // When
-    size_t i = 0;
     for (i = 0; i < SAMPLE_COUNT; i++) {
         TEST_CHECK(srtp_calc_aead_iv_srtcp(&session_keys, &output_iv[i],
                                            sequence_num[i],
index eb203f4c4afee982bb249380ae661e1417701a36..2abc28e7f9ea135c8d8ac9137ddaf4ec3bcc4508 100644 (file)
  *
  */
 
+#include "config.h"
 #include "util.h"
 
 #include <string.h>
 #include <stdint.h>
 
-char bit_string[MAX_PRINT_STRING_LEN];
+/* include space for null terminator */
+char bit_string[MAX_PRINT_STRING_LEN + 1];
 
 static inline int hex_char_to_nibble(uint8_t c)
 {
@@ -151,7 +153,7 @@ char *octet_string_hex_string(const void *s, int length)
 
     /* truncate string if it would be too long */
     if (length > MAX_PRINT_STRING_LEN) {
-        length = MAX_PRINT_STRING_LEN - 1;
+        length = MAX_PRINT_STRING_LEN;
     }
 
     for (i = 0; i < length; i += 2) {