[Build-System] Update libsrtp to 2.3.0

This commit is contained in:
Andrey Volk 2020-01-09 17:17:45 +04:00
parent 1f268e0292
commit b0169c1c89
43 changed files with 2279 additions and 631 deletions

View 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 \

View 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"])
dnl Check the byte order
AC_C_BIGENDIAN
if test "${enable_optimizer}" = "yes" ; then
AC_DEFINE([OPTIMZER],[],[Enable Optimization.])
AX_CC_MAXOPT
fi
AC_CANONICAL_HOST
# 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
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
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])
;;
*-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=""
* )
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 ;)])
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
AC_DEFINE_UNQUOTED([inline],[$IN_LINE],[sunpro is bad at inline])
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])])
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.])
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
AC_MSG_RESULT($enable_kernel_linux)
done
dnl Check for /dev/urandom
AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom,
[AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])
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
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_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))
fi
dnl Check the byte order
AC_C_BIGENDIAN
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).])
int main(void)
{
int fd = socket(0, 0, 0);
if (fd < 0)
return -1;
else
AC_DEFINE(CPU_CISC, 1)
return 0;
}
])],
[ac_cv_func_socket=yes
AC_MSG_RESULT([yes])],
[LIBS="$SAVELIBS"
AC_MSG_RESULT([no])])
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 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.])
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)
AC_MSG_RESULT([$enable_debug_logging])
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)
PKG_PROG_PKG_CONFIG
AS_IF([test "x$PKG_CONFIG" != "x"], [PKG_CONFIG="$PKG_CONFIG --static"])
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 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_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])])
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.])
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])
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...])
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
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_RESULT([$enable_log_stdout])
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([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])])
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)
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])])
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"])
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_HEADERS([crypto/include/config.h:config_in.h])
AC_OUTPUT(Makefile crypto/Makefile doc/Makefile test/Makefile libsrtp2.pc)
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])

View 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."

View File

@ -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 */

View 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,

View File

@ -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 /* */
};

View 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"
@ -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;

View 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);

View 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;
}

View 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 */

View File

@ -1,5 +1,5 @@
/*
* aes_gcm_ossl.h
* aes_gcm.h
*
* Header for AES Galois Counter Mode.
*
@ -43,12 +43,15 @@
*
*/
#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 */

View 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 */

View File

@ -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 */

View File

@ -47,10 +47,10 @@
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;

View 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

View 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)

View 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);
}

View 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;

View 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);

View 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);

View 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++)

View File

@ -49,10 +49,13 @@
#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)

View File

@ -48,12 +48,12 @@
#endif
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */
#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);

View 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
}

View File

@ -54,12 +54,7 @@
#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(

View 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

View 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

View File

@ -129,6 +129,11 @@
<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>

View 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;
}

View File

@ -51,12 +51,13 @@
#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 -
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 -
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;

View 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;

View 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;
@ -321,7 +322,6 @@ srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
}
#include <time.h> /* for clock() */
#include <stdlib.h> /* for random() */
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);

View 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;

View 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

View 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;

View File

@ -83,23 +83,76 @@
#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,9 +215,11 @@ 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",
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);
}
@ -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:
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:
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)
{
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;
}
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 (rtp) {
/* verify rtp header */
if (dcdr->message.header.version != 2) {
if (message.header.version != 2) {
return;
}
if (dcdr->srtp_ctx == NULL) {
status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
if (status) {
exit(1);
}
}
status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
if (status) {
dcdr->error_cnt++;
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)

View File

@ -52,13 +52,22 @@
#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);
srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
unsigned int ssrc);
int rtp_decoder_deinit(rtp_decoder_t decoder);
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);
void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
const char *msg,
void *data);
#endif /* RTP_DECODER_H */

View 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);

View File

@ -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

View File

@ -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

View File

@ -61,13 +61,13 @@
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,

View File

@ -43,16 +43,16 @@
*
*/
/*
* Test specific.
*/
#include "cutest.h"
/*
* libSRTP specific.
*/
#include "../srtp/srtp.c" // Get access to static functions
/*
* Test specific.
*/
#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],

View File

@ -42,12 +42,14 @@
*
*/
#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) {