FS-11816: [Build-System] Update libsrtp to 2.2.0

This commit is contained in:
Andrey Volk 2019-04-26 15:31:40 +04:00
parent 239bf913f4
commit f82321ee0c
93 changed files with 11420 additions and 11604 deletions

79
libs/srtp/.clang-format Normal file
View File

@ -0,0 +1,79 @@
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: false
BraceWrapping:
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ContinuationIndentWidth: 4
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
PenaltyBreakBeforeFirstCallParameter: 16
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000
PenaltyReturnTypeOnItsOwnLine: 9000
Cpp11BracedListStyle: false
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

50
libs/srtp/.gitignore vendored Normal file
View File

@ -0,0 +1,50 @@
# Misc crap
*~
old
old?
*.pc
# Object files
*.o
# Libraries
*.lib
*.a
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
# srtp things
Debug
Makefile
Root
autom4te.cache
config.log
config.status
crypto/include/config.h
crypto/test/aes_calc
crypto/test/cipher_driver
crypto/test/datatypes_driver
crypto/test/env
crypto/test/kernel_driver
crypto/test/rand_gen
crypto/test/sha1_driver
crypto/test/stat_driver
crypto/test/rand_gen_soak
tables/aes_tables
test/dtls_srtp_driver
test/rdbx_driver
test/replay_driver
test/roc_driver
test/rtp_decoder
test/rtpw
test/srtp_driver
test/test_srtp

131
libs/srtp/.travis.yml Normal file
View File

@ -0,0 +1,131 @@
dist: trusty
sudo: false
language: c
env:
global:
- secure: "QD09MuUxftXRXtz7ZrB7S0NV/3O9yVhjvIlCSbXN8B87rNSDC8wxMThKMT7iZewnqGk53m+Up19PiMw5ERlHose5tm2cmY1FO/l+c9oAyWZaAL+4XNXryq6zI5F5FX5I61NbfqV3xcnfLTI2QIJF6WqDojNxhPjTbNzQGxIDuqw="
matrix:
include:
# default linux build with gcc
- os: linux
env:
- TEST="linux gcc"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
script:
- CC=gcc-6 EXTRA_CFLAGS=-Werror ./configure
- make
- make runtest
# linux build with openssl and gcc
- os: linux
env:
- TEST="linux gcc (openssl)"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
script:
- CC=gcc-6 EXTRA_CFLAGS=-Werror ./configure --enable-openssl
- make
- make runtest
# linux build with openssl and clang
- os: linux
env:
- TEST="linux clang (openssl)"
addons:
apt:
packages:
- clang
script:
- CC=clang EXTRA_CFLAGS=-Werror ./configure --enable-openssl
- make
- make runtest
# default osx build with xcode (clang)
- os: osx
env:
- TEST="osx XCode 8.2"
osx_image: xcode8.2
script:
- EXTRA_CFLAGS=-Werror ./configure
- make
- make runtest
# code format check
- os: linux
env:
- TEST="clang-format"
addons:
apt:
packages:
- clang-format-3.9
script:
- CLANG_FORMAT=clang-format-3.9 ./format.sh -d
# valgrind
- os: linux
env:
- TEST="valgrind (openssl)"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
- valgrind
script:
- CC=gcc-6 ./configure --enable-openssl
- make
- make runtest-valgrind
# big-endian
- os: linux
sudo: true
env:
- TEST="big-endian"
services:
- docker
addons:
apt:
packages:
- qemu-user-static
- qemu-system-mips
before_install:
- sudo docker run --volume $(pwd):/src --workdir /src --name mipsX --tty --detach ubuntu:16.04 tail
- sudo docker exec --tty mipsX apt-get update
- sudo docker exec --tty mipsX apt-get install build-essential -y
- sudo docker exec --tty mipsX apt-get install gcc-mips-linux-gnu -y
script:
- sudo docker exec --tty mipsX bash -c 'EXTRA_CFLAGS=-static CC=mips-linux-gnu-gcc ./configure --host=mips-linux-gnu'
- sudo docker exec --tty mipsX make
- sudo docker kill mipsX
- file test/srtp_driver
- make runtest
# coverity scan
- os: linux
env:
- TEST="Coverity Scan"
addons:
coverity_scan:
project:
name: "cisco-libSRTP"
description: "Build submitted via Travis CI"
version: 2
notification_email: pabuhler@cisco.com
build_command_prepend: "./configure"
build_command: "make"
branch_pattern: master
script:
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-

View File

@ -1 +1 @@
Wed Apr 9 03:14:42 CDT 2014
Fri Apr 26 00:00:02 CDT 2019

View File

@ -1,5 +1,65 @@
Changelog
2.2.0-pre (This version)
Major changes
All code has been reformatted to be consistent. A .clang-format file and format.sh script has been added that can be use to verify and enforce consistent formatting. An automated check on code formatting is now part of travis build.
Other changes
PR #409 - Compatibilty with LibreSSL
PR #406 - Fix unprotect when pktlen < (2*mki_size + tag_len)
PR #405 - Prevent potential double free
PR #404 - Add back extern to global variables
PR #403 - Set gcm IV directly with EVP_CipherInit_ex
PR #401 - Fix memory access issue in srtp_get_session_keys()
PR #398 - Fix memory access fixes when invalid profiles where used
PR #391 - Return NULL when allocating memory of size zero
PR #390 - Bitvector of length zero is not valid
PR #385 - Treat warnings as errors on travis builds
PR #388 - Moved externs from crypto_kernel into its own header
PR #379 - Fixed several compiler warnings from Firefox builds
PR #377 - Removed variable init code in rdbx which never gets used
PR #381 - Added error in case the platform is not detected
PR #376 - Add coverity scan to travis builds
PR #374 - Add a big endian build on travis
PR #373 - Fixed buffer size issue in test/srtp_driver.c
PR #372 - Make rtp_decoder compile on MinGW
PR #367 - Rename configure.in to configure.ac
PR #365 - Replace calls to free() with srtp_crypto_free()
PR #364 - Add valgrind to travis and fix leaks in tests
PR #363 - Change smtp_crypto_alloc to initialize memory to zero
PR #354 - Fix potential leak if cloning of stream fails
PR #340 - Fix potential leak in srtp_add_stream()
PR #323 - Fix running test in out of source builds
Issue #316 - Remove VERSION file
2.1.0
Compatibility changes
@ -164,4 +224,4 @@ Other changes
PR #302 - Fix warning regarding unused variable
PR #303 - Makefile.in: Add gnu as match for shared lib suffix
PR #303 - Makefile.in: Add gnu as match for shared lib suffix

View File

@ -1,35 +0,0 @@
/*
*
* Copyright (c) 2001-2005 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.
*
*/

View File

@ -1,236 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script). Here is a another example:
/bin/bash ./configure CONFIG_SHELL=/bin/bash
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
configuration-related scripts to be executed by `/bin/bash'.
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@ -34,7 +34,8 @@ libsrtp_la_SOURCES += gdoi/srtp+gdoi.c
endif
library_includedir = $(prefix)/include/srtp
library_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/include/auth.h \
library_include_HEADERS = include/srtp.h include/ut_sim.h crypto/include/auth.h \
crypto/include/cipher_types.h \
crypto/include/datatypes.h crypto/include/integers.h crypto/include/null_cipher.h \
crypto/include/rdbx.h crypto/include/aes_icm.h crypto/include/cipher.h crypto/include/crypto_types.h \
crypto/include/err.h crypto/include/sha1.h \
@ -43,4 +44,4 @@ library_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/i
crypto/include/hmac.h crypto/include/null_auth.h crypto/include/rdb.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = srtp-1.42.pc
pkgconfig_DATA = libsrtp2.pc

View File

@ -1,3 +1,6 @@
[![Build Status](https://travis-ci.org/cisco/libsrtp.svg?branch=master)](https://travis-ci.org/cisco/libsrtp)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/14274/badge.svg)](https://scan.coverity.com/projects/cisco-libsrtp)
<a name="introduction-to-libsrtp"></a>
# Introduction to libSRTP
@ -51,6 +54,7 @@ because it does its work behind the scenes.
- [Supported Features](#supported-features)
- [Implementation Notes](#implementation-notes)
- [Installing and Building libSRTP](#installing-and-building-libsrtp)
- [Changing Build Configuration](#changing-build-configuration)
- [Applications](#applications)
- [Example Code](#example-code)
- [Credits](#credits)
@ -291,6 +295,26 @@ OpenBSD (sparc-unknown-openbsd2.7).
--------------------------------------------------------------------------------
<a name="changing-build-configuration"></a>
## Changing Build Configuration
To build the `./configure` script mentioned above, libSRTP relies on the
[automake](https://www.gnu.org/software/automake/) toolchain. Since
`./configure` is built from `configure.in` by automake, if you make changes in
how `./configure` works (e.g., to add a new library dependency), you will need
to rebuild `./configure` and commit the updated version. In addition to
automake itself, you will need to have the `pkgconfig` tools installed as well.
For example, on macOS:
```
brew install automake pkgconfig
# Edit configure.in
autoremake -ivf
```
--------------------------------------------------------------------------------
<a name="applications"></a>
# Applications
@ -397,6 +421,9 @@ uint8_t key[30] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
// initialize libSRTP
srtp_init();
// default policy values
memset(&policy, 0x0, sizeof(srtp_policy_t));
// set policy to describe a policy for an SRTP stream
crypto_policy_set_rtp_default(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);

View File

@ -1,66 +0,0 @@
TODO List
1.4.1
- document which fields are in NBO/HBO, and check for consistency.
- move HAVE_U_LONG_LONG inside of datatypes.c, or some other
separate file
- re-write configure.in to make cross-compilation easier
- eliminate GENERIC_AESICM by generalizing the code a bit
Older comments
- add tests for key_limit_t datatype
- move octet_get_weight() from datatypes.c to math.c (any other
funcs?)
Changes and additions planned
Make cipher and auth dealloc() functions zeroize the key-storage
areas before calling free().
Eliminate key_len from auth_init()
Doucument internal APIs (cipher, auth, srtp_protect, ...)
SRTP options not (yet) included in this libaray:
- the aes-f8-mode cipher
- the Master Key Index
- re-keying using the key derivation function (only the initial
use of the PRF has been implemented, as it's sufficient
for most uses)
(OLD) PLANNED CHANGES
strip out test/lfsr.c
Write new documentation!!!
Fix the x86 assembly code in aes.c.
Eliminate /* DAM */ - there's one in srtp.c
Change debugging so that it can print more than one line. Or perhaps
just change it so that a single check of the debug-enabled flag is
needed.
Improve interface between cipher and rdbx - perhaps generalize rdbx
into 'nonce' datatype.
Make rijndael_icm accept variable sized keys.
Add rdbx functions that allow different-sized explicit sequence
numbers to be used.
Write uniform byte-buffering code for PRFs, preferably as macros.
Consider eliminating low-level alloc functions in favor of len()
functions, so that there need not be multiple allocations within a
particular alloc() function.

View File

@ -1 +0,0 @@
2.1.0-pre

View File

@ -1,6 +0,0 @@
m4_include([build/config/ax_compiler_vendor.m4])
m4_include([build/config/ax_cflags_warn_all_ansi.m4])
m4_include([build/config/ax_cc_maxopt.m4])
m4_include([build/config/ax_check_compiler_flags.m4])
m4_include([build/config/ac_gcc_archflag.m4])
m4_include([build/config/ac_gcc_x86_cpuid.m4])

View File

@ -181,5 +181,4 @@ typedef __int64 int64_t;
#ifdef _MSC_VER
#pragma warning(disable:4311)
#define OPENSSL
#endif

View File

@ -1,182 +0,0 @@
/* crypto/include/config.h. Generated by configure. */
/* config_in.h. Generated from configure.in by autoheader. */
#if (_MSC_VER >= 1400)
# define HAVE_RAND_S 1
# define _CRT_RAND_S
#endif
/* Define if building for a CISC machine (e.g. Intel). */
#define CPU_CISC 1
/* Define if building for a RISC machine (assume slow byte access). */
/* #undef CPU_RISC */
/* Define to enabled debug logging for all mudules. */
#undef ENABLE_DEBUG_LOGGING
/* Logging statments will be writen to this file. */
/* #undef ERR_REPORTING_FILE */
/* Define to redirect logging to stdout. */
#undef ERR_REPORTING_STDOUT
/* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the `inet_aton' function. */
/* #undef HAVE_INET_ATON */
/* Define to 1 if the system has the type `int16_t'. */
#define HAVE_INT16_T 1
/* Define to 1 if the system has the type `int32_t'. */
#define HAVE_INT32_T 1
/* Define to 1 if the system has the type `int8_t'. */
#define HAVE_INT8_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <machine/types.h> header file. */
/* #undef HAVE_MACHINE_TYPES_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Define to 1 if you have the `socket' function. */
/* #undef HAVE_SOCKET */
/* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/int_types.h> header file. */
/* #undef HAVE_SYS_INT_TYPES_H */
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
/* #undef HAVE_SYS_UIO_H */
/* Define to 1 if the system has the type `uint16_t'. */
#define HAVE_UINT16_T 1
/* Define to 1 if the system has the type `uint32_t'. */
#define HAVE_UINT32_T 1
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if the system has the type `uint8_t'. */
#define HAVE_UINT8_T 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the `usleep' function. */
/* #undef HAVE_USLEEP */
/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1
/* Define to 1 if you have the <winsock2.h> header file. */
#define HAVE_WINSOCK2_H 1
/* Define to use X86 inlined assembly code */
/* #undef HAVE_X86 */
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* The size of a `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG 4
/* The size of a `unsigned long long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG_LONG 8
/* Define to use GDOI. */
/* #undef SRTP_GDOI */
/* Define to compile for kernel contexts. */
/* #undef SRTP_KERNEL */
/* Define to compile for Linux kernel context. */
/* #undef SRTP_KERNEL_LINUX */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define 'inline' to nothing, since the MSVC compiler doesn't support it. */
#define inline
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
#if (_MSC_VER >= 1400) // VC8+
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifndef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#endif
#endif // VC8+
#ifndef uint32_t
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
#endif
#ifdef _MSC_VER
#pragma warning(disable:4311)
#endif

View File

@ -333,7 +333,7 @@ AM_CONDITIONAL([GDOI],[test "SRTP_GDOI" = "1"])
AC_CONFIG_HEADERS(crypto/include/config.h:config_in.h)
AC_OUTPUT(Makefile crypto/Makefile doc/Makefile test/Makefile srtp-1.42.pc)
AC_OUTPUT(Makefile crypto/Makefile doc/Makefile test/Makefile libsrtp2.pc)
# This is needed when building outside the source dir.
AS_MKDIR_P(crypto/cipher)

View File

@ -1,4 +1,4 @@
# Makefile for libcryptomodule.a
# Makefile for crypto test suite
#
# David A. McGrew
# Cisco Systems, Inc.
@ -9,14 +9,14 @@ top_builddir = @top_builddir@
VPATH = @srcdir@
CC = @CC@
INCDIR = -Iinclude -I$(srcdir)/include
INCDIR = -Iinclude -I$(srcdir)/include -I$(top_srcdir)/include
DEFS = @DEFS@
CPPFLAGS= @CPPFLAGS@
CFLAGS = @CFLAGS@
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@ -L. -L..
COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
CRYPTOLIB = -lsrtp
CRYPTOLIB = -lsrtp2
RANLIB = @RANLIB@
@ -37,16 +37,16 @@ endif
.PHONY: dummy all runtest clean superclean
dummy : all runtest
dummy : all runtest
# test applications
# test applications
ifneq (1, $(USE_OPENSSL))
AES_CALC = test/aes_calc$(EXE)
endif
testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
test/stat_driver$(EXE) test/sha1_driver$(EXE) \
test/kernel_driver$(EXE) $(AES_CALC) test/rand_gen$(EXE) \
test/kernel_driver$(EXE) $(AES_CALC) \
test/env$(EXE)
# data values used to test the aes_calc application for AES-128
@ -73,7 +73,6 @@ endif
test/stat_driver$(EXE) >/dev/null
test/sha1_driver$(EXE) -v >/dev/null
test/kernel_driver$(EXE) -v >/dev/null
test/rand_gen$(EXE) -n 256 >/dev/null
@echo "crypto test applications passed."
@ -82,16 +81,15 @@ endif
%.o: %.c
$(COMPILE) -c $< -o $@
%$(EXE): %.c
$(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)
%$(EXE): %.c $(srcdir)/../test/getopt_s.c
$(COMPILE) $(LDFLAGS) $< $(srcdir)/../test/getopt_s.c -o $@ $(CRYPTOLIB) $(LIBS)
all: $(testapp)
# housekeeping functions
clean:
rm -f libcryptomodule.a
rm -f $(testapp) *.o */*.o
rm -f $(testapp) *.o */*.o
for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
rm -f `find . -name "*.[ch]~*~"`
rm -rf latex
@ -99,13 +97,4 @@ clean:
superclean: clean
rm -f *core TAGS ktrace.out
# the target 'package' builds a compressed tar archive of the source code
distname = crypto-$(shell cat VERSION)
package: superclean
cd ..; tar cvzf $(distname).tgz crypto/
# EOF

View File

@ -44,7 +44,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "aes.h"
@ -63,7 +63,7 @@
*/
#ifndef WORDS_BIGENDIAN
/* clang-format off */
static const uint32_t T0[256] = {
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
@ -130,7 +130,9 @@ static const uint32_t T0[256] = {
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T1[256] = {
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
@ -197,7 +199,9 @@ static const uint32_t T1[256] = {
0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11,
0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T2[256] = {
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
@ -264,7 +268,9 @@ static const uint32_t T2[256] = {
0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f,
0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T3[256] = {
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
@ -331,7 +337,9 @@ static const uint32_t T3[256] = {
0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
};
/* clang-format on */
/* clang-format off */
static const uint32_t U0[256] = {
0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
@ -398,7 +406,9 @@ static const uint32_t U0[256] = {
0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0,
};
/* clang-format on */
/* clang-format off */
static const uint32_t U1[256] = {
0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96,
0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93,
@ -465,7 +475,9 @@ static const uint32_t U1[256] = {
0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490,
0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042,
};
/* clang-format on */
/* clang-format off */
static const uint32_t U2[256] = {
0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e,
0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303,
@ -532,7 +544,9 @@ static const uint32_t U2[256] = {
0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1,
0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257,
};
/* clang-format on */
/* clang-format off */
static const uint32_t U3[256] = {
0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27,
0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3,
@ -599,9 +613,10 @@ static const uint32_t U3[256] = {
0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156,
0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8,
};
/* clang-format on */
#else /* assume big endian */
/* clang-format off */
static const uint32_t T0[256] = {
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
@ -668,7 +683,9 @@ static const uint32_t T0[256] = {
0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T1[256] = {
0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
@ -735,7 +752,9 @@ static const uint32_t T1[256] = {
0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T2[256] = {
0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
@ -802,7 +821,9 @@ static const uint32_t T2[256] = {
0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f,
0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
};
/* clang-format on */
/* clang-format off */
static const uint32_t T3[256] = {
0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
@ -869,7 +890,9 @@ static const uint32_t T3[256] = {
0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e,
0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
};
/* clang-format on */
/* clang-format off */
static const uint32_t U0[256] = {
0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
@ -936,7 +959,9 @@ static const uint32_t U0[256] = {
0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190,
0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
};
/* clang-format on */
/* clang-format off */
static const uint32_t U1[256] = {
0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
@ -1003,7 +1028,9 @@ static const uint32_t U1[256] = {
0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857
};
/* clang-format on */
/* clang-format off */
static const uint32_t U2[256] = {
0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3,
@ -1070,7 +1097,9 @@ static const uint32_t U2[256] = {
0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8
};
/* clang-format on */
/* clang-format off */
static const uint32_t U3[256] = {
0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
@ -1137,16 +1166,15 @@ static const uint32_t U3[256] = {
0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064,
0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0
};
/* clang-format on */
#endif
/*
* the following tables (aes_sbox, aes_inv_sbox, T4, U4) are
* endian-neutral
*/
static const uint8_t
aes_sbox[256] = {
/* clang-format off */
static const uint8_t aes_sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
@ -1180,10 +1208,11 @@ static const uint8_t
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
/* clang-format on */
#ifndef CPU_RISC
static const uint8_t
aes_inv_sbox[256] = {
/* clang-format off */
static const uint8_t aes_inv_sbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
@ -1217,11 +1246,12 @@ static const uint8_t
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
/* clang-format on */
#endif /* ! CPU_RISC */
#ifdef CPU_RISC
static const uint32_t
T4[256] = {
/* clang-format off */
static const uint32_t T4[256] = {
0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
@ -1287,7 +1317,9 @@ static const uint32_t
0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
};
/* clang-format on */
/* clang-format off */
static const uint32_t U4[256] = {
0x52525252, 0x9090909, 0x6a6a6a6a, 0xd5d5d5d5,
0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838,
@ -1354,6 +1386,7 @@ static const uint32_t U4[256] = {
0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363,
0x55555555, 0x21212121, 0xc0c0c0c, 0x7d7d7d7d
};
/* clang-format on */
#endif /* CPU_RISC */
#define gf2_8_field_polynomial 0x1B
@ -1363,16 +1396,13 @@ static const uint32_t U4[256] = {
* next gf2_8 value in the cyclic representation of that field. The
* value z should be an uint8_t.
*/
#define gf2_8_shift(z) (((z) & 128) ? \
(((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1))
#define gf2_8_shift(z) \
(((z)&128) ? (((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1))
/* aes internals */
extern srtp_debug_module_t srtp_mod_aes_icm;
static void
aes_128_expand_encryption_key (const uint8_t *key,
srtp_aes_expanded_key_t *expanded_key)
static void aes_128_expand_encryption_key(const uint8_t *key,
srtp_aes_expanded_key_t *expanded_key)
{
int i;
uint8_t rc;
@ -1391,14 +1421,17 @@ aes_128_expand_encryption_key (const uint8_t *key,
/* loop over round keys */
for (i = 1; i < 11; i++) {
/* munge first word of round key */
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i - 1].v8[15]];
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i - 1].v8[12]];
expanded_key->round[i].v8[0] =
aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
expanded_key->round[i].v8[1] =
aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[2] =
aes_sbox[expanded_key->round[i - 1].v8[15]];
expanded_key->round[i].v8[3] =
aes_sbox[expanded_key->round[i - 1].v8[12]];
expanded_key->round[i].v32[0] ^= expanded_key->round[i - 1].v32[0];
expanded_key->round[i].v32[0] ^= expanded_key->round[i - 1].v32[0];
/* set remaining 32 bit words to the exor of the one previous with
* the one four words previous */
@ -1419,13 +1452,11 @@ aes_128_expand_encryption_key (const uint8_t *key,
/* modify round constant */
rc = gf2_8_shift(rc);
}
}
static void
aes_256_expand_encryption_key (const unsigned char *key,
srtp_aes_expanded_key_t *expanded_key)
static void aes_256_expand_encryption_key(const unsigned char *key,
srtp_aes_expanded_key_t *expanded_key)
{
int i;
uint8_t rc;
@ -1447,24 +1478,31 @@ aes_256_expand_encryption_key (const unsigned char *key,
/* loop over rest of round keys */
for (i = 2; i < 15; i++) {
/* munge first word of round key */
if ((i & 1) == 0) {
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i - 1].v8[15]];
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i - 1].v8[12]];
expanded_key->round[i].v8[0] =
aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
expanded_key->round[i].v8[1] =
aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[2] =
aes_sbox[expanded_key->round[i - 1].v8[15]];
expanded_key->round[i].v8[3] =
aes_sbox[expanded_key->round[i - 1].v8[12]];
/* modify round constant */
rc = gf2_8_shift(rc);
}else {
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i - 1].v8[12]];
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i - 1].v8[13]];
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i - 1].v8[15]];
} else {
expanded_key->round[i].v8[0] =
aes_sbox[expanded_key->round[i - 1].v8[12]];
expanded_key->round[i].v8[1] =
aes_sbox[expanded_key->round[i - 1].v8[13]];
expanded_key->round[i].v8[2] =
aes_sbox[expanded_key->round[i - 1].v8[14]];
expanded_key->round[i].v8[3] =
aes_sbox[expanded_key->round[i - 1].v8[15]];
}
expanded_key->round[i].v32[0] ^= expanded_key->round[i - 2].v32[0];
expanded_key->round[i].v32[0] ^= expanded_key->round[i - 2].v32[0];
/* set remaining 32 bit words to the exor of the one previous with
* the one eight words previous */
@ -1482,31 +1520,32 @@ aes_256_expand_encryption_key (const unsigned char *key,
debug_print2(srtp_mod_aes_icm,
"expanded key[%d]: %s", i, v128_hex_string(&expanded_key->round[i]));
#endif
}
}
srtp_err_status_t srtp_aes_expand_encryption_key (const uint8_t *key,
int key_len,
srtp_aes_expanded_key_t *expanded_key)
srtp_err_status_t srtp_aes_expand_encryption_key(
const uint8_t *key,
int key_len,
srtp_aes_expanded_key_t *expanded_key)
{
if (key_len == 16) {
aes_128_expand_encryption_key(key, expanded_key);
return srtp_err_status_ok;
}else if (key_len == 24) {
} else if (key_len == 24) {
/* AES-192 not yet supported */
return srtp_err_status_bad_param;
}else if (key_len == 32) {
} else if (key_len == 32) {
aes_256_expand_encryption_key(key, expanded_key);
return srtp_err_status_ok;
}else {
} else {
return srtp_err_status_bad_param;
}
}
srtp_err_status_t srtp_aes_expand_decryption_key (const uint8_t *key,
int key_len,
srtp_aes_expanded_key_t *expanded_key)
srtp_err_status_t srtp_aes_expand_decryption_key(
const uint8_t *key,
int key_len,
srtp_aes_expanded_key_t *expanded_key)
{
int i;
srtp_err_status_t status;
@ -1521,7 +1560,8 @@ srtp_err_status_t srtp_aes_expand_decryption_key (const uint8_t *key,
for (i = 0; i < num_rounds / 2; i++) {
v128_t tmp;
v128_copy(&tmp, &expanded_key->round[num_rounds - i]);
v128_copy(&expanded_key->round[num_rounds - i], &expanded_key->round[i]);
v128_copy(&expanded_key->round[num_rounds - i],
&expanded_key->round[i]);
v128_copy(&expanded_key->round[i], &tmp);
}
@ -1538,6 +1578,7 @@ srtp_err_status_t srtp_aes_expand_decryption_key (const uint8_t *key,
uint32_t tmp;
#ifdef WORDS_BIGENDIAN
/* clang-format off */
tmp = expanded_key->round[i].v32[0];
expanded_key->round[i].v32[0] =
U0[T4[(tmp >> 24) ] & 0xff] ^
@ -1593,31 +1634,32 @@ srtp_err_status_t srtp_aes_expand_decryption_key (const uint8_t *key,
U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
U1[T4[(tmp >> 8) & 0xff] & 0xff] ^
U0[T4[(tmp) & 0xff] & 0xff];
#endif /* WORDS_BIGENDIAN */
/* clang-format on */
#endif /* WORDS_BIGENDIAN */
#else /* assume CPU_CISC */
uint32_t c0, c1, c2, c3;
c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]]
^ U1[aes_sbox[expanded_key->round[i].v8[1]]]
^ U2[aes_sbox[expanded_key->round[i].v8[2]]]
^ U3[aes_sbox[expanded_key->round[i].v8[3]]];
c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]] ^
U1[aes_sbox[expanded_key->round[i].v8[1]]] ^
U2[aes_sbox[expanded_key->round[i].v8[2]]] ^
U3[aes_sbox[expanded_key->round[i].v8[3]]];
c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]]
^ U1[aes_sbox[expanded_key->round[i].v8[5]]]
^ U2[aes_sbox[expanded_key->round[i].v8[6]]]
^ U3[aes_sbox[expanded_key->round[i].v8[7]]];
c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]] ^
U1[aes_sbox[expanded_key->round[i].v8[5]]] ^
U2[aes_sbox[expanded_key->round[i].v8[6]]] ^
U3[aes_sbox[expanded_key->round[i].v8[7]]];
c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]]
^ U1[aes_sbox[expanded_key->round[i].v8[9]]]
^ U2[aes_sbox[expanded_key->round[i].v8[10]]]
^ U3[aes_sbox[expanded_key->round[i].v8[11]]];
c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]] ^
U1[aes_sbox[expanded_key->round[i].v8[9]]] ^
U2[aes_sbox[expanded_key->round[i].v8[10]]] ^
U3[aes_sbox[expanded_key->round[i].v8[11]]];
c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]]
^ U1[aes_sbox[expanded_key->round[i].v8[13]]]
^ U2[aes_sbox[expanded_key->round[i].v8[14]]]
^ U3[aes_sbox[expanded_key->round[i].v8[15]]];
c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]] ^
U1[aes_sbox[expanded_key->round[i].v8[13]]] ^
U2[aes_sbox[expanded_key->round[i].v8[14]]] ^
U3[aes_sbox[expanded_key->round[i].v8[15]]];
expanded_key->round[i].v32[0] = c0;
expanded_key->round[i].v32[1] = c1;
@ -1632,61 +1674,57 @@ srtp_err_status_t srtp_aes_expand_decryption_key (const uint8_t *key,
#ifdef CPU_CISC
static inline void aes_round (v128_t *state, const v128_t *round_key)
static inline void aes_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
/* compute the columns of the output square in terms of the octets
of state, using the tables T0, T1, T2, T3 */
column0 = T0[state->v8[0]] ^ T1[state->v8[5]]
^ T2[state->v8[10]] ^ T3[state->v8[15]];
column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
T3[state->v8[15]];
column1 = T0[state->v8[4]] ^ T1[state->v8[9]]
^ T2[state->v8[14]] ^ T3[state->v8[3]];
column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
T3[state->v8[3]];
column2 = T0[state->v8[8]] ^ T1[state->v8[13]]
^ T2[state->v8[2]] ^ T3[state->v8[7]];
column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
T3[state->v8[7]];
column3 = T0[state->v8[12]] ^ T1[state->v8[1]]
^ T2[state->v8[6]] ^ T3[state->v8[11]];
column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
T3[state->v8[11]];
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_inv_round (v128_t *state, const v128_t *round_key)
static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
/* compute the columns of the output square in terms of the octets
of state, using the tables U0, U1, U2, U3 */
column0 = U0[state->v8[0]] ^ U1[state->v8[13]]
^ U2[state->v8[10]] ^ U3[state->v8[7]];
column0 = U0[state->v8[0]] ^ U1[state->v8[13]] ^ U2[state->v8[10]] ^
U3[state->v8[7]];
column1 = U0[state->v8[4]] ^ U1[state->v8[1]]
^ U2[state->v8[14]] ^ U3[state->v8[11]];
column1 = U0[state->v8[4]] ^ U1[state->v8[1]] ^ U2[state->v8[14]] ^
U3[state->v8[11]];
column2 = U0[state->v8[8]] ^ U1[state->v8[5]]
^ U2[state->v8[2]] ^ U3[state->v8[15]];
column2 = U0[state->v8[8]] ^ U1[state->v8[5]] ^ U2[state->v8[2]] ^
U3[state->v8[15]];
column3 = U0[state->v8[12]] ^ U1[state->v8[9]]
^ U2[state->v8[6]] ^ U3[state->v8[3]];
column3 = U0[state->v8[12]] ^ U1[state->v8[9]] ^ U2[state->v8[6]] ^
U3[state->v8[3]];
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_final_round (v128_t *state, const v128_t *round_key)
static inline void aes_final_round(v128_t *state, const v128_t *round_key)
{
uint8_t tmp;
@ -1722,7 +1760,7 @@ static inline void aes_final_round (v128_t *state, const v128_t *round_key)
v128_xor_eq(state, round_key);
}
static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
{
uint8_t tmp;
@ -1758,201 +1796,143 @@ static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
v128_xor_eq(state, round_key);
}
#elif CPU_RISC
static inline void aes_round (v128_t *state, const v128_t *round_key)
static inline void aes_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
/* compute the columns of the output square in terms of the octets
of state, using the tables T0, T1, T2, T3 */
/* compute the columns of the output square in terms of the octets
of state, using the tables T0, T1, T2, T3 */
#ifdef WORDS_BIGENDIAN
column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff]
^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] ^
T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff]
^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] ^
T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff]
^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] ^
T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff]
^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] ^
T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
#else
column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff]
^ T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] ^
T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff]
^ T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] ^
T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff]
^ T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];
column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff] ^
T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];
column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff]
^ T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];
column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff] ^
T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];
#endif /* WORDS_BIGENDIAN */
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_inv_round (v128_t *state, const v128_t *round_key)
static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
/* compute the columns of the output square in terms of the octets
of state, using the tables U0, U1, U2, U3 */
/* compute the columns of the output square in terms of the octets
of state, using the tables U0, U1, U2, U3 */
#ifdef WORDS_BIGENDIAN
column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff]
^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff] ^
U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff]
^ U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] ^
U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff]
^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] ^
U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff]
^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff] ^
U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
#else
column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff]
^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[(state->v32[1] >> 24) & 0xff];
column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff] ^
U2[(state->v32[2] >> 16) & 0xff] ^
U3[(state->v32[1] >> 24) & 0xff];
column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff]
^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[(state->v32[2] >> 24) & 0xff];
column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff] ^
U2[(state->v32[3] >> 16) & 0xff] ^
U3[(state->v32[2] >> 24) & 0xff];
column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff]
^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[(state->v32[3] >> 24) & 0xff];
column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff] ^
U2[(state->v32[0] >> 16) & 0xff] ^
U3[(state->v32[3] >> 24) & 0xff];
column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff]
^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[(state->v32[0] >> 24) & 0xff];
column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff] ^
U2[(state->v32[1] >> 16) & 0xff] ^
U3[(state->v32[0] >> 24) & 0xff];
#endif /* WORDS_BIGENDIAN */
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_final_round (v128_t *state, const v128_t *round_key)
static inline void aes_final_round(v128_t *state, const v128_t *round_key)
{
uint32_t tmp0, tmp1, tmp2, tmp3;
#ifdef WORDS_BIGENDIAN
tmp0 = (T4[(state->v32[0] >> 24)] & 0xff000000)
^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff)
^ round_key->v32[0];
/* clang-format off */
tmp0 = (T4[(state->v32[0] >> 24)] & 0xff000000) ^
(T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[3] ) & 0xff] & 0x000000ff) ^
round_key->v32[0];
tmp1 = (T4[(state->v32[1] >> 24)] & 0xff000000)
^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff)
^ round_key->v32[1];
tmp1 = (T4[(state->v32[1] >> 24)] & 0xff000000) ^
(T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[0] ) & 0xff] & 0x000000ff) ^
round_key->v32[1];
tmp2 = (T4[(state->v32[2] >> 24)] & 0xff000000)
^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff)
^ round_key->v32[2];
tmp2 = (T4[(state->v32[2] >> 24)] & 0xff000000) ^
(T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[1] ) & 0xff] & 0x000000ff) ^
round_key->v32[2];
tmp3 = (T4[(state->v32[3] >> 24)] & 0xff000000)
^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
tmp3 = (T4[(state->v32[3] >> 24)] & 0xff000000) ^
(T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[2] ) & 0xff] & 0x000000ff) ^
round_key->v32[3];
#else
tmp0 = (T4[(state->v32[3] >> 24)] & 0xff000000)
^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[0] ) & 0xff] & 0x000000ff)
^ round_key->v32[0];
tmp0 = (T4[(state->v32[3] >> 24)] & 0xff000000) ^
(T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[0] ) & 0xff] & 0x000000ff) ^
round_key->v32[0];
tmp1 = (T4[(state->v32[0] >> 24)] & 0xff000000)
^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[1] ) & 0xff] & 0x000000ff)
^ round_key->v32[1];
tmp1 = (T4[(state->v32[0] >> 24)] & 0xff000000) ^
(T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[1] ) & 0xff] & 0x000000ff) ^
round_key->v32[1];
tmp2 = (T4[(state->v32[1] >> 24)] & 0xff000000)
^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[2] ) & 0xff] & 0x000000ff)
^ round_key->v32[2];
tmp2 = (T4[(state->v32[1] >> 24)] & 0xff000000) ^
(T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[2] ) & 0xff] & 0x000000ff) ^
round_key->v32[2];
tmp3 = (T4[(state->v32[2] >> 24)] & 0xff000000)
^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
^ (T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
^ (T4[(state->v32[3] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
#endif /* WORDS_BIGENDIAN */
state->v32[0] = tmp0;
state->v32[1] = tmp1;
state->v32[2] = tmp2;
state->v32[3] = tmp3;
}
static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
{
uint32_t tmp0, tmp1, tmp2, tmp3;
#ifdef WORDS_BIGENDIAN
tmp0 = (U4[(state->v32[0] >> 24)] & 0xff000000)
^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[1] ) & 0xff] & 0x000000ff)
^ round_key->v32[0];
tmp1 = (U4[(state->v32[1] >> 24)] & 0xff000000)
^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[2] ) & 0xff] & 0x000000ff)
^ round_key->v32[1];
tmp2 = (U4[(state->v32[2] >> 24)] & 0xff000000)
^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[3] ) & 0xff] & 0x000000ff)
^ round_key->v32[2];
tmp3 = (U4[(state->v32[3] >> 24)] & 0xff000000)
^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
#else
tmp0 = (U4[(state->v32[1] >> 24)] & 0xff000000)
^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[0] ) & 0xff] & 0x000000ff)
^ round_key->v32[0];
tmp1 = (U4[(state->v32[2] >> 24)] & 0xff000000)
^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[1] ) & 0xff] & 0x000000ff)
^ round_key->v32[1];
tmp2 = (U4[(state->v32[3] >> 24)] & 0xff000000)
^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[2] ) & 0xff] & 0x000000ff)
^ round_key->v32[2];
tmp3 = (U4[(state->v32[0] >> 24)] & 0xff000000)
^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
^ (U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00)
^ (U4[(state->v32[3] ) & 0xff] & 0x000000ff)
^ round_key->v32[3];
tmp3 = (T4[(state->v32[2] >> 24)] & 0xff000000) ^
(T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
(T4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) ^
(T4[(state->v32[3] ) & 0xff] & 0x000000ff) ^
round_key->v32[3];
/* clang-format on */
#endif /* WORDS_BIGENDIAN */
state->v32[0] = tmp0;
@ -1961,62 +1941,120 @@ static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
state->v32[3] = tmp3;
}
#elif CPU_16 /* assume 16-bit word size on processor */
static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
{
uint32_t tmp0, tmp1, tmp2, tmp3;
static inline void aes_round (v128_t *state, const v128_t *round_key)
#ifdef WORDS_BIGENDIAN
/* clang-format off */
tmp0 = (U4[(state->v32[0] >> 24)] & 0xff000000) ^
(U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[1] ) & 0xff] & 0x000000ff) ^
round_key->v32[0];
tmp1 = (U4[(state->v32[1] >> 24)] & 0xff000000) ^
(U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[2] ) & 0xff] & 0x000000ff) ^
round_key->v32[1];
tmp2 = (U4[(state->v32[2] >> 24)] & 0xff000000) ^
(U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[3] ) & 0xff] & 0x000000ff) ^
round_key->v32[2];
tmp3 = (U4[(state->v32[3] >> 24)] & 0xff000000) ^
(U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[0] ) & 0xff] & 0x000000ff) ^
round_key->v32[3];
#else
tmp0 = (U4[(state->v32[1] >> 24)] & 0xff000000) ^
(U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[3] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[0] ) & 0xff] & 0x000000ff) ^
round_key->v32[0];
tmp1 = (U4[(state->v32[2] >> 24)] & 0xff000000) ^
(U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[0] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[1] ) & 0xff] & 0x000000ff) ^
round_key->v32[1];
tmp2 = (U4[(state->v32[3] >> 24)] & 0xff000000) ^
(U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[1] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[2] ) & 0xff] & 0x000000ff) ^
round_key->v32[2];
tmp3 = (U4[(state->v32[0] >> 24)] & 0xff000000) ^
(U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
(U4[(state->v32[2] >> 8) & 0xff] & 0x0000ff00) ^
(U4[(state->v32[3] ) & 0xff] & 0x000000ff) ^
round_key->v32[3];
/* clang-format on */
#endif /* WORDS_BIGENDIAN */
state->v32[0] = tmp0;
state->v32[1] = tmp1;
state->v32[2] = tmp2;
state->v32[3] = tmp3;
}
#elif CPU_16 /* assume 16-bit word size on processor */
static inline void aes_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
uint16_t c
/* compute the columns of the output square in terms of the octets
of state, using the tables T0, T1, T2, T3 */
column0 = T0[state->v8[0]] ^ T1[state->v8[5]]
^ T2[state->v8[10]] ^ T3[state->v8[15]];
column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
T3[state->v8[15]];
column1 = T0[state->v8[4]] ^ T1[state->v8[9]]
^ T2[state->v8[14]] ^ T3[state->v8[3]];
column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
T3[state->v8[3]];
column2 = T0[state->v8[8]] ^ T1[state->v8[13]]
^ T2[state->v8[2]] ^ T3[state->v8[7]];
column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
T3[state->v8[7]];
column3 = T0[state->v8[12]] ^ T1[state->v8[1]]
^ T2[state->v8[6]] ^ T3[state->v8[11]];
column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
T3[state->v8[11]];
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_inv_round (v128_t *state, const v128_t *round_key)
static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
{
uint32_t column0, column1, column2, column3;
/* compute the columns of the output square in terms of the octets
of state, using the tables U0, U1, U2, U3 */
column0 = U0[state->v8[0]] ^ U1[state->v8[5]]
^ U2[state->v8[10]] ^ U3[state->v8[15]];
column0 = U0[state->v8[0]] ^ U1[state->v8[5]] ^ U2[state->v8[10]] ^
U3[state->v8[15]];
column1 = U0[state->v8[4]] ^ U1[state->v8[9]]
^ U2[state->v8[14]] ^ U3[state->v8[3]];
column1 = U0[state->v8[4]] ^ U1[state->v8[9]] ^ U2[state->v8[14]] ^
U3[state->v8[3]];
column2 = U0[state->v8[8]] ^ U1[state->v8[13]]
^ U2[state->v8[2]] ^ U3[state->v8[7]];
column2 = U0[state->v8[8]] ^ U1[state->v8[13]] ^ U2[state->v8[2]] ^
U3[state->v8[7]];
column3 = U0[state->v8[12]] ^ U1[state->v8[1]]
^ U2[state->v8[6]] ^ U3[state->v8[11]];
column3 = U0[state->v8[12]] ^ U1[state->v8[1]] ^ U2[state->v8[6]] ^
U3[state->v8[11]];
state->v32[0] = column0 ^ round_key->v32[0];
state->v32[1] = column1 ^ round_key->v32[1];
state->v32[2] = column2 ^ round_key->v32[2];
state->v32[3] = column3 ^ round_key->v32[3];
}
static inline void aes_final_round (v128_t *state, const v128_t *round_key)
static inline void aes_final_round(v128_t *state, const v128_t *round_key)
{
uint8_t tmp;
@ -2052,7 +2090,7 @@ static inline void aes_final_round (v128_t *state, const v128_t *round_key)
v128_xor_eq(state, round_key);
}
static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
{
uint8_t tmp;
@ -2088,12 +2126,10 @@ static inline void aes_inv_final_round (v128_t *state, const v128_t *round_key)
v128_xor_eq(state, round_key);
}
#endif /* CPU type */
#endif /* CPU type */
void srtp_aes_encrypt (v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
{
/* add in the subkey */
v128_xor_eq(plaintext, &exp_key->round[0]);
@ -2109,11 +2145,11 @@ void srtp_aes_encrypt (v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key
aes_round(plaintext, &exp_key->round[9]);
if (exp_key->num_rounds == 10) {
aes_final_round(plaintext, &exp_key->round[10]);
}else if (exp_key->num_rounds == 12) {
} else if (exp_key->num_rounds == 12) {
aes_round(plaintext, &exp_key->round[10]);
aes_round(plaintext, &exp_key->round[11]);
aes_final_round(plaintext, &exp_key->round[12]);
}else if (exp_key->num_rounds == 14) {
} else if (exp_key->num_rounds == 14) {
aes_round(plaintext, &exp_key->round[10]);
aes_round(plaintext, &exp_key->round[11]);
aes_round(plaintext, &exp_key->round[12]);
@ -2122,9 +2158,8 @@ void srtp_aes_encrypt (v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key
}
}
void srtp_aes_decrypt (v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
{
/* add in the subkey */
v128_xor_eq(plaintext, &exp_key->round[0]);
@ -2140,11 +2175,11 @@ void srtp_aes_decrypt (v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key
aes_inv_round(plaintext, &exp_key->round[9]);
if (exp_key->num_rounds == 10) {
aes_inv_final_round(plaintext, &exp_key->round[10]);
}else if (exp_key->num_rounds == 12) {
} else if (exp_key->num_rounds == 12) {
aes_inv_round(plaintext, &exp_key->round[10]);
aes_inv_round(plaintext, &exp_key->round[11]);
aes_inv_final_round(plaintext, &exp_key->round[12]);
}else if (exp_key->num_rounds == 14) {
} else if (exp_key->num_rounds == 14) {
aes_inv_round(plaintext, &exp_key->round[10]);
aes_inv_round(plaintext, &exp_key->round[11]);
aes_inv_round(plaintext, &exp_key->round[12]);

View File

@ -45,36 +45,28 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <openssl/evp.h>
#include "aes_icm_ossl.h"
#include "aes_gcm_ossl.h"
#include "alloc.h"
#include "err.h" /* for srtp_debug */
#include "err.h" /* for srtp_debug */
#include "crypto_types.h"
#include "cipher_types.h"
srtp_debug_module_t srtp_mod_aes_gcm = {
0, /* debugging is off by default */
"aes gcm" /* printable module name */
0, /* debugging is off by default */
"aes gcm" /* printable module name */
};
/*
* The following are the global singleton instances for the
* 128-bit and 256-bit GCM ciphers.
*/
extern const srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern const srtp_cipher_type_t srtp_aes_gcm_256_openssl;
/*
* For now we only support 8 and 16 octet tags. The spec allows for
* optional 12 byte tag, which may be supported in the future.
*/
#define GCM_AUTH_TAG_LEN 16
#define GCM_AUTH_TAG_LEN_8 8
#define GCM_AUTH_TAG_LEN 16
#define GCM_AUTH_TAG_LEN_8 8
/*
* This function allocates a new instance of this crypto engine.
@ -83,11 +75,14 @@ extern const srtp_cipher_type_t srtp_aes_gcm_256_openssl;
* key length includes the 14 byte salt value that is used when
* initializing the KDF.
*/
static srtp_err_status_t srtp_aes_gcm_openssl_alloc (srtp_cipher_t **c, int key_len, int tlen)
static srtp_err_status_t srtp_aes_gcm_openssl_alloc(srtp_cipher_t **c,
int key_len,
int tlen)
{
srtp_aes_gcm_ctx_t *gcm;
debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d", key_len);
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);
/*
@ -98,8 +93,7 @@ static srtp_err_status_t srtp_aes_gcm_openssl_alloc (srtp_cipher_t **c, int key_
return (srtp_err_status_bad_param);
}
if (tlen != GCM_AUTH_TAG_LEN &&
tlen != GCM_AUTH_TAG_LEN_8) {
if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
return (srtp_err_status_bad_param);
}
@ -108,15 +102,13 @@ static srtp_err_status_t srtp_aes_gcm_openssl_alloc (srtp_cipher_t **c, int key_
if (*c == NULL) {
return (srtp_err_status_alloc_fail);
}
memset(*c, 0x0, sizeof(srtp_cipher_t));
gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
if (gcm == NULL) {
srtp_crypto_free(*c);
*c = NULL;
srtp_crypto_free(*c);
*c = NULL;
return (srtp_err_status_alloc_fail);
}
memset(gcm, 0x0, sizeof(srtp_aes_gcm_ctx_t));
gcm->ctx = EVP_CIPHER_CTX_new();
if (gcm->ctx == NULL) {
@ -151,15 +143,14 @@ static srtp_err_status_t srtp_aes_gcm_openssl_alloc (srtp_cipher_t **c, int key_
return (srtp_err_status_ok);
}
/*
* This function deallocates a GCM session
*/
static srtp_err_status_t srtp_aes_gcm_openssl_dealloc (srtp_cipher_t *c)
static srtp_err_status_t srtp_aes_gcm_openssl_dealloc(srtp_cipher_t *c)
{
srtp_aes_gcm_ctx_t *ctx;
ctx = (srtp_aes_gcm_ctx_t*)c->state;
ctx = (srtp_aes_gcm_ctx_t *)c->state;
if (ctx) {
EVP_CIPHER_CTX_free(ctx->ctx);
/* zeroize the key material */
@ -179,14 +170,16 @@ static srtp_err_status_t srtp_aes_gcm_openssl_dealloc (srtp_cipher_t *c)
*
* the key is the secret key
*/
static srtp_err_status_t srtp_aes_gcm_openssl_context_init (void* cv, const uint8_t *key)
static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv,
const uint8_t *key)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
const EVP_CIPHER *evp;
c->dir = srtp_direction_any;
debug_print(srtp_mod_aes_gcm, "key: %s", srtp_octet_string_hex_string(key, c->key_size));
debug_print(srtp_mod_aes_gcm, "key: %s",
srtp_octet_string_hex_string(key, c->key_size));
switch (c->key_size) {
case SRTP_AES_256_KEY_LEN:
@ -207,35 +200,32 @@ static srtp_err_status_t srtp_aes_gcm_openssl_context_init (void* cv, const uint
return (srtp_err_status_ok);
}
/*
* aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
* the offset
*/
static srtp_err_status_t srtp_aes_gcm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
static srtp_err_status_t srtp_aes_gcm_openssl_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) {
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", v128_hex_string((v128_t*)iv));
debug_print(srtp_mod_aes_gcm, "setting iv: %s",
v128_hex_string((v128_t *)iv));
if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL,
NULL, (c->dir == srtp_direction_encrypt ? 1 : 0))) {
return (srtp_err_status_init_fail);
}
/* set IV len and the IV value, the followiong 3 calls are required */
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
return (srtp_err_status_init_fail);
}
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void*)iv)) {
return (srtp_err_status_init_fail);
}
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_IV_GEN, 0, (void*)iv)) {
if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL, iv,
(c->dir == srtp_direction_encrypt ? 1 : 0))) {
return (srtp_err_status_init_fail);
}
@ -250,7 +240,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_iv (void *cv, uint8_t *iv, srt
* aad Additional data to process for AEAD cipher suites
* aad_len length of aad buffer
*/
static srtp_err_status_t srtp_aes_gcm_openssl_set_aad (void *cv, const uint8_t *aad, uint32_t aad_len)
static srtp_err_status_t srtp_aes_gcm_openssl_set_aad(void *cv,
const uint8_t *aad,
uint32_t aad_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
int rv;
@ -262,8 +254,8 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_aad (void *cv, const uint8_t *
/*
* OpenSSL never write to address pointed by the last parameter of
* EVP_CIPHER_CTX_ctrl while EVP_CTRL_GCM_SET_TAG (in reality,
* OpenSSL copy its content to the context), so we can make
* EVP_CIPHER_CTX_ctrl while EVP_CTRL_GCM_SET_TAG (in reality,
* OpenSSL copy its content to the context), so we can make
* aad read-only in this function and all its wrappers.
*/
unsigned char dummy_tag[GCM_AUTH_TAG_LEN];
@ -286,7 +278,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_aad (void *cv, const uint8_t *
* buf data to encrypt
* enc_len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_openssl_encrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
static srtp_err_status_t srtp_aes_gcm_openssl_encrypt(void *cv,
unsigned char *buf,
unsigned int *enc_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
@ -312,7 +306,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_encrypt (void *cv, unsigned char *
* buf data to encrypt
* len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_openssl_get_tag (void *cv, uint8_t *buf, uint32_t *len)
static srtp_err_status_t srtp_aes_gcm_openssl_get_tag(void *cv,
uint8_t *buf,
uint32_t *len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
/*
@ -333,7 +329,6 @@ static srtp_err_status_t srtp_aes_gcm_openssl_get_tag (void *cv, uint8_t *buf, u
return (srtp_err_status_ok);
}
/*
* This function decrypts a buffer using AES GCM mode
*
@ -342,7 +337,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_get_tag (void *cv, uint8_t *buf, u
* buf data to encrypt
* enc_len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_gcm_openssl_decrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv,
unsigned char *buf,
unsigned int *enc_len)
{
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
@ -372,32 +369,36 @@ static srtp_err_status_t srtp_aes_gcm_openssl_decrypt (void *cv, unsigned char *
return (srtp_err_status_ok);
}
/*
* Name of this crypto engine
*/
static const char srtp_aes_gcm_128_openssl_description[] = "AES-128 GCM using openssl";
static const char srtp_aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl";
static const char srtp_aes_gcm_128_openssl_description[] =
"AES-128 GCM using openssl";
static const char srtp_aes_gcm_256_openssl_description[] =
"AES-256 GCM using openssl";
/*
* KAT values for AES self-test. These
* values we're derived from independent test code
* using OpenSSL.
*/
/* 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,
@ -409,12 +410,15 @@ static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] = {
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,
@ -428,6 +432,7 @@ static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
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 */
@ -439,7 +444,7 @@ static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
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,
GCM_AUTH_TAG_LEN_8, /* */
NULL /* pointer to next testcase */
};
@ -453,10 +458,11 @@ static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
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,
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,
@ -464,14 +470,17 @@ static const uint8_t srtp_aes_gcm_test_case_1_key[SRTP_AES_GCM_256_KEY_LEN_WSALT
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,
@ -482,13 +491,17 @@ static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] = {
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,
@ -502,6 +515,7 @@ static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
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 */
@ -513,7 +527,7 @@ static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
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,
GCM_AUTH_TAG_LEN_8, /* */
NULL /* pointer to next testcase */
};
@ -527,7 +541,7 @@ static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
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,
GCM_AUTH_TAG_LEN, /* */
&srtp_aes_gcm_test_case_1a /* pointer to next testcase */
};
@ -564,4 +578,3 @@ const srtp_cipher_type_t srtp_aes_gcm_256_openssl = {
&srtp_aes_gcm_test_case_1,
SRTP_AES_GCM_256
};

View File

@ -44,21 +44,19 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#define ALIGN_32 0
#include "aes_icm.h"
#include "alloc.h"
#include "cipher_types.h"
srtp_debug_module_t srtp_mod_aes_icm = {
0, /* debugging is off by default */
"aes icm" /* printable module name */
0, /* debugging is off by default */
"aes icm" /* printable module name */
};
extern const srtp_cipher_type_t srtp_aes_icm_128;
extern const srtp_cipher_type_t srtp_aes_icm_256;
/*
* integer counter mode works as follows:
@ -94,12 +92,14 @@ extern const srtp_cipher_type_t srtp_aes_icm_256;
*
*/
static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int tlen)
static srtp_err_status_t srtp_aes_icm_alloc(srtp_cipher_t **c,
int key_len,
int tlen)
{
srtp_aes_icm_ctx_t *icm;
debug_print(srtp_mod_aes_icm,
"allocating cipher with key length %d", key_len);
debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
key_len);
/*
* The check for key_len = 30/46 does not apply. Our usage
@ -107,7 +107,8 @@ static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int
* has not broken anything. Don't know what would be the
* effect of skipping this check for srtp in general.
*/
if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT && key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
return srtp_err_status_bad_param;
}
@ -116,14 +117,13 @@ static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int
if (*c == NULL) {
return srtp_err_status_alloc_fail;
}
memset(*c, 0x0, sizeof(srtp_cipher_t));
icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
if (icm == NULL) {
srtp_crypto_free(*c);
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
}
memset(icm, 0x0, sizeof(srtp_aes_icm_ctx_t));
/* set pointers */
(*c)->state = icm;
@ -146,7 +146,7 @@ static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_aes_icm_dealloc (srtp_cipher_t *c)
static srtp_err_status_t srtp_aes_icm_dealloc(srtp_cipher_t *c)
{
srtp_aes_icm_ctx_t *ctx;
@ -167,7 +167,6 @@ static srtp_err_status_t srtp_aes_icm_dealloc (srtp_cipher_t *c)
return srtp_err_status_ok;
}
/*
* aes_icm_context_init(...) initializes the aes_icm_context
* using the value in key[].
@ -178,15 +177,16 @@ static srtp_err_status_t srtp_aes_icm_dealloc (srtp_cipher_t *c)
* randomizes the starting point in the keystream
*/
static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key)
static srtp_err_status_t srtp_aes_icm_context_init(void *cv, const uint8_t *key)
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
srtp_err_status_t status;
int base_key_len, copy_len;
if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT || c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) {
if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT ||
c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) {
base_key_len = c->key_size - SRTP_SALT_LEN;
} else{
} else {
return srtp_err_status_bad_param;
}
@ -198,7 +198,8 @@ static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key
v128_set_to_zero(&c->offset);
copy_len = c->key_size - base_key_len;
/* force last two octets of the offset to be left zero (for srtp compatibility) */
/* force last two octets of the offset to be left zero (for srtp
* compatibility) */
if (copy_len > SRTP_SALT_LEN) {
copy_len = SRTP_SALT_LEN;
}
@ -206,13 +207,13 @@ static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key
memcpy(&c->counter, key + base_key_len, copy_len);
memcpy(&c->offset, key + base_key_len, copy_len);
debug_print(srtp_mod_aes_icm,
"key: %s", srtp_octet_string_hex_string(key, base_key_len));
debug_print(srtp_mod_aes_icm,
"offset: %s", v128_hex_string(&c->offset));
debug_print(srtp_mod_aes_icm, "key: %s",
srtp_octet_string_hex_string(key, base_key_len));
debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
/* expand key */
status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
status =
srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
if (status) {
v128_set_to_zero(&c->counter);
v128_set_to_zero(&c->offset);
@ -230,7 +231,9 @@ static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key
* the offset
*/
static srtp_err_status_t srtp_aes_icm_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
static srtp_err_status_t srtp_aes_icm_set_iv(void *cv,
uint8_t *iv,
srtp_cipher_direction_t direction)
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
v128_t nonce;
@ -238,13 +241,12 @@ static srtp_err_status_t srtp_aes_icm_set_iv (void *cv, uint8_t *iv, srtp_cipher
/* set nonce (for alignment) */
v128_copy_octet_string(&nonce, iv);
debug_print(srtp_mod_aes_icm,
"setting iv: %s", v128_hex_string(&nonce));
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));
debug_print(srtp_mod_aes_icm, "set_counter: %s",
v128_hex_string(&c->counter));
/* indicate that the keystream_buffer is empty */
c->bytes_in_buffer = 0;
@ -252,15 +254,13 @@ static srtp_err_status_t srtp_aes_icm_set_iv (void *cv, uint8_t *iv, srtp_cipher
return srtp_err_status_ok;
}
/*
* aes_icm_advance(...) refills the keystream_buffer and
* advances the block index of the sicm_context forward by one
*
* this is an internal, hopefully inlined function
*/
static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
static void srtp_aes_icm_advance(srtp_aes_icm_ctx_t *c)
{
/* fill buffer with new keystream */
v128_copy(&c->keystream_buffer, &c->counter);
@ -278,7 +278,7 @@ static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
}
}
/*e
/*
* icm_encrypt deals with the following cases:
*
* bytes_to_encr < bytes_in_buffer
@ -291,10 +291,11 @@ static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
* - fill buffer then add in remaining (< 16) bytes of keystream
*/
static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
unsigned char *buf, unsigned int *enc_len)
static srtp_err_status_t srtp_aes_icm_encrypt(void *cv,
unsigned char *buf,
unsigned int *enc_len)
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t*)cv;
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
unsigned int bytes_to_encr = *enc_len;
unsigned int i;
uint32_t *b;
@ -304,10 +305,8 @@ static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
return srtp_err_status_terminus;
}
debug_print(srtp_mod_aes_icm, "block index: %d",
htons(c->counter.v16[7]));
debug_print(srtp_mod_aes_icm, "block index: %d", htons(c->counter.v16[7]));
if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
/* deal with odd case of small bytes_to_encr */
for (i = (sizeof(v128_t) - c->bytes_in_buffer);
i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) {
@ -320,37 +319,35 @@ static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
return srtp_err_status_ok;
} else {
/* encrypt bytes until the remaining data is 16-byte aligned */
for (i = (sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) {
for (i = (sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t);
i++) {
*buf++ ^= c->keystream_buffer.v8[i];
}
bytes_to_encr -= c->bytes_in_buffer;
c->bytes_in_buffer = 0;
}
/* now loop over entire 16-byte blocks of keystream */
for (i = 0; i < (bytes_to_encr / sizeof(v128_t)); i++) {
/* fill buffer with new keystream */
srtp_aes_icm_advance(c);
/*
* add keystream into the data buffer (this would be a lot faster
* if we could assume 32-bit alignment!)
*/
/*
* add keystream into the data buffer (this would be a lot faster
* if we could assume 32-bit alignment!)
*/
#if ALIGN_32
b = (uint32_t*)buf;
b = (uint32_t *)buf;
*b++ ^= c->keystream_buffer.v32[0];
*b++ ^= c->keystream_buffer.v32[1];
*b++ ^= c->keystream_buffer.v32[2];
*b++ ^= c->keystream_buffer.v32[3];
buf = (uint8_t*)b;
buf = (uint8_t *)b;
#else
if ((((unsigned long)buf) & 0x03) != 0) {
if ((((uintptr_t)buf) & 0x03) != 0) {
*buf++ ^= c->keystream_buffer.v8[0];
*buf++ ^= c->keystream_buffer.v8[1];
*buf++ ^= c->keystream_buffer.v8[2];
@ -368,20 +365,18 @@ static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
*buf++ ^= c->keystream_buffer.v8[14];
*buf++ ^= c->keystream_buffer.v8[15];
} else {
b = (uint32_t*)buf;
b = (uint32_t *)buf;
*b++ ^= c->keystream_buffer.v32[0];
*b++ ^= c->keystream_buffer.v32[1];
*b++ ^= c->keystream_buffer.v32[2];
*b++ ^= c->keystream_buffer.v32[3];
buf = (uint8_t*)b;
buf = (uint8_t *)b;
}
#endif /* #if ALIGN_32 */
#endif /* #if ALIGN_32 */
}
/* if there is a tail end of the data, process it */
if ((bytes_to_encr & 0xf) != 0) {
/* fill buffer with new keystream */
srtp_aes_icm_advance(c);
@ -392,58 +387,67 @@ static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
/* reset the keystream buffer size to right value */
c->bytes_in_buffer = sizeof(v128_t) - i;
} else {
/* no tail, so just reset the keystream buffer size to zero */
c->bytes_in_buffer = 0;
}
return srtp_err_status_ok;
}
static const char srtp_aes_icm_128_description[] = "AES-128 integer counter mode";
static const char srtp_aes_icm_256_description[] = "AES-256 integer counter mode";
static const char srtp_aes_icm_128_description[] =
"AES-128 integer counter mode";
static const char srtp_aes_icm_256_description[] =
"AES-256 integer counter mode";
/* 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_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 */
32, /* octets in plaintext */
srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */
32, /* octets in ciphertext */
srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
0, /* */
NULL, /* */
0, /* */
NULL /* pointer to next testcase */
};
/* 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,
@ -452,70 +456,75 @@ static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_W
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_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 */
32, /* octets in plaintext */
srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */
32, /* octets in ciphertext */
srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL, /* pointer to next testcase */
0, /* */
NULL, /* */
0, /* */
NULL, /* pointer to next testcase */
};
/*
* note: the encrypt function is identical to the decrypt function
*/
const srtp_cipher_type_t srtp_aes_icm_128 = {
srtp_aes_icm_alloc,
srtp_aes_icm_dealloc,
srtp_aes_icm_context_init,
0, /* set_aad */
srtp_aes_icm_encrypt,
srtp_aes_icm_encrypt,
srtp_aes_icm_set_iv,
0, /* get_tag */
srtp_aes_icm_128_description,
&srtp_aes_icm_128_test_case_0,
SRTP_AES_ICM_128
srtp_aes_icm_alloc, /* */
srtp_aes_icm_dealloc, /* */
srtp_aes_icm_context_init, /* */
0, /* set_aad */
srtp_aes_icm_encrypt, /* */
srtp_aes_icm_encrypt, /* */
srtp_aes_icm_set_iv, /* */
0, /* get_tag */
srtp_aes_icm_128_description, /* */
&srtp_aes_icm_128_test_case_0, /* */
SRTP_AES_ICM_128 /* */
};
const srtp_cipher_type_t srtp_aes_icm_256 = {
srtp_aes_icm_alloc,
srtp_aes_icm_dealloc,
srtp_aes_icm_context_init,
0, /* set_aad */
srtp_aes_icm_encrypt,
srtp_aes_icm_encrypt,
srtp_aes_icm_set_iv,
0, /* get_tag */
srtp_aes_icm_256_description,
&srtp_aes_icm_256_test_case_0,
SRTP_AES_ICM_256
srtp_aes_icm_alloc, /* */
srtp_aes_icm_dealloc, /* */
srtp_aes_icm_context_init, /* */
0, /* set_aad */
srtp_aes_icm_encrypt, /* */
srtp_aes_icm_encrypt, /* */
srtp_aes_icm_set_iv, /* */
0, /* get_tag */
srtp_aes_icm_256_description, /* */
&srtp_aes_icm_256_test_case_0, /* */
SRTP_AES_ICM_256 /* */
};

View File

@ -49,23 +49,20 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <openssl/evp.h>
#include "aes_icm_ossl.h"
#include "crypto_types.h"
#include "err.h" /* for srtp_debug */
#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 ossl" /* printable module name */
0, /* debugging is off by default */
"aes icm ossl" /* printable module name */
};
extern const srtp_cipher_type_t srtp_aes_icm_128;
extern const srtp_cipher_type_t srtp_aes_icm_192;
extern const srtp_cipher_type_t srtp_aes_icm_256;
/*
* integer counter mode works as follows:
@ -109,16 +106,20 @@ extern const srtp_cipher_type_t srtp_aes_icm_256;
* 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_openssl_alloc (srtp_cipher_t **c, int key_len, int tlen)
static srtp_err_status_t srtp_aes_icm_openssl_alloc(srtp_cipher_t **c,
int key_len,
int tlen)
{
srtp_aes_icm_ctx_t *icm;
debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d", key_len);
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 &&
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;
}
@ -128,15 +129,13 @@ static srtp_err_status_t srtp_aes_icm_openssl_alloc (srtp_cipher_t **c, int key_
if (*c == NULL) {
return srtp_err_status_alloc_fail;
}
memset(*c, 0x0, sizeof(srtp_cipher_t));
icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
if (icm == NULL) {
srtp_crypto_free(*c);
*c = NULL;
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
}
memset(icm, 0x0, sizeof(srtp_aes_icm_ctx_t));
icm->ctx = EVP_CIPHER_CTX_new();
if (icm->ctx == NULL) {
@ -174,11 +173,10 @@ static srtp_err_status_t srtp_aes_icm_openssl_alloc (srtp_cipher_t **c, int key_
return srtp_err_status_ok;
}
/*
* This function deallocates an instance of this engine
*/
static srtp_err_status_t srtp_aes_icm_openssl_dealloc (srtp_cipher_t *c)
static srtp_err_status_t srtp_aes_icm_openssl_dealloc(srtp_cipher_t *c)
{
srtp_aes_icm_ctx_t *ctx;
@ -189,7 +187,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_dealloc (srtp_cipher_t *c)
/*
* Free the EVP context
*/
ctx = (srtp_aes_icm_ctx_t*)c->state;
ctx = (srtp_aes_icm_ctx_t *)c->state;
if (ctx != NULL) {
EVP_CIPHER_CTX_free(ctx->ctx);
/* zeroize the key material */
@ -212,7 +210,8 @@ static srtp_err_status_t srtp_aes_icm_openssl_dealloc (srtp_cipher_t *c)
* 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_openssl_context_init (void* cv, const uint8_t *key)
static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv,
const uint8_t *key)
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
const EVP_CIPHER *evp;
@ -230,7 +229,8 @@ static srtp_err_status_t srtp_aes_icm_openssl_context_init (void* cv, const uint
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, "key: %s",
srtp_octet_string_hex_string(key, c->key_size));
debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
switch (c->key_size) {
@ -248,8 +248,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_context_init (void* cv, const uint
break;
}
if (!EVP_EncryptInit_ex(c->ctx, evp,
NULL, key, NULL)) {
if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) {
return srtp_err_status_fail;
} else {
return srtp_err_status_ok;
@ -258,12 +257,14 @@ static srtp_err_status_t srtp_aes_icm_openssl_context_init (void* cv, const uint
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_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
static srtp_err_status_t srtp_aes_icm_openssl_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;
@ -275,10 +276,10 @@ static srtp_err_status_t srtp_aes_icm_openssl_set_iv (void *cv, uint8_t *iv, srt
v128_xor(&c->counter, &c->offset, &nonce);
debug_print(srtp_mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));
debug_print(srtp_mod_aes_icm, "set_counter: %s",
v128_hex_string(&c->counter));
if (!EVP_EncryptInit_ex(c->ctx, NULL,
NULL, NULL, c->counter.v8)) {
if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) {
return srtp_err_status_fail;
} else {
return srtp_err_status_ok;
@ -293,7 +294,9 @@ static srtp_err_status_t srtp_aes_icm_openssl_set_iv (void *cv, uint8_t *iv, srt
* buf data to encrypt
* enc_len length of encrypt buffer
*/
static srtp_err_status_t srtp_aes_icm_openssl_encrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv,
unsigned char *buf,
unsigned int *enc_len)
{
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
int len = 0;
@ -316,59 +319,70 @@ static srtp_err_status_t srtp_aes_icm_openssl_encrypt (void *cv, unsigned char *
/*
* Name of this crypto engine
*/
static const char srtp_aes_icm_128_openssl_description[] = "AES-128 counter mode using openssl";
static const char srtp_aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
static const char srtp_aes_icm_256_openssl_description[] = "AES-256 counter mode using openssl";
static const char srtp_aes_icm_128_openssl_description[] =
"AES-128 counter mode using openssl";
static const char srtp_aes_icm_192_openssl_description[] =
"AES-192 counter mode using openssl";
static const char srtp_aes_icm_256_openssl_description[] =
"AES-256 counter mode using openssl";
/*
* KAT values for AES self-test. These
* values came from the legacy libsrtp code.
*/
/* 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 */
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,
@ -376,44 +390,52 @@ static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_W
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 */
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,
@ -422,38 +444,45 @@ static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_W
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 */
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 */
};
/*
@ -461,17 +490,17 @@ static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
* note: the encrypt function is identical to the decrypt function
*/
const srtp_cipher_type_t srtp_aes_icm_128 = {
srtp_aes_icm_openssl_alloc,
srtp_aes_icm_openssl_dealloc,
srtp_aes_icm_openssl_context_init,
0, /* set_aad */
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_set_iv,
0, /* get_tag */
srtp_aes_icm_128_openssl_description,
&srtp_aes_icm_128_test_case_0,
SRTP_AES_ICM_128
srtp_aes_icm_openssl_alloc, /* */
srtp_aes_icm_openssl_dealloc, /* */
srtp_aes_icm_openssl_context_init, /* */
0, /* set_aad */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_set_iv, /* */
0, /* get_tag */
srtp_aes_icm_128_openssl_description, /* */
&srtp_aes_icm_128_test_case_0, /* */
SRTP_AES_ICM_128 /* */
};
/*
@ -479,17 +508,17 @@ const srtp_cipher_type_t srtp_aes_icm_128 = {
* note: the encrypt function is identical to the decrypt function
*/
const srtp_cipher_type_t srtp_aes_icm_192 = {
srtp_aes_icm_openssl_alloc,
srtp_aes_icm_openssl_dealloc,
srtp_aes_icm_openssl_context_init,
0, /* set_aad */
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_set_iv,
0, /* get_tag */
srtp_aes_icm_192_openssl_description,
&srtp_aes_icm_192_test_case_0,
SRTP_AES_ICM_192
srtp_aes_icm_openssl_alloc, /* */
srtp_aes_icm_openssl_dealloc, /* */
srtp_aes_icm_openssl_context_init, /* */
0, /* set_aad */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_set_iv, /* */
0, /* get_tag */
srtp_aes_icm_192_openssl_description, /* */
&srtp_aes_icm_192_test_case_0, /* */
SRTP_AES_ICM_192 /* */
};
/*
@ -497,16 +526,15 @@ const srtp_cipher_type_t srtp_aes_icm_192 = {
* note: the encrypt function is identical to the decrypt function
*/
const srtp_cipher_type_t srtp_aes_icm_256 = {
srtp_aes_icm_openssl_alloc,
srtp_aes_icm_openssl_dealloc,
srtp_aes_icm_openssl_context_init,
0, /* set_aad */
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_encrypt,
srtp_aes_icm_openssl_set_iv,
0, /* get_tag */
srtp_aes_icm_256_openssl_description,
&srtp_aes_icm_256_test_case_0,
SRTP_AES_ICM_256
srtp_aes_icm_openssl_alloc, /* */
srtp_aes_icm_openssl_dealloc, /* */
srtp_aes_icm_openssl_context_init, /* */
0, /* set_aad */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_encrypt, /* */
srtp_aes_icm_openssl_set_iv, /* */
0, /* get_tag */
srtp_aes_icm_256_openssl_description, /* */
&srtp_aes_icm_256_test_case_0, /* */
SRTP_AES_ICM_256 /* */
};

View File

@ -45,56 +45,61 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "cipher.h"
#include "crypto_types.h"
#include "err.h" /* for srtp_debug */
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
#include "err.h" /* for srtp_debug */
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
srtp_debug_module_t srtp_mod_cipher = {
0, /* debugging is off by default */
"cipher" /* printable module name */
0, /* debugging is off by default */
"cipher" /* printable module name */
};
srtp_err_status_t srtp_cipher_type_alloc (const srtp_cipher_type_t *ct, srtp_cipher_t **c, int key_len, int tlen)
srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct,
srtp_cipher_t **c,
int key_len,
int tlen)
{
if (!ct || !ct->alloc) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return ((ct)->alloc((c), (key_len), (tlen)));
}
srtp_err_status_t srtp_cipher_dealloc (srtp_cipher_t *c)
srtp_err_status_t srtp_cipher_dealloc(srtp_cipher_t *c)
{
if (!c || !c->type) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return (((c)->type)->dealloc(c));
}
srtp_err_status_t srtp_cipher_init (srtp_cipher_t *c, const uint8_t *key)
srtp_err_status_t srtp_cipher_init(srtp_cipher_t *c, const uint8_t *key)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return (((c)->type)->init(((c)->state), (key)));
}
srtp_err_status_t srtp_cipher_set_iv (srtp_cipher_t *c, uint8_t *iv, int direction)
srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c,
uint8_t *iv,
int direction)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return (((c)->type)->set_iv(((c)->state), iv, direction));
return (((c)->type)->set_iv(((c)->state), iv, direction));
}
srtp_err_status_t srtp_cipher_output (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output)
srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output)
{
/* zeroize the buffer */
octet_string_set_to_zero(buffer, *num_octets_to_output);
@ -102,43 +107,51 @@ srtp_err_status_t srtp_cipher_output (srtp_cipher_t *c, uint8_t *buffer, uint32_
return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
}
srtp_err_status_t srtp_cipher_encrypt (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output)
srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
}
srtp_err_status_t srtp_cipher_decrypt (srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output)
srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
return (((c)->type)->decrypt(((c)->state), buffer, num_octets_to_output));
}
srtp_err_status_t srtp_cipher_get_tag (srtp_cipher_t *c, uint8_t *buffer, uint32_t *tag_len)
srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *tag_len)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
if (!((c)->type)->get_tag) {
return (srtp_err_status_no_such_op);
return (srtp_err_status_no_such_op);
}
return (((c)->type)->get_tag(((c)->state), buffer, tag_len));
}
srtp_err_status_t srtp_cipher_set_aad (srtp_cipher_t *c, const uint8_t *aad, uint32_t aad_len)
srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c,
const uint8_t *aad,
uint32_t aad_len)
{
if (!c || !c->type || !c->state) {
return (srtp_err_status_bad_param);
return (srtp_err_status_bad_param);
}
if (!((c)->type)->set_aad) {
return (srtp_err_status_no_such_op);
return (srtp_err_status_no_such_op);
}
return (((c)->type)->set_aad(((c)->state), aad, aad_len));
@ -146,57 +159,56 @@ srtp_err_status_t srtp_cipher_set_aad (srtp_cipher_t *c, const uint8_t *aad, uin
/* some bookkeeping functions */
int srtp_cipher_get_key_length (const srtp_cipher_t *c)
int srtp_cipher_get_key_length(const srtp_cipher_t *c)
{
return c->key_len;
}
/*
* A trivial platform independent random source. The random
* data is used for some of the cipher self-tests.
*/
static srtp_err_status_t srtp_cipher_rand (void *dest, uint32_t len)
static srtp_err_status_t srtp_cipher_rand(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);
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--;
}
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;
while (len)
{
int val = rand();
/* rand() returns 0-32767 (ugh) */
/* Is this a good enough way to get random bytes?
It is if it passes FIPS-140... */
*dst++ = val & 0xff;
len--;
}
/* Generic C-library (rand()) version */
/* This is a random source of last resort */
uint8_t *dst = (uint8_t *)dest;
while (len) {
int val = rand();
/* rand() returns 0-32767 (ugh) */
/* Is this a good enough way to get random bytes?
It is if it passes FIPS-140... */
*dst++ = val & 0xff;
len--;
}
#endif
return srtp_err_status_ok;
return srtp_err_status_ok;
}
#define SELF_TEST_BUF_OCTETS 128
#define NUM_RAND_TESTS 128
#define MAX_KEY_LEN 64
#define NUM_RAND_TESTS 128
#define MAX_KEY_LEN 64
/*
* srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against
* test cases provided in a list test_data of values of key, salt, iv,
* plaintext, and ciphertext that is known to be good
*/
srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srtp_cipher_test_case_t *test_data)
srtp_err_status_t srtp_cipher_type_test(
const srtp_cipher_type_t *ct,
const srtp_cipher_test_case_t *test_data)
{
const srtp_cipher_test_case_t *test_case = test_data;
srtp_cipher_t *c;
@ -206,6 +218,7 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
uint32_t tag_len;
unsigned int len;
int i, j, case_num = 0;
unsigned k = 0;
debug_print(srtp_mod_cipher, "running self-test for cipher %s",
ct->description);
@ -224,7 +237,8 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
*/
while (test_case != NULL) {
/* allocate cipher */
status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
test_case->tag_length_octets);
if (status) {
return status;
}
@ -246,36 +260,39 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
srtp_cipher_dealloc(c);
return srtp_err_status_bad_param;
}
for (i = 0; i < test_case->plaintext_length_octets; i++) {
buffer[i] = test_case->plaintext[i];
for (k = 0; k < test_case->plaintext_length_octets; k++) {
buffer[k] = test_case->plaintext[k];
}
debug_print(srtp_mod_cipher, "plaintext: %s",
srtp_octet_string_hex_string(buffer,
test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
buffer, test_case->plaintext_length_octets));
/* set the initialization vector */
status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_encrypt);
status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
srtp_direction_encrypt);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
debug_print(srtp_mod_cipher, "IV: %s",
srtp_octet_string_hex_string(test_case->idx, 12));
/*
* Set the AAD
*/
status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets);
status = srtp_cipher_set_aad(c, test_case->aad,
test_case->aad_length_octets);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
debug_print(srtp_mod_cipher, "AAD: %s",
srtp_octet_string_hex_string(test_case->aad,
test_case->aad_length_octets));
srtp_octet_string_hex_string(
test_case->aad, test_case->aad_length_octets));
}
/* encrypt */
@ -286,7 +303,8 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
/*
* Get the GCM tag
*/
@ -299,8 +317,8 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
}
debug_print(srtp_mod_cipher, "ciphertext: %s",
srtp_octet_string_hex_string(buffer,
test_case->ciphertext_length_octets));
srtp_octet_string_hex_string(
buffer, test_case->ciphertext_length_octets));
/* compare the resulting ciphertext with that in the test case */
if (len != test_case->ciphertext_length_octets) {
@ -308,22 +326,22 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
return srtp_err_status_algo_fail;
}
status = srtp_err_status_ok;
for (i = 0; i < test_case->ciphertext_length_octets; i++) {
if (buffer[i] != test_case->ciphertext[i]) {
for (k = 0; k < test_case->ciphertext_length_octets; k++) {
if (buffer[k] != test_case->ciphertext[k]) {
status = srtp_err_status_algo_fail;
debug_print(srtp_mod_cipher, "test case %d failed", case_num);
debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
break;
}
}
if (status) {
debug_print(srtp_mod_cipher, "c computed: %s",
srtp_octet_string_hex_string(buffer,
2 * test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
buffer, 2 * test_case->plaintext_length_octets));
debug_print(srtp_mod_cipher, "c expected: %s",
srtp_octet_string_hex_string(test_case->ciphertext,
2 * test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
test_case->ciphertext,
2 * test_case->plaintext_length_octets));
srtp_cipher_dealloc(c);
return srtp_err_status_algo_fail;
@ -346,33 +364,36 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
srtp_cipher_dealloc(c);
return srtp_err_status_bad_param;
}
for (i = 0; i < test_case->ciphertext_length_octets; i++) {
buffer[i] = test_case->ciphertext[i];
for (k = 0; k < test_case->ciphertext_length_octets; k++) {
buffer[k] = test_case->ciphertext[k];
}
debug_print(srtp_mod_cipher, "ciphertext: %s",
srtp_octet_string_hex_string(buffer,
test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
buffer, test_case->plaintext_length_octets));
/* set the initialization vector */
status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt);
status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
srtp_direction_decrypt);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
/*
* Set the AAD
*/
status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets);
status = srtp_cipher_set_aad(c, test_case->aad,
test_case->aad_length_octets);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
debug_print(srtp_mod_cipher, "AAD: %s",
srtp_octet_string_hex_string(test_case->aad,
test_case->aad_length_octets));
srtp_octet_string_hex_string(
test_case->aad, test_case->aad_length_octets));
}
/* decrypt */
@ -384,8 +405,8 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
}
debug_print(srtp_mod_cipher, "plaintext: %s",
srtp_octet_string_hex_string(buffer,
test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
buffer, test_case->plaintext_length_octets));
/* compare the resulting plaintext with that in the test case */
if (len != test_case->plaintext_length_octets) {
@ -393,21 +414,21 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
return srtp_err_status_algo_fail;
}
status = srtp_err_status_ok;
for (i = 0; i < test_case->plaintext_length_octets; i++) {
if (buffer[i] != test_case->plaintext[i]) {
for (k = 0; k < test_case->plaintext_length_octets; k++) {
if (buffer[k] != test_case->plaintext[k]) {
status = srtp_err_status_algo_fail;
debug_print(srtp_mod_cipher, "test case %d failed", case_num);
debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
}
}
if (status) {
debug_print(srtp_mod_cipher, "p computed: %s",
srtp_octet_string_hex_string(buffer,
2 * test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
buffer, 2 * test_case->plaintext_length_octets));
debug_print(srtp_mod_cipher, "p expected: %s",
srtp_octet_string_hex_string(test_case->plaintext,
2 * test_case->plaintext_length_octets));
srtp_octet_string_hex_string(
test_case->plaintext,
2 * test_case->plaintext_length_octets));
srtp_cipher_dealloc(c);
return srtp_err_status_algo_fail;
@ -431,14 +452,15 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
/* allocate cipher, using paramaters from the first test case */
test_case = test_data;
status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets, test_case->tag_length_octets);
status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
test_case->tag_length_octets);
if (status) {
return status;
}
for (j = 0; j < NUM_RAND_TESTS; j++) {
unsigned length;
int plaintext_len;
unsigned int length;
unsigned int plaintext_len;
uint8_t key[MAX_KEY_LEN];
uint8_t iv[MAX_KEY_LEN];
@ -485,24 +507,27 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
}
/* set initialization vector */
status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_encrypt);
status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
srtp_direction_encrypt);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
/*
* Set the AAD
*/
status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets);
status = srtp_cipher_set_aad(c, test_case->aad,
test_case->aad_length_octets);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
debug_print(srtp_mod_cipher, "AAD: %s",
srtp_octet_string_hex_string(test_case->aad,
test_case->aad_length_octets));
srtp_octet_string_hex_string(
test_case->aad, test_case->aad_length_octets));
}
/* encrypt buffer with cipher */
@ -512,7 +537,8 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
srtp_cipher_dealloc(c);
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
/*
* Get the GCM tag
*/
@ -535,23 +561,26 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
srtp_cipher_dealloc(c);
return status;
}
status = srtp_cipher_set_iv(c, (uint8_t*)test_case->idx, srtp_direction_decrypt);
status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
srtp_direction_decrypt);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
if (c->algorithm == SRTP_AES_GCM_128 || c->algorithm == SRTP_AES_GCM_256) {
if (c->algorithm == SRTP_AES_GCM_128 ||
c->algorithm == SRTP_AES_GCM_256) {
/*
* Set the AAD
*/
status = srtp_cipher_set_aad(c, test_case->aad, test_case->aad_length_octets);
status = srtp_cipher_set_aad(c, test_case->aad,
test_case->aad_length_octets);
if (status) {
srtp_cipher_dealloc(c);
return status;
}
debug_print(srtp_mod_cipher, "AAD: %s",
srtp_octet_string_hex_string(test_case->aad,
test_case->aad_length_octets));
srtp_octet_string_hex_string(
test_case->aad, test_case->aad_length_octets));
}
status = srtp_cipher_decrypt(c, buffer, &length);
if (status) {
@ -568,18 +597,18 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
return srtp_err_status_algo_fail;
}
status = srtp_err_status_ok;
for (i = 0; i < plaintext_len; i++) {
if (buffer[i] != buffer2[i]) {
for (k = 0; k < plaintext_len; k++) {
if (buffer[k] != buffer2[k]) {
status = srtp_err_status_algo_fail;
debug_print(srtp_mod_cipher, "random test case %d failed", case_num);
debug_print(srtp_mod_cipher, "(failure at byte %d)", i);
debug_print(srtp_mod_cipher, "random test case %d failed",
case_num);
debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
}
}
if (status) {
srtp_cipher_dealloc(c);
return srtp_err_status_algo_fail;
}
}
status = srtp_cipher_dealloc(c);
@ -590,12 +619,11 @@ srtp_err_status_t srtp_cipher_type_test (const srtp_cipher_type_t *ct, const srt
return srtp_err_status_ok;
}
/*
* srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's internal
* list of test data.
* srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's
* internal list of test data.
*/
srtp_err_status_t srtp_cipher_type_self_test (const srtp_cipher_type_t *ct)
srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct)
{
return srtp_cipher_type_test(ct, ct->test_data);
}
@ -610,7 +638,9 @@ srtp_err_status_t srtp_cipher_type_self_test (const srtp_cipher_type_t *ct)
*
* if an error is encountered, the value 0 is returned
*/
uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, int num_trials)
uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
int octets_in_buffer,
int num_trials)
{
int i;
v128_t nonce;
@ -618,16 +648,16 @@ uint64_t srtp_cipher_bits_per_second (srtp_cipher_t *c, int octets_in_buffer, in
unsigned char *enc_buf;
unsigned int len = octets_in_buffer;
enc_buf = (unsigned char*)srtp_crypto_alloc(octets_in_buffer);
enc_buf = (unsigned char *)srtp_crypto_alloc(octets_in_buffer);
if (enc_buf == NULL) {
return 0; /* indicate bad parameters by returning null */
}
/* time repeated trials */
v128_set_to_zero(&nonce);
timer = clock();
for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
if (srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt) != srtp_err_status_ok) {
if (srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt) !=
srtp_err_status_ok) {
srtp_crypto_free(enc_buf);
return 0;
}

View File

@ -45,45 +45,42 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "datatypes.h"
#include "null_cipher.h"
#include "err.h" /* for srtp_debug */
#include "err.h" /* for srtp_debug */
#include "alloc.h"
#include "cipher_types.h"
/* the null_cipher uses the cipher debug module */
extern srtp_debug_module_t srtp_mod_cipher;
static srtp_err_status_t srtp_null_cipher_alloc (srtp_cipher_t **c, int key_len, int tlen)
static srtp_err_status_t srtp_null_cipher_alloc(srtp_cipher_t **c,
int key_len,
int tlen)
{
extern const srtp_cipher_type_t srtp_null_cipher;
debug_print(srtp_mod_cipher,
"allocating cipher with key length %d", key_len);
debug_print(srtp_mod_cipher, "allocating cipher with key length %d",
key_len);
/* allocate memory a cipher of type null_cipher */
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
if (*c == NULL) {
return srtp_err_status_alloc_fail;
}
memset(*c, 0x0, sizeof(srtp_cipher_t));
/* set pointers */
(*c)->algorithm = SRTP_NULL_CIPHER;
(*c)->type = &srtp_null_cipher;
(*c)->state = (void *) 0x1; /* The null cipher does not maintain state */
(*c)->state = (void *)0x1; /* The null cipher does not maintain state */
/* set key size */
(*c)->key_len = key_len;
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_cipher_dealloc (srtp_cipher_t *c)
static srtp_err_status_t srtp_null_cipher_dealloc(srtp_cipher_t *c)
{
extern const srtp_cipher_type_t srtp_null_cipher;
@ -94,28 +91,30 @@ static srtp_err_status_t srtp_null_cipher_dealloc (srtp_cipher_t *c)
srtp_crypto_free(c);
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_cipher_init (void *cv, const uint8_t *key)
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; */
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
debug_print(srtp_mod_cipher, "initializing null cipher", NULL);
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_cipher_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
static srtp_err_status_t srtp_null_cipher_set_iv(void *cv,
uint8_t *iv,
srtp_cipher_direction_t dir)
{
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_cipher_encrypt (void *cv,
unsigned char *buf, unsigned int *bytes_to_encr)
static srtp_err_status_t srtp_null_cipher_encrypt(void *cv,
unsigned char *buf,
unsigned int *bytes_to_encr)
{
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
return srtp_err_status_ok;
}
@ -129,28 +128,26 @@ static const srtp_cipher_test_case_t srtp_null_cipher_test_0 = {
NULL, /* plaintext */
0, /* octets in plaintext */
NULL, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
0, /* */
NULL, /* */
0, /* */
NULL /* pointer to next testcase */
};
/*
* note: the decrypt function is idential to the encrypt function
*/
const srtp_cipher_type_t srtp_null_cipher = {
srtp_null_cipher_alloc,
srtp_null_cipher_dealloc,
srtp_null_cipher_init,
0, /* set_aad */
srtp_null_cipher_encrypt,
srtp_null_cipher_encrypt,
srtp_null_cipher_set_iv,
0, /* get_tag */
srtp_null_cipher_description,
&srtp_null_cipher_test_0,
SRTP_NULL_CIPHER
srtp_null_cipher_alloc, /* */
srtp_null_cipher_dealloc, /* */
srtp_null_cipher_init, /* */
0, /* set_aad */
srtp_null_cipher_encrypt, /* */
srtp_null_cipher_encrypt, /* */
srtp_null_cipher_set_iv, /* */
0, /* get_tag */
srtp_null_cipher_description, /* */
&srtp_null_cipher_test_0, /* */
SRTP_NULL_CIPHER /* */
};

View File

@ -44,32 +44,31 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "auth.h"
#include "err.h" /* for srtp_debug */
#include "datatypes.h" /* for octet_string */
#include "err.h" /* for srtp_debug */
#include "datatypes.h" /* for octet_string */
/* the debug module for authentiation */
srtp_debug_module_t srtp_mod_auth = {
0, /* debugging is off by default */
"auth func" /* printable name for module */
0, /* debugging is off by default */
"auth func" /* printable name for module */
};
int srtp_auth_get_key_length (const srtp_auth_t *a)
int srtp_auth_get_key_length(const srtp_auth_t *a)
{
return a->key_len;
}
int srtp_auth_get_tag_length (const srtp_auth_t *a)
int srtp_auth_get_tag_length(const srtp_auth_t *a)
{
return a->out_len;
}
int srtp_auth_get_prefix_length (const srtp_auth_t *a)
int srtp_auth_get_prefix_length(const srtp_auth_t *a)
{
return a->prefix_len;
}
@ -83,8 +82,8 @@ int srtp_auth_get_prefix_length (const srtp_auth_t *a)
/* should be big enough for most occasions */
#define SELF_TEST_TAG_BUF_OCTETS 32
srtp_err_status_t
srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *test_data)
srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
const srtp_auth_test_case_t *test_data)
{
const srtp_auth_test_case_t *test_case = test_data;
srtp_auth_t *a;
@ -105,7 +104,6 @@ srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *te
/* loop over all test cases */
while (test_case != NULL) {
/* check test case parameters */
if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) {
return srtp_err_status_bad_param;
@ -113,7 +111,7 @@ srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *te
/* allocate auth */
status = srtp_auth_type_alloc(at, &a, test_case->key_length_octets,
test_case->tag_length_octets);
test_case->tag_length_octets);
if (status) {
return status;
}
@ -128,7 +126,7 @@ srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *te
/* zeroize tag then compute */
octet_string_set_to_zero(tag, test_case->tag_length_octets);
status = srtp_auth_compute(a, test_case->data,
test_case->data_length_octets, tag);
test_case->data_length_octets, tag);
if (status) {
srtp_auth_dealloc(a);
return status;
@ -138,10 +136,11 @@ srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *te
srtp_octet_string_hex_string(test_case->key,
test_case->key_length_octets));
debug_print(srtp_mod_auth, "data: %s",
srtp_octet_string_hex_string(test_case->data,
test_case->data_length_octets));
debug_print(srtp_mod_auth, "tag computed: %s",
srtp_octet_string_hex_string(tag, test_case->tag_length_octets));
srtp_octet_string_hex_string(
test_case->data, test_case->data_length_octets));
debug_print(
srtp_mod_auth, "tag computed: %s",
srtp_octet_string_hex_string(tag, test_case->tag_length_octets));
debug_print(srtp_mod_auth, "tag expected: %s",
srtp_octet_string_hex_string(test_case->tag,
test_case->tag_length_octets));
@ -177,14 +176,12 @@ srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *te
return srtp_err_status_ok;
}
/*
* auth_type_self_test(at) performs srtp_auth_type_test on at's internal
* srtp_auth_type_self_test(at) performs srtp_auth_type_test on at's internal
* list of test data.
*/
srtp_err_status_t srtp_auth_type_self_test (const srtp_auth_type_t *at)
srtp_err_status_t srtp_auth_type_self_test(const srtp_auth_type_t *at)
{
return srtp_auth_type_test(at, at->test_data);
}

View File

@ -43,27 +43,31 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "hmac.h"
#include "alloc.h"
#include "cipher_types.h"
/* the debug module for authentiation */
srtp_debug_module_t srtp_mod_hmac = {
0, /* debugging is off by default */
"hmac sha-1" /* printable name for module */
0, /* debugging is off by default */
"hmac sha-1" /* printable name for module */
};
static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
static srtp_err_status_t srtp_hmac_alloc(srtp_auth_t **a,
int key_len,
int out_len)
{
extern const srtp_auth_type_t srtp_hmac;
uint8_t *pointer;
debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
debug_print(srtp_mod_hmac, " tag length %d", out_len);
debug_print(srtp_mod_hmac, "allocating auth func with key length %d",
key_len);
debug_print(srtp_mod_hmac, " tag length %d",
out_len);
/*
* check key length - note that we don't support keys larger
@ -79,13 +83,14 @@ static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_
}
/* allocate memory for auth and srtp_hmac_ctx_t structures */
pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
pointer = (uint8_t *)srtp_crypto_alloc(sizeof(srtp_hmac_ctx_t) +
sizeof(srtp_auth_t));
if (pointer == NULL) {
return srtp_err_status_alloc_fail;
}
/* set pointers */
*a = (srtp_auth_t*)pointer;
*a = (srtp_auth_t *)pointer;
(*a)->type = &srtp_hmac;
(*a)->state = pointer + sizeof(srtp_auth_t);
(*a)->out_len = out_len;
@ -95,7 +100,7 @@ static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
static srtp_err_status_t srtp_hmac_dealloc(srtp_auth_t *a)
{
/* zeroize entire state*/
octet_string_set_to_zero(a, sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
@ -106,7 +111,9 @@ static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
static srtp_err_status_t srtp_hmac_init(void *statev,
const uint8_t *key,
int key_len)
{
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
int i;
@ -131,10 +138,11 @@ static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int k
/* set the rest of ipad, opad to constant values */
for (; i < 64; i++) {
ipad[i] = 0x36;
((uint8_t*)state->opad)[i] = 0x5c;
((uint8_t *)state->opad)[i] = 0x5c;
}
debug_print(srtp_mod_hmac, "ipad: %s", srtp_octet_string_hex_string(ipad, 64));
debug_print(srtp_mod_hmac, "ipad: %s",
srtp_octet_string_hex_string(ipad, 64));
/* initialize sha1 context */
srtp_sha1_init(&state->init_ctx);
@ -146,7 +154,7 @@ static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int k
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_start (void *statev)
static srtp_err_status_t srtp_hmac_start(void *statev)
{
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
@ -155,7 +163,9 @@ static srtp_err_status_t srtp_hmac_start (void *statev)
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
static srtp_err_status_t srtp_hmac_update(void *statev,
const uint8_t *message,
int msg_octets)
{
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
@ -168,8 +178,11 @@ static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message,
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message,
int msg_octets, int tag_len, uint8_t *result)
static srtp_err_status_t srtp_hmac_compute(void *statev,
const uint8_t *message,
int msg_octets,
int tag_len,
uint8_t *result)
{
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
uint32_t hash_value[5];
@ -190,49 +203,53 @@ static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message
* function hmac_update() already did that for us
*/
debug_print(srtp_mod_hmac, "intermediate state: %s",
srtp_octet_string_hex_string((uint8_t*)H, 20));
srtp_octet_string_hex_string((uint8_t *)H, 20));
/* re-initialize hash context */
srtp_sha1_init(&state->ctx);
/* hash opad ^ key */
srtp_sha1_update(&state->ctx, (uint8_t*)state->opad, 64);
srtp_sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
/* hash the result of the inner hash */
srtp_sha1_update(&state->ctx, (uint8_t*)H, 20);
srtp_sha1_update(&state->ctx, (uint8_t *)H, 20);
/* the result is returned in the array hash_value[] */
srtp_sha1_final(&state->ctx, hash_value);
/* copy hash_value to *result */
for (i = 0; i < tag_len; i++) {
result[i] = ((uint8_t*)hash_value)[i];
result[i] = ((uint8_t *)hash_value)[i];
}
debug_print(srtp_mod_hmac, "output: %s",
srtp_octet_string_hex_string((uint8_t*)hash_value, tag_len));
srtp_octet_string_hex_string((uint8_t *)hash_value, tag_len));
return srtp_err_status_ok;
}
/* begin test case 0 */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_key[20] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b
};
/* clang-format on */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_data[8] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
};
/* clang-format on */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_tag[20] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00
};
/* clang-format on */
static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
20, /* octets in key */
@ -246,21 +263,21 @@ static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
/* end test case 0 */
static const char srtp_hmac_description[] = "hmac sha-1 authentication function";
static const char srtp_hmac_description[] =
"hmac sha-1 authentication function";
/*
* srtp_auth_type_t hmac is the hmac metaobject
*/
const srtp_auth_type_t srtp_hmac = {
srtp_hmac_alloc,
srtp_hmac_dealloc,
srtp_hmac_init,
srtp_hmac_compute,
srtp_hmac_update,
srtp_hmac_start,
srtp_hmac_description,
&srtp_hmac_test_case_0,
SRTP_HMAC_SHA1
const srtp_auth_type_t srtp_hmac = {
srtp_hmac_alloc, /* */
srtp_hmac_dealloc, /* */
srtp_hmac_init, /* */
srtp_hmac_compute, /* */
srtp_hmac_update, /* */
srtp_hmac_start, /* */
srtp_hmac_description, /* */
&srtp_hmac_test_case_0, /* */
SRTP_HMAC_SHA1 /* */
};

View File

@ -43,31 +43,34 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "auth.h"
#include "alloc.h"
#include "err.h" /* for srtp_debug */
#include "err.h" /* for srtp_debug */
#include <openssl/evp.h>
#include <openssl/hmac.h>
#define SHA1_DIGEST_SIZE 20
#define SHA1_DIGEST_SIZE 20
/* the debug module for authentiation */
srtp_debug_module_t srtp_mod_hmac = {
0, /* debugging is off by default */
"hmac sha-1 openssl" /* printable name for module */
0, /* debugging is off by default */
"hmac sha-1 openssl" /* printable name for module */
};
static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
static srtp_err_status_t srtp_hmac_alloc(srtp_auth_t **a,
int key_len,
int out_len)
{
extern const srtp_auth_type_t srtp_hmac;
debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
debug_print(srtp_mod_hmac, " tag length %d", out_len);
debug_print(srtp_mod_hmac, "allocating auth func with key length %d",
key_len);
debug_print(srtp_mod_hmac, " tag length %d",
out_len);
/* check output length - should be less than 20 bytes */
if (out_len > SHA1_DIGEST_SIZE) {
@ -76,24 +79,25 @@ static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_
/* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated
using HMAC_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
{
/* allocate memory for auth and HMAC_CTX structures */
uint8_t* pointer;
uint8_t *pointer;
HMAC_CTX *new_hmac_ctx;
pointer = (uint8_t*)srtp_crypto_alloc(sizeof(HMAC_CTX) + sizeof(srtp_auth_t));
pointer = (uint8_t *)srtp_crypto_alloc(sizeof(HMAC_CTX) +
sizeof(srtp_auth_t));
if (pointer == NULL) {
return srtp_err_status_alloc_fail;
}
*a = (srtp_auth_t*)pointer;
*a = (srtp_auth_t *)pointer;
(*a)->state = pointer + sizeof(srtp_auth_t);
new_hmac_ctx = (HMAC_CTX*)((*a)->state);
new_hmac_ctx = (HMAC_CTX *)((*a)->state);
HMAC_CTX_init(new_hmac_ctx);
}
#else
*a = (srtp_auth_t*)srtp_crypto_alloc(sizeof(srtp_auth_t));
*a = (srtp_auth_t *)srtp_crypto_alloc(sizeof(srtp_auth_t));
if (*a == NULL) {
return srtp_err_status_alloc_fail;
}
@ -115,13 +119,13 @@ static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
static srtp_err_status_t srtp_hmac_dealloc(srtp_auth_t *a)
{
HMAC_CTX *hmac_ctx;
hmac_ctx = (HMAC_CTX*)a->state;
hmac_ctx = (HMAC_CTX *)a->state;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
HMAC_CTX_cleanup(hmac_ctx);
/* zeroize entire state*/
@ -140,7 +144,7 @@ static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_start (void *statev)
static srtp_err_status_t srtp_hmac_start(void *statev)
{
HMAC_CTX *state = (HMAC_CTX *)statev;
@ -150,7 +154,9 @@ static srtp_err_status_t srtp_hmac_start (void *statev)
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
static srtp_err_status_t srtp_hmac_init(void *statev,
const uint8_t *key,
int key_len)
{
HMAC_CTX *state = (HMAC_CTX *)statev;
@ -160,7 +166,9 @@ static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int k
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
static srtp_err_status_t srtp_hmac_update(void *statev,
const uint8_t *message,
int msg_octets)
{
HMAC_CTX *state = (HMAC_CTX *)statev;
@ -173,8 +181,11 @@ static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message,
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message,
int msg_octets, int tag_len, uint8_t *result)
static srtp_err_status_t srtp_hmac_compute(void *statev,
const uint8_t *message,
int msg_octets,
int tag_len,
uint8_t *result)
{
HMAC_CTX *state = (HMAC_CTX *)statev;
uint8_t hash_value[SHA1_DIGEST_SIZE];
@ -207,52 +218,56 @@ static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message
return srtp_err_status_ok;
}
/* begin test case 0 */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_key[SHA1_DIGEST_SIZE] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b
};
/* clang-format on */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_data[8] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
};
/* clang-format on */
/* clang-format off */
static const uint8_t srtp_hmac_test_case_0_tag[SHA1_DIGEST_SIZE] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00
};
/* clang-format on */
static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
sizeof(srtp_hmac_test_case_0_key), /* octets in key */
srtp_hmac_test_case_0_key, /* key */
sizeof(srtp_hmac_test_case_0_data), /* octets in data */
srtp_hmac_test_case_0_data, /* data */
sizeof(srtp_hmac_test_case_0_tag), /* octets in tag */
srtp_hmac_test_case_0_tag, /* tag */
NULL /* pointer to next testcase */
sizeof(srtp_hmac_test_case_0_key), /* octets in key */
srtp_hmac_test_case_0_key, /* key */
sizeof(srtp_hmac_test_case_0_data), /* octets in data */
srtp_hmac_test_case_0_data, /* data */
sizeof(srtp_hmac_test_case_0_tag), /* octets in tag */
srtp_hmac_test_case_0_tag, /* tag */
NULL /* pointer to next testcase */
};
/* end test case 0 */
static const char srtp_hmac_description[] = "hmac sha-1 authentication function";
static const char srtp_hmac_description[] =
"hmac sha-1 authentication function";
/*
* srtp_auth_type_t hmac is the hmac metaobject
*/
const srtp_auth_type_t srtp_hmac = {
srtp_hmac_alloc,
srtp_hmac_dealloc,
srtp_hmac_init,
srtp_hmac_compute,
srtp_hmac_update,
srtp_hmac_start,
srtp_hmac_description,
&srtp_hmac_test_case_0,
SRTP_HMAC_SHA1
const srtp_auth_type_t srtp_hmac = {
srtp_hmac_alloc, /* */
srtp_hmac_dealloc, /* */
srtp_hmac_init, /* */
srtp_hmac_compute, /* */
srtp_hmac_update, /* */
srtp_hmac_start, /* */
srtp_hmac_description, /* */
&srtp_hmac_test_case_0, /* */
SRTP_HMAC_SHA1 /* */
};

View File

@ -45,33 +45,35 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "null_auth.h"
#include "err.h" /* for srtp_debug */
#include "err.h" /* for srtp_debug */
#include "alloc.h"
#include "cipher_types.h"
/* null_auth uses the auth debug module */
extern srtp_debug_module_t srtp_mod_auth;
static srtp_err_status_t srtp_null_auth_alloc (srtp_auth_t **a, int key_len, int out_len)
static srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a,
int key_len,
int out_len)
{
extern const srtp_auth_type_t srtp_null_auth;
uint8_t *pointer;
debug_print(srtp_mod_auth, "allocating auth func with key length %d", key_len);
debug_print(srtp_mod_auth, " tag length %d", out_len);
debug_print(srtp_mod_auth, "allocating auth func with key length %d",
key_len);
debug_print(srtp_mod_auth, " tag length %d",
out_len);
/* allocate memory for auth and srtp_null_auth_ctx_t structures */
pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
pointer = (uint8_t *)srtp_crypto_alloc(sizeof(srtp_null_auth_ctx_t) +
sizeof(srtp_auth_t));
if (pointer == NULL) {
return srtp_err_status_alloc_fail;
}
/* set pointers */
*a = (srtp_auth_t*)pointer;
*a = (srtp_auth_t *)pointer;
(*a)->type = &srtp_null_auth;
(*a)->state = pointer + sizeof(srtp_auth_t);
(*a)->out_len = out_len;
@ -81,12 +83,13 @@ static srtp_err_status_t srtp_null_auth_alloc (srtp_auth_t **a, int key_len, int
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_auth_dealloc (srtp_auth_t *a)
static srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a)
{
extern const srtp_auth_type_t srtp_null_auth;
/* zeroize entire state*/
octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) +
sizeof(srtp_auth_t));
/* free memory */
srtp_crypto_free(a);
@ -94,7 +97,9 @@ static srtp_err_status_t srtp_null_auth_dealloc (srtp_auth_t *a)
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_auth_init (void *statev, const uint8_t *key, int key_len)
static srtp_err_status_t srtp_null_auth_init(void *statev,
const uint8_t *key,
int key_len)
{
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
/* accept any length of key, and do nothing */
@ -102,23 +107,27 @@ static srtp_err_status_t srtp_null_auth_init (void *statev, const uint8_t *key,
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_auth_compute (void *statev, const uint8_t *message,
int msg_octets, int tag_len, uint8_t *result)
static srtp_err_status_t srtp_null_auth_compute(void *statev,
const uint8_t *message,
int msg_octets,
int tag_len,
uint8_t *result)
{
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_auth_update (void *statev, const uint8_t *message,
int msg_octets)
static srtp_err_status_t srtp_null_auth_update(void *statev,
const uint8_t *message,
int msg_octets)
{
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
return srtp_err_status_ok;
}
static srtp_err_status_t srtp_null_auth_start (void *statev)
static srtp_err_status_t srtp_null_auth_start(void *statev)
{
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
@ -133,28 +142,27 @@ static srtp_err_status_t srtp_null_auth_start (void *statev)
/* begin test case 0 */
static const srtp_auth_test_case_t srtp_null_auth_test_case_0 = {
0, /* octets in key */
NULL, /* key */
0, /* octets in data */
NULL, /* data */
0, /* octets in tag */
NULL, /* tag */
NULL /* pointer to next testcase */
0, /* octets in key */
NULL, /* key */
0, /* octets in data */
NULL, /* data */
0, /* octets in tag */
NULL, /* tag */
NULL /* pointer to next testcase */
};
/* end test case 0 */
static const char srtp_null_auth_description[] = "null authentication function";
const srtp_auth_type_t srtp_null_auth = {
srtp_null_auth_alloc,
srtp_null_auth_dealloc,
srtp_null_auth_init,
srtp_null_auth_compute,
srtp_null_auth_update,
srtp_null_auth_start,
srtp_null_auth_description,
&srtp_null_auth_test_case_0,
SRTP_NULL_AUTH
const srtp_auth_type_t srtp_null_auth = {
srtp_null_auth_alloc, /* */
srtp_null_auth_dealloc, /* */
srtp_null_auth_init, /* */
srtp_null_auth_compute, /* */
srtp_null_auth_update, /* */
srtp_null_auth_start, /* */
srtp_null_auth_description, /* */
&srtp_null_auth_test_case_0, /* */
SRTP_NULL_AUTH /* */
};

View File

@ -45,19 +45,19 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "sha1.h"
srtp_debug_module_t srtp_mod_sha1 = {
0, /* debugging is off by default */
"sha-1" /* printable module name */
0, /* debugging is off by default */
"sha-1" /* printable module name */
};
/* SN == Rotate left N bits */
#define S1(X) ((X << 1) | (X >> 31))
#define S5(X) ((X << 5) | (X >> 27))
#define S1(X) ((X << 1) | (X >> 31))
#define S5(X) ((X << 5) | (X >> 27))
#define S30(X) ((X << 30) | (X >> 2))
#define f0(B, C, D) ((B & C) | (~B & D))
@ -71,19 +71,18 @@ srtp_debug_module_t srtp_mod_sha1 = {
* on systems that uses curses
*/
uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */
uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */
uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
void srtp_sha1 (const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
void srtp_sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
{
srtp_sha1_ctx_t ctx;
srtp_sha1_init(&ctx);
srtp_sha1_update(&ctx, msg, octets_in_msg);
srtp_sha1_final(&ctx, hash_value);
}
/*
@ -98,7 +97,7 @@ void srtp_sha1 (const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
* (crypto/cipher/seal.c)
*/
void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
void srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5])
{
uint32_t H0;
uint32_t H1;
@ -118,38 +117,54 @@ void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
/* copy/xor message into array */
W[0] = be32_to_cpu(M[0]);
W[1] = be32_to_cpu(M[1]);
W[2] = be32_to_cpu(M[2]);
W[3] = be32_to_cpu(M[3]);
W[4] = be32_to_cpu(M[4]);
W[5] = be32_to_cpu(M[5]);
W[6] = be32_to_cpu(M[6]);
W[7] = be32_to_cpu(M[7]);
W[8] = be32_to_cpu(M[8]);
W[9] = be32_to_cpu(M[9]);
W[0] = be32_to_cpu(M[0]);
W[1] = be32_to_cpu(M[1]);
W[2] = be32_to_cpu(M[2]);
W[3] = be32_to_cpu(M[3]);
W[4] = be32_to_cpu(M[4]);
W[5] = be32_to_cpu(M[5]);
W[6] = be32_to_cpu(M[6]);
W[7] = be32_to_cpu(M[7]);
W[8] = be32_to_cpu(M[8]);
W[9] = be32_to_cpu(M[9]);
W[10] = be32_to_cpu(M[10]);
W[11] = be32_to_cpu(M[11]);
W[12] = be32_to_cpu(M[12]);
W[13] = be32_to_cpu(M[13]);
W[14] = be32_to_cpu(M[14]);
W[15] = be32_to_cpu(M[15]);
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP);
TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP);
TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP);
TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP);
TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP);
TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP);
TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP);
TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP);
TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP);
TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP);
TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP);
TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP);
TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP);
TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP);
TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP);
TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0];
W[16] = S1(TEMP);
TEMP = W[14] ^ W[9] ^ W[3] ^ W[1];
W[17] = S1(TEMP);
TEMP = W[15] ^ W[10] ^ W[4] ^ W[2];
W[18] = S1(TEMP);
TEMP = W[16] ^ W[11] ^ W[5] ^ W[3];
W[19] = S1(TEMP);
TEMP = W[17] ^ W[12] ^ W[6] ^ W[4];
W[20] = S1(TEMP);
TEMP = W[18] ^ W[13] ^ W[7] ^ W[5];
W[21] = S1(TEMP);
TEMP = W[19] ^ W[14] ^ W[8] ^ W[6];
W[22] = S1(TEMP);
TEMP = W[20] ^ W[15] ^ W[9] ^ W[7];
W[23] = S1(TEMP);
TEMP = W[21] ^ W[16] ^ W[10] ^ W[8];
W[24] = S1(TEMP);
TEMP = W[22] ^ W[17] ^ W[11] ^ W[9];
W[25] = S1(TEMP);
TEMP = W[23] ^ W[18] ^ W[12] ^ W[10];
W[26] = S1(TEMP);
TEMP = W[24] ^ W[19] ^ W[13] ^ W[11];
W[27] = S1(TEMP);
TEMP = W[25] ^ W[20] ^ W[14] ^ W[12];
W[28] = S1(TEMP);
TEMP = W[26] ^ W[21] ^ W[15] ^ W[13];
W[29] = S1(TEMP);
TEMP = W[27] ^ W[22] ^ W[16] ^ W[14];
W[30] = S1(TEMP);
TEMP = W[28] ^ W[23] ^ W[17] ^ W[15];
W[31] = S1(TEMP);
/* process the remainder of the array */
for (t = 32; t < 80; t++) {
@ -157,23 +172,43 @@ void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
W[t] = S1(TEMP);
}
A = H0; B = H1; C = H2; D = H3; E = H4;
A = H0;
B = H1;
C = H2;
D = H3;
E = H4;
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
hash_value[0] = H0 + A;
@ -185,9 +220,8 @@ void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
return;
}
void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
void srtp_sha1_init(srtp_sha1_ctx_t *ctx)
{
/* initialize state vector */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
@ -200,22 +234,21 @@ void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
/* reset message bit-count to zero */
ctx->num_bits_in_msg = 0;
}
void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg)
void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
const uint8_t *msg,
int octets_in_msg)
{
int i;
uint8_t *buf = (uint8_t*)ctx->M;
uint8_t *buf = (uint8_t *)ctx->M;
/* update message bit-count */
ctx->num_bits_in_msg += octets_in_msg * 8;
/* loop over 16-word blocks of M */
while (octets_in_msg > 0) {
if (octets_in_msg + ctx->octets_in_buffer >= 64) {
/*
* copy words of M into msg buffer until that buffer is full,
* converting them into host byte order as needed
@ -228,13 +261,14 @@ void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_m
/* process a whole block */
debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()", NULL);
debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()",
NULL);
srtp_sha1_core(ctx->M, ctx->H);
} else {
debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()", NULL);
debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()",
NULL);
for (i = ctx->octets_in_buffer;
i < (ctx->octets_in_buffer + octets_in_msg); i++) {
@ -243,9 +277,7 @@ void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_m
ctx->octets_in_buffer += octets_in_msg;
octets_in_msg = 0;
}
}
}
/*
@ -253,7 +285,7 @@ void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_m
* into the twenty octets located at *output
*/
void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
{
uint32_t A, B, C, D, E, TEMP;
uint32_t W[80];
@ -268,7 +300,7 @@ void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
/* copy/xor message into array */
for (i = 0; i < (ctx->octets_in_buffer + 3) / 4; i++) {
W[i] = be32_to_cpu(ctx->M[i]);
W[i] = be32_to_cpu(ctx->M[i]);
}
/* set the high bit of the octet immediately following the message */
@ -321,19 +353,35 @@ void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
ctx->H[0] += A;
@ -341,14 +389,13 @@ void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
}
debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
if (ctx->octets_in_buffer >= 56) {
debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again", NULL);
debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again",
NULL);
/* we need to do one final run of the compression algo */
@ -375,19 +422,35 @@ void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
for (t = 0; t < 20; t++) {
TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 40; t++) {
TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 60; t++) {
TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
for (; t < 80; t++) {
TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
E = D; D = C; C = S30(B); B = A; A = TEMP;
E = D;
D = C;
C = S30(B);
B = A;
A = TEMP;
}
ctx->H[0] += A;
@ -409,6 +472,3 @@ void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
return;
}

View File

@ -70,9 +70,11 @@ srtp_err_status_t srtp_aes_expand_decryption_key(
int key_len,
srtp_aes_expanded_key_t *expanded_key);
void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
void srtp_aes_encrypt(v128_t *plaintext,
const srtp_aes_expanded_key_t *exp_key);
void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
void srtp_aes_decrypt(v128_t *plaintext,
const srtp_aes_expanded_key_t *exp_key);
#ifdef __cplusplus
}

View File

@ -55,9 +55,8 @@
typedef struct {
int key_size;
int tag_len;
EVP_CIPHER_CTX* ctx;
EVP_CIPHER_CTX *ctx;
srtp_cipher_direction_t dir;
} srtp_aes_gcm_ctx_t;
#endif /* AES_GCM_OSSL_H */

View File

@ -9,26 +9,26 @@
*/
/*
*
*
* 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
@ -60,4 +60,3 @@ typedef struct {
} srtp_aes_icm_ctx_t;
#endif /* AES_ICM_H */

View File

@ -52,11 +52,10 @@
#include <openssl/aes.h>
typedef struct {
v128_t counter; /* holds the counter value */
v128_t offset; /* initial offset value */
v128_t counter; /* holds the counter value */
v128_t offset; /* initial offset value */
int key_size;
EVP_CIPHER_CTX* ctx;
EVP_CIPHER_CTX *ctx;
} srtp_aes_icm_ctx_t;
#endif /* AES_ICM_H */

View File

@ -1,32 +1,32 @@
/*
* alloc.h
*
* interface to memory allocation and deallocation, with optional debugging
* interface to memory allocation and deallocation, with optional debugging
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -42,7 +42,6 @@
*
*/
#ifndef CRYPTO_ALLOC_H
#define CRYPTO_ALLOC_H
@ -52,8 +51,22 @@
extern "C" {
#endif
void * srtp_crypto_alloc(size_t size);
/*
* srtp_crypto_alloc
*
* Allocates a block of memory of given size. The memory will be
* initialized to zero's. Free the memory with a call to srtp_crypto_free.
*
* returns pointer to memory on success or else NULL
*/
void *srtp_crypto_alloc(size_t size);
/*
* srtp_crypto_free
*
* Frees the block of memory ptr previously allocated with
* srtp_crypto_alloc
*/
void srtp_crypto_free(void *ptr);
#ifdef __cplusplus

View File

@ -47,46 +47,51 @@
#define SRTP_AUTH_H
#include "srtp.h"
#include "crypto_types.h" /* for values of auth_type_id_t */
#include "crypto_types.h" /* for values of auth_type_id_t */
#ifdef __cplusplus
extern "C" {
#endif
typedef const struct srtp_auth_type_t *srtp_auth_type_pointer;
typedef struct srtp_auth_t *srtp_auth_pointer_t;
typedef struct srtp_auth_t *srtp_auth_pointer_t;
typedef srtp_err_status_t (*srtp_auth_alloc_func)
(srtp_auth_pointer_t *ap, int key_len, int out_len);
typedef srtp_err_status_t (*srtp_auth_alloc_func)(srtp_auth_pointer_t *ap,
int key_len,
int out_len);
typedef srtp_err_status_t (*srtp_auth_init_func)
(void *state, const uint8_t *key, int key_len);
typedef srtp_err_status_t (*srtp_auth_init_func)(void *state,
const uint8_t *key,
int key_len);
typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap);
typedef srtp_err_status_t (*srtp_auth_compute_func)
(void *state, const uint8_t *buffer, int octets_to_auth,
int tag_len, uint8_t *tag);
typedef srtp_err_status_t (*srtp_auth_compute_func)(void *state,
const uint8_t *buffer,
int octets_to_auth,
int tag_len,
uint8_t *tag);
typedef srtp_err_status_t (*srtp_auth_update_func)
(void *state, const uint8_t *buffer, int octets_to_auth);
typedef srtp_err_status_t (*srtp_auth_update_func)(void *state,
const uint8_t *buffer,
int octets_to_auth);
typedef srtp_err_status_t (*srtp_auth_start_func)(void *state);
/* some syntactic sugar on these function types */
#define srtp_auth_type_alloc(at, a, klen, outlen) \
#define srtp_auth_type_alloc(at, a, klen, outlen) \
((at)->alloc((a), (klen), (outlen)))
#define srtp_auth_init(a, key) \
#define srtp_auth_init(a, key) \
(((a)->type)->init((a)->state, (key), ((a)->key_len)))
#define srtp_auth_compute(a, buf, len, res) \
#define srtp_auth_compute(a, buf, len, res) \
(((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
#define srtp_auth_update(a, buf, len) \
#define srtp_auth_update(a, buf, len) \
(((a)->type)->update((a)->state, (buf), (len)))
#define srtp_auth_start(a)(((a)->type)->start((a)->state))
#define srtp_auth_start(a) (((a)->type)->start((a)->state))
#define srtp_auth_dealloc(c) (((c)->type)->dealloc(c))
@ -105,13 +110,14 @@ int srtp_auth_get_prefix_length(const struct srtp_auth_t *a);
* function below)
*/
typedef struct srtp_auth_test_case_t {
int key_length_octets; /* octets in key */
const uint8_t *key; /* key */
int data_length_octets; /* octets in data */
const uint8_t *data; /* data */
int tag_length_octets; /* octets in tag */
const uint8_t *tag; /* tag */
const struct srtp_auth_test_case_t *next_test_case; /* pointer to next testcase */
int key_length_octets; /* octets in key */
const uint8_t *key; /* key */
int data_length_octets; /* octets in data */
const uint8_t *data; /* data */
int tag_length_octets; /* octets in tag */
const uint8_t *tag; /* tag */
const struct srtp_auth_test_case_t
*next_test_case; /* pointer to next testcase */
} srtp_auth_test_case_t;
/* srtp_auth_type_t */
@ -122,17 +128,17 @@ typedef struct srtp_auth_type_t {
srtp_auth_compute_func compute;
srtp_auth_update_func update;
srtp_auth_start_func start;
const char *description;
const srtp_auth_test_case_t *test_data;
const char *description;
const srtp_auth_test_case_t *test_data;
srtp_auth_type_id_t id;
} srtp_auth_type_t;
typedef struct srtp_auth_t {
const srtp_auth_type_t *type;
void *state;
int out_len; /* length of output tag in octets */
int key_len; /* length of key in octets */
int prefix_len; /* length of keystream prefix */
void *state;
int out_len; /* length of output tag in octets */
int key_len; /* length of key in octets */
int prefix_len; /* length of keystream prefix */
} srtp_auth_t;
/*
@ -147,8 +153,8 @@ srtp_err_status_t srtp_auth_type_self_test(const srtp_auth_type_t *at);
* provided in an array of values of key/message/tag that is known to
* be good
*/
srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
const srtp_auth_test_case_t *test_data);
srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
const srtp_auth_test_case_t *test_data);
/*
* srtp_replace_auth_type(ct, id)
@ -157,7 +163,8 @@ srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
* with a new one passed in externally. The new auth type must pass all the
* existing auth_type's self tests as well as its own.
*/
srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *ct, srtp_auth_type_id_t id);
srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *ct,
srtp_auth_type_id_t id);
#ifdef __cplusplus
}

View File

@ -42,13 +42,11 @@
*
*/
#ifndef SRTP_CIPHER_H
#define SRTP_CIPHER_H
#include "srtp.h"
#include "crypto_types.h" /* for values of cipher_type_id_t */
#include "crypto_types.h" /* for values of cipher_type_id_t */
#ifdef __cplusplus
extern "C" {
@ -71,51 +69,60 @@ typedef enum {
* the srtp_cipher_pointer_t definition is needed
* as srtp_cipher_t is not yet defined
*/
typedef struct srtp_cipher_t *srtp_cipher_pointer_t;
typedef struct srtp_cipher_t *srtp_cipher_pointer_t;
/*
* a srtp_cipher_alloc_func_t allocates (but does not initialize) a srtp_cipher_t
* a srtp_cipher_alloc_func_t allocates (but does not initialize) a
* srtp_cipher_t
*/
typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)
(srtp_cipher_pointer_t *cp, int key_len, int tag_len);
typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)(srtp_cipher_pointer_t *cp,
int key_len,
int tag_len);
/*
* a srtp_cipher_init_func_t [re-]initializes a cipher_t with a given key
*/
typedef srtp_err_status_t (*srtp_cipher_init_func_t)
(void *state, const uint8_t *key);
typedef srtp_err_status_t (*srtp_cipher_init_func_t)(void *state,
const uint8_t *key);
/* a srtp_cipher_dealloc_func_t de-allocates a cipher_t */
typedef srtp_err_status_t (*srtp_cipher_dealloc_func_t)(srtp_cipher_pointer_t cp);
typedef srtp_err_status_t (*srtp_cipher_dealloc_func_t)(
srtp_cipher_pointer_t cp);
/*
* a srtp_cipher_set_aad_func_t processes the AAD data for AEAD ciphers
*/
typedef srtp_err_status_t (*srtp_cipher_set_aad_func_t)
(void *state, const uint8_t *aad, uint32_t aad_len);
typedef srtp_err_status_t (*srtp_cipher_set_aad_func_t)(void *state,
const uint8_t *aad,
uint32_t aad_len);
/* a srtp_cipher_encrypt_func_t encrypts data in-place */
typedef srtp_err_status_t (*srtp_cipher_encrypt_func_t)
(void *state, uint8_t *buffer, unsigned int *octets_to_encrypt);
typedef srtp_err_status_t (*srtp_cipher_encrypt_func_t)(
void *state,
uint8_t *buffer,
unsigned int *octets_to_encrypt);
/* a srtp_cipher_decrypt_func_t decrypts data in-place */
typedef srtp_err_status_t (*srtp_cipher_decrypt_func_t)
(void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);
typedef srtp_err_status_t (*srtp_cipher_decrypt_func_t)(
void *state,
uint8_t *buffer,
unsigned int *octets_to_decrypt);
/*
* a srtp_cipher_set_iv_func_t function sets the current initialization vector
*/
typedef srtp_err_status_t (*srtp_cipher_set_iv_func_t)
(void *state, uint8_t *iv, srtp_cipher_direction_t direction);
typedef srtp_err_status_t (*srtp_cipher_set_iv_func_t)(
void *state,
uint8_t *iv,
srtp_cipher_direction_t direction);
/*
* a cipher_get_tag_func_t function is used to get the authentication
* tag that was calculated by an AEAD cipher.
*/
typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)
(void *state, uint8_t *tag, uint32_t *len);
typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)(void *state,
uint8_t *tag,
uint32_t *len);
/*
* srtp_cipher_test_case_t is a (list of) key, salt, plaintext, ciphertext,
@ -125,17 +132,18 @@ typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)
* (see the srtp_cipher_type_self_test() function below)
*/
typedef struct srtp_cipher_test_case_t {
int key_length_octets; /* octets in key */
const uint8_t *key; /* key */
uint8_t *idx; /* packet index */
int plaintext_length_octets; /* octets in plaintext */
const uint8_t *plaintext; /* plaintext */
int ciphertext_length_octets; /* octets in plaintext */
const uint8_t *ciphertext; /* ciphertext */
int aad_length_octets; /* octets in AAD */
const uint8_t *aad; /* AAD */
int tag_length_octets; /* Length of AEAD tag */
const struct srtp_cipher_test_case_t *next_test_case; /* pointer to next testcase */
int key_length_octets; /* octets in key */
const uint8_t *key; /* key */
uint8_t *idx; /* packet index */
unsigned int plaintext_length_octets; /* octets in plaintext */
const uint8_t *plaintext; /* plaintext */
unsigned int ciphertext_length_octets; /* octets in plaintext */
const uint8_t *ciphertext; /* ciphertext */
int aad_length_octets; /* octets in AAD */
const uint8_t *aad; /* AAD */
int tag_length_octets; /* Length of AEAD tag */
const struct srtp_cipher_test_case_t
*next_test_case; /* pointer to next testcase */
} srtp_cipher_test_case_t;
/* srtp_cipher_type_t defines the 'metadata' for a particular cipher type */
@ -148,8 +156,8 @@ typedef struct srtp_cipher_type_t {
srtp_cipher_encrypt_func_t decrypt;
srtp_cipher_set_iv_func_t set_iv;
srtp_cipher_get_tag_func_t get_tag;
const char *description;
const srtp_cipher_test_case_t *test_data;
const char *description;
const srtp_cipher_test_case_t *test_data;
srtp_cipher_type_id_t id;
} srtp_cipher_type_t;
@ -159,7 +167,7 @@ typedef struct srtp_cipher_type_t {
*/
typedef struct srtp_cipher_t {
const srtp_cipher_type_t *type;
void *state;
void *state;
int key_len;
int algorithm;
} srtp_cipher_t;
@ -167,7 +175,6 @@ typedef struct srtp_cipher_t {
/* some bookkeeping functions */
int srtp_cipher_get_key_length(const srtp_cipher_t *c);
/*
* srtp_cipher_type_self_test() tests a cipher against test cases provided in
* an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext
@ -175,14 +182,15 @@ int srtp_cipher_get_key_length(const srtp_cipher_t *c);
*/
srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct);
/*
* srtp_cipher_type_test() tests a cipher against external test cases provided in
* srtp_cipher_type_test() tests a cipher against external test cases provided
* in
* an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext
* that is known to be good
*/
srtp_err_status_t srtp_cipher_type_test(const srtp_cipher_type_t *ct, const srtp_cipher_test_case_t *test_data);
srtp_err_status_t srtp_cipher_type_test(
const srtp_cipher_type_t *ct,
const srtp_cipher_test_case_t *test_data);
/*
* srtp_cipher_bits_per_second(c, l, t) computes (an estimate of) the
@ -194,17 +202,34 @@ srtp_err_status_t srtp_cipher_type_test(const srtp_cipher_type_t *ct, const srtp
*
* if an error is encountered, then the value 0 is returned
*/
uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c, int octets_in_buffer, int num_trials);
uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
int octets_in_buffer,
int num_trials);
srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct, srtp_cipher_t **c, int key_len, int tlen);
srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct,
srtp_cipher_t **c,
int key_len,
int tlen);
srtp_err_status_t srtp_cipher_dealloc(srtp_cipher_t *c);
srtp_err_status_t srtp_cipher_init(srtp_cipher_t *c, const uint8_t *key);
srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c, uint8_t *iv, int direction);
srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c, uint8_t *buffer, uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c, uint8_t *buffer, uint32_t *tag_len);
srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c, const uint8_t *aad, uint32_t aad_len);
srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c,
uint8_t *iv,
int direction);
srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *num_octets_to_output);
srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c,
uint8_t *buffer,
uint32_t *tag_len);
srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c,
const uint8_t *aad,
uint32_t aad_len);
/*
* srtp_replace_cipher_type(ct, id)
@ -213,7 +238,8 @@ srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c, const uint8_t *aad, uint
* with a new one passed in externally. The new cipher must pass all the
* existing cipher_type's self tests as well as its own.
*/
srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *ct, srtp_cipher_type_id_t id);
srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *ct,
srtp_cipher_type_id_t id);
#ifdef __cplusplus
}

View File

@ -1,32 +1,24 @@
/*
* rtp_priv.h
*
* private, internal header file for RTP
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006 Cisco Systems, Inc.
* 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
@ -42,33 +34,48 @@
*
*/
#ifndef CIHPER_TYPES_H
#define CIHPER_TYPES_H
#ifndef RTP_PRIV_H
#define RTP_PRIV_H
#include "cipher.h"
#include "auth.h"
#include "srtp_priv.h"
#include "rtp.h"
/*
* cipher types that can be included in the kernel
*/
typedef srtp_hdr_t rtp_hdr_t;
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
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;
#endif
typedef struct {
srtp_hdr_t header;
char body[RTP_MAX_BUF_LEN];
} rtp_msg_t;
/*
* auth func types that can be included in the kernel
*/
typedef struct rtp_sender_ctx_t {
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* reciever's address */
} rtp_sender_ctx_t;
extern const srtp_auth_type_t srtp_null_auth;
extern const srtp_auth_type_t srtp_hmac;
typedef struct rtp_receiver_ctx_t {
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* receiver's address */
} rtp_receiver_ctx_t;
/*
* other generic debug modules that can be included in the kernel
*/
extern srtp_debug_module_t srtp_mod_auth;
extern srtp_debug_module_t srtp_mod_cipher;
extern srtp_debug_module_t srtp_mod_stat;
extern srtp_debug_module_t srtp_mod_alloc;
#endif /* RTP_PRIV_H */
/* debug modules for cipher types */
extern srtp_debug_module_t srtp_mod_aes_icm;
#ifdef OPENSSL
extern srtp_debug_module_t srtp_mod_aes_gcm;
#endif
/* debug modules for auth types */
extern srtp_debug_module_t srtp_mod_hmac;
#endif

View File

@ -42,7 +42,6 @@
*
*/
#ifndef CRYPTO_KERNEL
#define CRYPTO_KERNEL
@ -72,7 +71,7 @@ typedef enum {
*/
typedef struct srtp_kernel_cipher_type {
srtp_cipher_type_id_t id;
const srtp_cipher_type_t *cipher_type;
const srtp_cipher_type_t *cipher_type;
struct srtp_kernel_cipher_type *next;
} srtp_kernel_cipher_type_t;
@ -81,7 +80,7 @@ typedef struct srtp_kernel_cipher_type {
*/
typedef struct srtp_kernel_auth_type {
srtp_auth_type_id_t id;
const srtp_auth_type_t *auth_type;
const srtp_auth_type_t *auth_type;
struct srtp_kernel_auth_type *next;
} srtp_kernel_auth_type_t;
@ -93,7 +92,6 @@ typedef struct srtp_kernel_debug_module {
struct srtp_kernel_debug_module *next;
} srtp_kernel_debug_module_t;
/*
* crypto_kernel_t is the data structure for the crypto kernel
*
@ -101,18 +99,17 @@ typedef struct srtp_kernel_debug_module {
* a global variable defined in crypto_kernel.c
*/
typedef struct {
srtp_crypto_kernel_state_t state; /* current state of kernel */
srtp_kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */
srtp_kernel_auth_type_t *auth_type_list; /* list of all auth func types */
srtp_kernel_debug_module_t *debug_module_list; /* list of all debug modules */
srtp_crypto_kernel_state_t state; /* current state of kernel */
srtp_kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */
srtp_kernel_auth_type_t *auth_type_list; /* list of all auth func types */
srtp_kernel_debug_module_t
*debug_module_list; /* list of all debug modules */
} srtp_crypto_kernel_t;
/*
* srtp_crypto_kernel_t external api
*/
/*
* The function srtp_crypto_kernel_init() initialized the crypto kernel and
* runs the self-test operations on the random number generators and
@ -126,7 +123,6 @@ typedef struct {
*/
srtp_err_status_t srtp_crypto_kernel_init(void);
/*
* The function srtp_crypto_kernel_shutdown() de-initializes the
* crypto_kernel, zeroizes keys and other cryptographic material, and
@ -150,7 +146,6 @@ srtp_err_status_t srtp_crypto_kernel_shutdown(void);
*/
srtp_err_status_t srtp_crypto_kernel_status(void);
/*
* srtp_crypto_kernel_list_debug_modules() outputs a list of debugging modules
*
@ -161,11 +156,15 @@ srtp_err_status_t srtp_crypto_kernel_list_debug_modules(void);
* srtp_crypto_kernel_load_cipher_type()
*
*/
srtp_err_status_t srtp_crypto_kernel_load_cipher_type(const srtp_cipher_type_t *ct, srtp_cipher_type_id_t id);
srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
const srtp_cipher_type_t *ct,
srtp_cipher_type_id_t id);
srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct, srtp_auth_type_id_t id);
srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct,
srtp_auth_type_id_t id);
srtp_err_status_t srtp_crypto_kernel_load_debug_module(srtp_debug_module_t *new_dm);
srtp_err_status_t srtp_crypto_kernel_load_debug_module(
srtp_debug_module_t *new_dm);
/*
* srtp_crypto_kernel_alloc_cipher(id, cp, key_len);
@ -177,7 +176,10 @@ srtp_err_status_t srtp_crypto_kernel_load_debug_module(srtp_debug_module_t *new_
* srtp_err_status_alloc_fail an allocation failure occured
* srtp_err_status_fail couldn't find cipher with identifier 'id'
*/
srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id, srtp_cipher_pointer_t *cp, int key_len, int tag_len);
srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id,
srtp_cipher_pointer_t *cp,
int key_len,
int tag_len);
/*
* srtp_crypto_kernel_alloc_auth(id, ap, key_len, tag_len);
@ -190,8 +192,10 @@ srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id, srtp
* srtp_err_status_alloc_fail an allocation failure occured
* srtp_err_status_fail couldn't find auth with identifier 'id'
*/
srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id, srtp_auth_pointer_t *ap, int key_len, int tag_len);
srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id,
srtp_auth_pointer_t *ap,
int key_len,
int tag_len);
/*
* srtp_crypto_kernel_set_debug_module(mod_name, v)
@ -201,7 +205,8 @@ srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id, srtp_aut
*
* returns srtp_err_status_ok on success, srtp_err_status_fail otherwise
*/
srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *mod_name, int v);
srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *mod_name,
int v);
#ifdef __cplusplus
}

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -48,62 +48,62 @@
/*
* The null cipher performs no encryption.
*
* The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the
* The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the
* encryption and decryption operations. This cipher can be chosen
* to indicate that no encryption is to be performed.
*/
#define SRTP_NULL_CIPHER 0
#define SRTP_NULL_CIPHER 0
/*
/*
* AES-128 Integer Counter Mode (AES ICM)
*
* AES-128 ICM is the variant of counter mode that is used by
* Secure RTP. This cipher uses a 16-octet key concatenated with a
* 14-octet offset (or salt) value.
*/
#define SRTP_AES_ICM_128 1
#define SRTP_AES_ICM_128 1
/*
/*
* AES-192 Integer Counter Mode (AES ICM)
*
* AES-128 ICM is the variant of counter mode that is used by
* Secure RTP. This cipher uses a 24-octet key concatenated with a
* 14-octet offset (or salt) value.
*/
#define SRTP_AES_ICM_192 4
#define SRTP_AES_ICM_192 4
/*
/*
* AES-256 Integer Counter Mode (AES ICM)
*
* AES-128 ICM is the variant of counter mode that is used by
* Secure RTP. This cipher uses a 32-octet key concatenated with a
* 14-octet offset (or salt) value.
*/
#define SRTP_AES_ICM_256 5
#define SRTP_AES_ICM_256 5
/*
* AES-128_GCM Galois Counter Mode (AES GCM)
/*
* AES-128_GCM Galois Counter Mode (AES GCM)
*
* AES-128 GCM is the variant of galois counter mode that is used by
* AES-128 GCM is the variant of galois counter mode that is used by
* Secure RTP. This cipher uses a 16-octet key.
*/
#define SRTP_AES_GCM_128 6
#define SRTP_AES_GCM_128 6
/*
* AES-256_GCM Galois Counter Mode (AES GCM)
/*
* AES-256_GCM Galois Counter Mode (AES GCM)
*
* AES-256 GCM is the variant of galois counter mode that is used by
* AES-256 GCM is the variant of galois counter mode that is used by
* Secure RTP. This cipher uses a 32-octet key.
*/
#define SRTP_AES_GCM_256 7
#define SRTP_AES_GCM_256 7
/*
* The null authentication function performs no authentication.
*
* The NULL_AUTH function does nothing, and can be selected to indicate
* that authentication should not be performed.
*/
#define SRTP_NULL_AUTH 0
*/
#define SRTP_NULL_AUTH 0
/*
* HMAC-SHA1
@ -111,6 +111,6 @@
* SRTP_HMAC_SHA1 implements the Hash-based MAC using the NIST Secure
* Hash Algorithm version 1 (SHA1).
*/
#define SRTP_HMAC_SHA1 3
#define SRTP_HMAC_SHA1 3
#endif /* SRTP_CRYPTO_TYPES_H */
#endif /* SRTP_CRYPTO_TYPES_H */

View File

@ -1,6 +1,6 @@
/*
* datatypes.h
*
*
* data types for bit vectors and finite fields
*
* David A. McGrew
@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -43,11 +43,10 @@
*
*/
#ifndef DATATYPES_H
#define DATATYPES_H
#include "integers.h" /* definitions of uint32_t, et cetera */
#include "integers.h" /* definitions of uint32_t, et cetera */
#include "alloc.h"
#include <stdarg.h>
@ -56,42 +55,43 @@
#include <string.h>
#include <time.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#include <netinet/in.h>
#elif defined HAVE_WINSOCK2_H
# include <winsock2.h>
#include <winsock2.h>
#else
#error "Platform not recognized"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* if DATATYPES_USE_MACROS is defined, then little functions are macros */
#define DATATYPES_USE_MACROS
#define DATATYPES_USE_MACROS
typedef union {
uint8_t v8[2];
uint16_t value;
uint8_t v8[2];
uint16_t value;
} v16_t;
typedef union {
uint8_t v8[4];
uint16_t v16[2];
uint32_t value;
uint8_t v8[4];
uint16_t v16[2];
uint32_t value;
} v32_t;
typedef union {
uint8_t v8[8];
uint16_t v16[4];
uint32_t v32[2];
uint64_t value;
uint8_t v8[8];
uint16_t v16[4];
uint32_t v32[2];
uint64_t value;
} v64_t;
typedef union {
uint8_t v8[16];
uint16_t v16[8];
uint32_t v32[4];
uint64_t v64[2];
uint8_t v8[16];
uint16_t v16[8];
uint32_t v32[4];
uint64_t v64[2];
} v128_t;
typedef union {
@ -101,118 +101,82 @@ typedef union {
uint64_t v64[4];
} v256_t;
/* some useful and simple math functions */
#define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */
#define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */
#define pow_2(X) ((unsigned int)1 << (X)) /* 2^X */
#define pow_minus_one(X) ((X) ? -1 : 1) /* (-1)^X */
/*
* octet_get_weight(x) returns the hamming weight (number of bits equal to
* one) in the octet x
*/
int
octet_get_weight(uint8_t octet);
int octet_get_weight(uint8_t octet);
#define MAX_PRINT_STRING_LEN 1024
char *
srtp_octet_string_hex_string(const void *str, int length);
char *srtp_octet_string_hex_string(const void *str, int length);
char *
v128_bit_string(v128_t *x);
char *v128_bit_string(v128_t *x);
char *
v128_hex_string(v128_t *x);
char *v128_hex_string(v128_t *x);
void
v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
void v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
void
v128_left_shift(v128_t *x, int shift_index);
void v128_left_shift(v128_t *x, int shift_index);
void
v128_right_shift(v128_t *x, int shift_index);
void v128_right_shift(v128_t *x, int shift_index);
/*
* the following macros define the data manipulation functions
*
*
* If DATATYPES_USE_MACROS is defined, then these macros are used
* directly (and function call overhead is avoided). Otherwise,
* the macros are used through the functions defined in datatypes.c
* (and the compiler provides better warnings).
*/
#define _v128_set_to_zero(x) \
( \
(x)->v32[0] = 0, \
(x)->v32[1] = 0, \
(x)->v32[2] = 0, \
(x)->v32[3] = 0 \
)
#define _v128_set_to_zero(x) \
((x)->v32[0] = 0, (x)->v32[1] = 0, (x)->v32[2] = 0, (x)->v32[3] = 0)
#define _v128_copy(x, y) \
( \
(x)->v32[0] = (y)->v32[0], \
(x)->v32[1] = (y)->v32[1], \
(x)->v32[2] = (y)->v32[2], \
(x)->v32[3] = (y)->v32[3] \
)
#define _v128_copy(x, y) \
((x)->v32[0] = (y)->v32[0], (x)->v32[1] = (y)->v32[1], \
(x)->v32[2] = (y)->v32[2], (x)->v32[3] = (y)->v32[3])
#define _v128_xor(z, x, y) \
( \
(z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \
)
#define _v128_xor(z, x, y) \
((z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] ^ (y)->v32[3])
#define _v128_and(z, x, y) \
( \
(z)->v32[0] = (x)->v32[0] & (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] & (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] & (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] & (y)->v32[3] \
)
#define _v128_and(z, x, y) \
((z)->v32[0] = (x)->v32[0] & (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] & (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] & (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] & (y)->v32[3])
#define _v128_or(z, x, y) \
( \
(z)->v32[0] = (x)->v32[0] | (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] | (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] | (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] | (y)->v32[3] \
)
#define _v128_or(z, x, y) \
((z)->v32[0] = (x)->v32[0] | (y)->v32[0], \
(z)->v32[1] = (x)->v32[1] | (y)->v32[1], \
(z)->v32[2] = (x)->v32[2] | (y)->v32[2], \
(z)->v32[3] = (x)->v32[3] | (y)->v32[3])
#define _v128_complement(x) \
( \
(x)->v32[0] = ~(x)->v32[0], \
(x)->v32[1] = ~(x)->v32[1], \
(x)->v32[2] = ~(x)->v32[2], \
(x)->v32[3] = ~(x)->v32[3] \
)
#define _v128_complement(x) \
((x)->v32[0] = ~(x)->v32[0], (x)->v32[1] = ~(x)->v32[1], \
(x)->v32[2] = ~(x)->v32[2], (x)->v32[3] = ~(x)->v32[3])
/* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */
#define _v128_is_eq(x, y) \
(((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
#define _v128_is_eq(x, y) \
(((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
#ifdef NO_64BIT_MATH
#define _v128_xor_eq(z, x) \
( \
(z)->v32[0] ^= (x)->v32[0], \
(z)->v32[1] ^= (x)->v32[1], \
(z)->v32[2] ^= (x)->v32[2], \
(z)->v32[3] ^= (x)->v32[3] \
)
#define _v128_xor_eq(z, x) \
((z)->v32[0] ^= (x)->v32[0], (z)->v32[1] ^= (x)->v32[1], \
(z)->v32[2] ^= (x)->v32[2], (z)->v32[3] ^= (x)->v32[3])
#else
#define _v128_xor_eq(z, x) \
( \
(z)->v64[0] ^= (x)->v64[0], \
(z)->v64[1] ^= (x)->v64[1] \
)
#define _v128_xor_eq(z, x) \
((z)->v64[0] ^= (x)->v64[0], (z)->v64[1] ^= (x)->v64[1])
#endif
/* NOTE! This assumes an odd ordering! */
@ -224,76 +188,55 @@ v128_right_shift(v128_t *x, int shift_index);
really care which bit is which. AES does care which bit is which, but
doesn't use the 128-bit get/set or 128-bit shifts */
#define _v128_get_bit(x, bit) \
( \
((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \
)
#define _v128_get_bit(x, bit) (((((x)->v32[(bit) >> 5]) >> ((bit)&31)) & 1))
#define _v128_set_bit(x, bit) \
( \
(((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \
)
#define _v128_set_bit(x, bit) \
((((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit)&31))))
#define _v128_clear_bit(x, bit) \
( \
(((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \
)
#define _v128_clear_bit(x, bit) \
((((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit)&31))))
#define _v128_set_bit_to(x, bit, value) \
( \
(value) ? _v128_set_bit(x, bit) : \
_v128_clear_bit(x, bit) \
)
#define _v128_set_bit_to(x, bit, value) \
((value) ? _v128_set_bit(x, bit) : _v128_clear_bit(x, bit))
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
#define v128_set_to_zero(z) _v128_set_to_zero(z)
#define v128_copy(z, x) _v128_copy(z, x)
#define v128_xor(z, x, y) _v128_xor(z, x, y)
#define v128_and(z, x, y) _v128_and(z, x, y)
#define v128_or(z, x, y) _v128_or(z, x, y)
#define v128_complement(x) _v128_complement(x)
#define v128_is_eq(x, y) _v128_is_eq(x, y)
#define v128_xor_eq(x, y) _v128_xor_eq(x, y)
#define v128_get_bit(x, i) _v128_get_bit(x, i)
#define v128_set_bit(x, i) _v128_set_bit(x, i)
#define v128_clear_bit(x, i) _v128_clear_bit(x, i)
#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y)
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
#define v128_set_to_zero(z) _v128_set_to_zero(z)
#define v128_copy(z, x) _v128_copy(z, x)
#define v128_xor(z, x, y) _v128_xor(z, x, y)
#define v128_and(z, x, y) _v128_and(z, x, y)
#define v128_or(z, x, y) _v128_or(z, x, y)
#define v128_complement(x) _v128_complement(x)
#define v128_is_eq(x, y) _v128_is_eq(x, y)
#define v128_xor_eq(x, y) _v128_xor_eq(x, y)
#define v128_get_bit(x, i) _v128_get_bit(x, i)
#define v128_set_bit(x, i) _v128_set_bit(x, i)
#define v128_clear_bit(x, i) _v128_clear_bit(x, i)
#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y)
#else
void
v128_set_to_zero(v128_t *x);
void v128_set_to_zero(v128_t *x);
int
v128_is_eq(const v128_t *x, const v128_t *y);
int v128_is_eq(const v128_t *x, const v128_t *y);
void
v128_copy(v128_t *x, const v128_t *y);
void v128_copy(v128_t *x, const v128_t *y);
void
v128_xor(v128_t *z, v128_t *x, v128_t *y);
void v128_xor(v128_t *z, v128_t *x, v128_t *y);
void
v128_and(v128_t *z, v128_t *x, v128_t *y);
void v128_and(v128_t *z, v128_t *x, v128_t *y);
void
v128_or(v128_t *z, v128_t *x, v128_t *y);
void v128_or(v128_t *z, v128_t *x, v128_t *y);
void
v128_complement(v128_t *x);
void v128_complement(v128_t *x);
int
v128_get_bit(const v128_t *x, int i);
int v128_get_bit(const v128_t *x, int i);
void
v128_set_bit(v128_t *x, int i) ;
void v128_set_bit(v128_t *x, int i);
void
v128_clear_bit(v128_t *x, int i);
void v128_clear_bit(v128_t *x, int i);
void
v128_set_bit_to(v128_t *x, int i, int y);
void v128_set_bit_to(v128_t *x, int i, int y);
#endif /* DATATYPES_USE_MACROS */
@ -304,113 +247,102 @@ v128_set_bit_to(v128_t *x, int i, int y);
* verifying authentication tags.
*/
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
int octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
/*
* A portable way to zero out memory as recommended by
* https://cryptocoding.net/index.php/Coding_rules#Clean_memory_of_secret_data
* This is used to zero memory when OPENSSL_cleanse() is not available.
*/
void
srtp_cleanse(void *s, size_t len);
void srtp_cleanse(void *s, size_t len);
/*
* Functions as a wrapper that delegates to either srtp_cleanse() or
* OPENSSL_cleanse() if available to zero memory.
*/
void
octet_string_set_to_zero(void *s, size_t len);
void octet_string_set_to_zero(void *s, size_t len);
#if defined(HAVE_CONFIG_H)
#if defined(HAVE_CONFIG_H)
/*
/*
* Convert big endian integers to CPU byte order.
*/
#ifdef WORDS_BIGENDIAN
/* Nothing to do. */
# define be32_to_cpu(x) (x)
# define be64_to_cpu(x) (x)
#define be32_to_cpu(x) (x)
#define be64_to_cpu(x) (x)
#elif defined(HAVE_BYTESWAP_H)
/* We have (hopefully) optimized versions in byteswap.h */
# include <byteswap.h>
# define be32_to_cpu(x) bswap_32((x))
# define be64_to_cpu(x) bswap_64((x))
#else
#include <byteswap.h>
#define be32_to_cpu(x) bswap_32((x))
#define be64_to_cpu(x) bswap_64((x))
#else /* WORDS_BIGENDIAN */
#if defined(__GNUC__) && defined(HAVE_X86)
/* Fall back. */
static inline uint32_t be32_to_cpu(uint32_t v) {
/* optimized for x86. */
__asm__("bswap %0" : "=r" (v) : "0" (v));
return v;
static inline uint32_t be32_to_cpu(uint32_t v)
{
/* optimized for x86. */
asm("bswap %0" : "=r"(v) : "0"(v));
return v;
}
# else /* HAVE_X86 */
# ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
# elif defined HAVE_WINSOCK2_H
# include <winsock2.h>
# endif
# define be32_to_cpu(x) ntohl((x))
# endif /* HAVE_X86 */
#else /* HAVE_X86 */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#elif defined HAVE_WINSOCK2_H
#include <winsock2.h>
#endif /* HAVE_NETINET_IN_H */
#define be32_to_cpu(x) ntohl((x))
#endif /* HAVE_X86 */
static inline uint64_t be64_to_cpu(uint64_t v) {
# ifdef NO_64BIT_MATH
/* use the make64 functions to do 64-bit math */
v = make64(htonl(low32(v)),htonl(high32(v)));
# else
/* use the native 64-bit math */
v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32));
# endif
return v;
static inline uint64_t be64_to_cpu(uint64_t v)
{
#ifdef NO_64BIT_MATH
/* use the make64 functions to do 64-bit math */
v = make64(htonl(low32(v)), htonl(high32(v)));
#else /* NO_64BIT_MATH */
/* use the native 64-bit math */
v = (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) |
(((uint64_t)be32_to_cpu((uint32_t)v)) << 32));
#endif /* NO_64BIT_MATH */
return v;
}
#endif
#endif /* WORDS_BIGENDIAN */
#endif /* HAVE_CONFIG_H */
/*
* functions manipulating bitvector_t
* functions manipulating bitvector_t
*
* A bitvector_t consists of an array of words and an integer
* representing the number of significant bits stored in the array.
* The bits are packed as follows: the least significant bit is that
* of word[0], while the most significant bit is the nth most
* significant bit of word[m], where length = bits_per_word * m + n.
*
*
*/
#define bits_per_word 32
#define bits_per_word 32
#define bytes_per_word 4
typedef struct {
uint32_t length;
uint32_t *word;
uint32_t length;
uint32_t *word;
} bitvector_t;
#define _bitvector_get_bit(v, bit_index) \
(((((v)->word[((bit_index) >> 5)]) >> ((bit_index)&31)) & 1))
#define _bitvector_get_bit(v, bit_index) \
( \
((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \
)
#define _bitvector_set_bit(v, bit_index) \
((((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index)&31)))))
#define _bitvector_clear_bit(v, bit_index) \
((((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index)&31)))))
#define _bitvector_set_bit(v, bit_index) \
( \
(((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \
)
#define _bitvector_get_length(v) (((v)->length))
#define _bitvector_clear_bit(v, bit_index) \
( \
(((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \
)
#define _bitvector_get_length(v) \
( \
((v)->length) \
)
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
#define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index)
#define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index)
@ -419,34 +351,25 @@ typedef struct {
#else
int
bitvector_get_bit(const bitvector_t *v, int bit_index);
int bitvector_get_bit(const bitvector_t *v, int bit_index);
void
bitvector_set_bit(bitvector_t *v, int bit_index);
void bitvector_set_bit(bitvector_t *v, int bit_index);
void
bitvector_clear_bit(bitvector_t *v, int bit_index);
void bitvector_clear_bit(bitvector_t *v, int bit_index);
unsigned long
bitvector_get_length(const bitvector_t *v);
unsigned long bitvector_get_length(const bitvector_t *v);
#endif
int
bitvector_alloc(bitvector_t *v, unsigned long length);
int bitvector_alloc(bitvector_t *v, unsigned long length);
void
bitvector_dealloc(bitvector_t *v);
void bitvector_dealloc(bitvector_t *v);
void
bitvector_set_to_zero(bitvector_t *x);
void bitvector_set_to_zero(bitvector_t *x);
void
bitvector_left_shift(bitvector_t *x, int index);
void bitvector_left_shift(bitvector_t *x, int index);
char *
bitvector_bit_string(bitvector_t *x, char* buf, int len);
char *bitvector_bit_string(bitvector_t *x, char *buf, int len);
#ifdef __cplusplus
}

View File

@ -42,7 +42,6 @@
*
*/
#ifndef ERR_H
#define ERR_H
@ -62,7 +61,6 @@ extern "C" {
* @{
*/
/**
* @}
*/
@ -82,9 +80,11 @@ typedef enum {
srtp_err_status_t srtp_err_reporting_init(void);
typedef void (srtp_err_report_handler_func_t)(srtp_err_reporting_level_t level, const char * msg);
typedef void(srtp_err_report_handler_func_t)(srtp_err_reporting_level_t level,
const char *msg);
srtp_err_status_t srtp_install_err_report_handler(srtp_err_report_handler_func_t func);
srtp_err_status_t srtp_install_err_report_handler(
srtp_err_report_handler_func_t func);
/*
* srtp_err_report reports a 'printf' formatted error
@ -96,9 +96,7 @@ srtp_err_status_t srtp_install_err_report_handler(srtp_err_report_handler_func_t
*
*/
void
srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
/*
* debug_module_t defines a debug module
@ -111,17 +109,21 @@ typedef struct {
#ifdef ENABLE_DEBUG_LOGGING
#define debug_print(mod, format, arg) \
#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) \
srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
#define debug_print2(mod, format, arg1, arg2) \
srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, \
arg1, arg2)
#else
#define debug_print(mod, format, arg) \
if (mod.on) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
#define debug_print2(mod, format, arg1, arg2) \
if (mod.on) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
#define debug_print(mod, format, arg) \
if (mod.on) \
srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
#define debug_print2(mod, format, arg1, arg2) \
if (mod.on) \
srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, \
arg1, arg2)
#endif

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -43,29 +43,27 @@
*
*/
#ifndef INTEGERS_H
#define INTEGERS_H
/* use standard integer definitions, if they're available */
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#include <stdlib.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#include <inttypes.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_INT_TYPES_H
# include <sys/int_types.h> /* this exists on Sun OS */
#include <sys/int_types.h> /* this exists on Sun OS */
#endif
#ifdef HAVE_MACHINE_TYPES_H
# include <machine/types.h>
#include <machine/types.h>
#endif
#ifdef __cplusplus
@ -74,31 +72,30 @@ extern "C" {
/* Can we do 64 bit integers? */
#if !defined(HAVE_UINT64_T)
# if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long uint64_t;
# elif SIZEOF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long uint64_t;
# else
# define NO_64BIT_MATH 1
# endif
#if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long uint64_t;
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long uint64_t;
#else
#define NO_64BIT_MATH 1
#endif
#endif
/* Reasonable defaults for 32 bit machines - you may need to
* edit these definitions for your own machine. */
#ifndef HAVE_UINT8_T
typedef unsigned char uint8_t;
typedef unsigned char uint8_t;
#endif
#ifndef HAVE_UINT16_T
typedef unsigned short int uint16_t;
typedef unsigned short int uint16_t;
#endif
#ifndef HAVE_UINT32_T
typedef unsigned int uint32_t;
typedef unsigned int uint32_t;
#endif
#ifndef HAVE_INT32_T
typedef int int32_t;
#endif
#if defined(NO_64BIT_MATH) && defined(HAVE_CONFIG_H)
typedef double uint64_t;
/* assert that sizeof(double) == 8 */
@ -107,39 +104,38 @@ extern uint32_t high32(uint64_t value);
extern uint32_t low32(uint64_t value);
#endif
/* These macros are to load and store 32-bit values from un-aligned
addresses. This is required for processors that do not allow unaligned
loads. */
#ifdef ALIGNMENT_32BIT_REQUIRED
/* Note that if it's in a variable, you can memcpy it */
#ifdef WORDS_BIGENDIAN
#define PUT_32(addr,value) \
{ \
((unsigned char *) (addr))[0] = (value >> 24); \
((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \
((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \
((unsigned char *) (addr))[3] = (value) & 0xff; \
#define PUT_32(addr, value) \
{ \
((unsigned char *)(addr))[0] = (value >> 24); \
((unsigned char *)(addr))[1] = (value >> 16) & 0xff; \
((unsigned char *)(addr))[2] = (value >> 8) & 0xff; \
((unsigned char *)(addr))[3] = (value)&0xff; \
}
#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) | \
(((unsigned char *) (addr))[1] << 16) | \
(((unsigned char *) (addr))[2] << 8) | \
(((unsigned char *) (addr))[3]))
#define GET_32(addr) \
((((unsigned char *)(addr))[0] << 24) | \
(((unsigned char *)(addr))[1] << 16) | \
(((unsigned char *)(addr))[2] << 8) | (((unsigned char *)(addr))[3]))
#else
#define PUT_32(addr,value) \
{ \
((unsigned char *) (addr))[3] = (value >> 24); \
((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \
((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \
((unsigned char *) (addr))[0] = (value) & 0xff; \
#define PUT_32(addr, value) \
{ \
((unsigned char *)(addr))[3] = (value >> 24); \
((unsigned char *)(addr))[2] = (value >> 16) & 0xff; \
((unsigned char *)(addr))[1] = (value >> 8) & 0xff; \
((unsigned char *)(addr))[0] = (value)&0xff; \
}
#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) | \
(((unsigned char *) (addr))[2] << 16) | \
(((unsigned char *) (addr))[1] << 8) | \
(((unsigned char *) (addr))[0]))
#define GET_32(addr) \
((((unsigned char *)(addr))[3] << 24) | \
(((unsigned char *)(addr))[2] << 16) | \
(((unsigned char *)(addr))[1] << 8) | (((unsigned char *)(addr))[0]))
#endif // WORDS_BIGENDIAN
#else
#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value)
#define PUT_32(addr, value) *(((uint32_t *) (addr)) = (value)
#define GET_32(addr) (*(((uint32_t *) (addr)))
#endif

View File

@ -45,7 +45,7 @@
#ifndef KEY_H
#define KEY_H
#include "rdbx.h" /* for srtp_xtd_seq_num_t */
#include "rdbx.h" /* for srtp_xtd_seq_num_t */
#include "err.h"
#ifdef __cplusplus
@ -60,9 +60,11 @@ typedef enum {
srtp_key_event_hard_limit
} srtp_key_event_t;
srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key, const srtp_xtd_seq_num_t s);
srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key,
const srtp_xtd_seq_num_t s);
srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original, srtp_key_limit_t *new_key);
srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original,
srtp_key_limit_t *new_key);
srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key);

View File

@ -44,7 +44,6 @@
*
*/
#ifndef NULL_CIPHER_H
#define NULL_CIPHER_H

View File

@ -7,28 +7,27 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -47,9 +46,9 @@
#ifndef REPLAY_DB_H
#define REPLAY_DB_H
#include "integers.h" /* for uint32_t */
#include "datatypes.h" /* for v128_t */
#include "err.h" /* for srtp_err_status_t */
#include "integers.h" /* for uint32_t */
#include "datatypes.h" /* for v128_t */
#include "err.h" /* for srtp_err_status_t */
#ifdef __cplusplus
extern "C" {
@ -76,7 +75,6 @@ typedef struct {
*/
srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb);
/*
* srtp_rdb_check
*
@ -103,7 +101,6 @@ srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t rdb_index);
* srtp_rdb_t upon which srtp_rdb_add_index is used!
*/
/*
* srtp_rdb_increment(db) increments the sequence number in db, if it is
* not too high
@ -121,7 +118,6 @@ srtp_err_status_t srtp_rdb_increment(srtp_rdb_t *rdb);
*/
uint32_t srtp_rdb_get_value(const srtp_rdb_t *rdb);
#ifdef __cplusplus
}
#endif

View File

@ -9,26 +9,26 @@
*/
/*
*
*
* 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
@ -58,10 +58,10 @@ extern "C" {
#ifndef ROC_TEST
typedef uint16_t srtp_sequence_number_t; /* 16 bit sequence number */
typedef uint32_t srtp_rollover_counter_t; /* 32 bit rollover counter */
typedef uint16_t srtp_sequence_number_t; /* 16 bit sequence number */
typedef uint32_t srtp_rollover_counter_t; /* 32 bit rollover counter */
#else /* use small seq_num and roc datatypes for testing purposes */
#else /* use small seq_num and roc datatypes for testing purposes */
typedef unsigned char srtp_sequence_number_t; /* 8 bit sequence number */
typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */
@ -69,7 +69,7 @@ typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */
#endif
#define seq_num_median (1 << (8 * sizeof(srtp_sequence_number_t) - 1))
#define seq_num_max (1 << (8 * sizeof(srtp_sequence_number_t)))
#define seq_num_max (1 << (8 * sizeof(srtp_sequence_number_t)))
/*
* An rtp_xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'
@ -77,7 +77,6 @@ typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */
*/
typedef uint64_t srtp_xtd_seq_num_t;
/*
* An srtp_rdbx_t is a replay database with extended range; it uses an
* xtd_seq_num_t and a bitmask of recently received indices.
@ -87,7 +86,6 @@ typedef struct {
bitvector_t bitmask;
} srtp_rdbx_t;
/*
* srtp_rdbx_init(rdbx_ptr, ws)
*
@ -96,7 +94,6 @@ typedef struct {
*/
srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws);
/*
* srtp_rdbx_dealloc(rdbx_ptr)
*
@ -104,7 +101,6 @@ srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws);
*/
srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx);
/*
* srtp_rdbx_estimate_index(rdbx, guess, s)
*
@ -113,7 +109,9 @@ srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx);
* index to which s corresponds, and returns the difference between
* *guess and the locally stored synch info
*/
int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s);
int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx,
srtp_xtd_seq_num_t *guess,
srtp_sequence_number_t s);
/*
* srtp_rdbx_check(rdbx, delta);
@ -136,7 +134,6 @@ srtp_err_status_t srtp_rdbx_check(const srtp_rdbx_t *rdbx, int difference);
*/
srtp_err_status_t srtp_rdbx_add_index(srtp_rdbx_t *rdbx, int delta);
/*
* srtp_rdbx_set_roc(rdbx, roc) initalizes the srtp_rdbx_t at the location rdbx
* to have the rollover counter value roc. If that value is less than
@ -147,7 +144,8 @@ srtp_err_status_t srtp_rdbx_add_index(srtp_rdbx_t *rdbx, int delta);
srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc);
/*
* srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter for
* srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter
* for
* the srtp_rdbx_t pointed to by rdbx
*
*/
@ -166,14 +164,12 @@ srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx);
*/
unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx);
/* index_init(&pi) initializes a packet index pi (sets it to zero) */
void srtp_index_init(srtp_xtd_seq_num_t *pi);
/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */
void srtp_index_advance(srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s);
/*
* srtp_index_guess(local, guess, s)
*
@ -183,7 +179,9 @@ void srtp_index_advance(srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s);
* guess of the packet index to which s corresponds, and returns the
* difference between *guess and *local
*/
int32_t srtp_index_guess(const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s);
int32_t srtp_index_guess(const srtp_xtd_seq_num_t *local,
srtp_xtd_seq_num_t *guess,
srtp_sequence_number_t s);
/*
* srtp_rdbx_get_roc(rdbx)
@ -200,9 +198,9 @@ uint32_t srtp_rdbx_get_roc(const srtp_rdbx_t *rdbx);
* rollover counter value, then the function returns
* srtp_err_status_replay_old, otherwise, srtp_err_status_ok is returned.
*/
srtp_err_status_t srtp_rdbx_set_roc_seq (srtp_rdbx_t *rdbx,
uint32_t roc,
uint16_t seq);
srtp_err_status_t srtp_rdbx_set_roc_seq(srtp_rdbx_t *rdbx,
uint32_t roc,
uint16_t seq);
#ifdef __cplusplus
}

View File

@ -48,7 +48,7 @@
#define SHA1_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "err.h"
@ -81,49 +81,53 @@ extern "C" {
/* OpenSSL 1.1.0 made EVP_MD_CTX an opaque structure, which must be allocated
using EVP_MD_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
typedef EVP_MD_CTX srtp_sha1_ctx_t;
static inline void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
static inline void srtp_sha1_init(srtp_sha1_ctx_t *ctx)
{
EVP_MD_CTX_init(ctx);
EVP_DigestInit(ctx, EVP_sha1());
}
static inline void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg)
static inline void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
const uint8_t *M,
int octets_in_msg)
{
EVP_DigestUpdate(ctx, M, octets_in_msg);
}
static inline void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
static inline void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
{
unsigned int len = 0;
EVP_DigestFinal(ctx, (unsigned char*)output, &len);
EVP_DigestFinal(ctx, (unsigned char *)output, &len);
EVP_MD_CTX_cleanup(ctx);
}
#else
typedef EVP_MD_CTX* srtp_sha1_ctx_t;
typedef EVP_MD_CTX *srtp_sha1_ctx_t;
static inline void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
static inline void srtp_sha1_init(srtp_sha1_ctx_t *ctx)
{
*ctx = EVP_MD_CTX_new();
EVP_DigestInit(*ctx, EVP_sha1());
}
static inline void srtp_sha1_update (srtp_sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg)
static inline void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
const uint8_t *M,
int octets_in_msg)
{
EVP_DigestUpdate(*ctx, M, octets_in_msg);
}
static inline void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
static inline void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
{
unsigned int len = 0;
EVP_DigestFinal(*ctx, (unsigned char*)output, &len);
EVP_DigestFinal(*ctx, (unsigned char *)output, &len);
EVP_MD_CTX_free(*ctx);
}
#endif
@ -137,7 +141,6 @@ typedef struct {
uint32_t num_bits_in_msg; /* total number of bits in message */
} srtp_sha1_ctx_t;
/*
* srtp_sha1_init(&ctx) initializes the SHA1 context ctx
*
@ -150,9 +153,11 @@ typedef struct {
*/
void srtp_sha1_init(srtp_sha1_ctx_t *ctx);
void srtp_sha1_update(srtp_sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
const uint8_t *M,
int octets_in_msg);
void srtp_sha1_final(srtp_sha1_ctx_t * ctx, uint32_t output[5]);
void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t output[5]);
/*
* The srtp_sha1_core function is INTERNAL to SHA-1, but it is declared

View File

@ -1,6 +1,6 @@
/*
* stats.h
*
*
* interface to statistical test functions
*
* David A. McGrew
@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -43,12 +43,11 @@
*
*/
#ifndef STAT_H
#define STAT_H
#include "datatypes.h" /* for uint8_t */
#include "err.h" /* for srtp_err_status_t */
#include "datatypes.h" /* for uint8_t */
#include "err.h" /* for srtp_err_status_t */
#ifdef __cplusplus
extern "C" {

View File

@ -1,32 +1,32 @@
/*
* alloc.c
*
* memory allocation and deallocation
* memory allocation and deallocation
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -43,7 +43,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "alloc.h"
@ -51,9 +51,9 @@
/* the debug module for memory allocation */
srtp_debug_module_t mod_alloc = {
0, /* debugging is off by default */
"alloc" /* printable name for module */
srtp_debug_module_t srtp_mod_alloc = {
0, /* debugging is off by default */
"alloc" /* printable name for module */
};
/*
@ -67,29 +67,35 @@ srtp_debug_module_t mod_alloc = {
#if defined(HAVE_STDLIB_H)
void * srtp_crypto_alloc(size_t size) {
void *ptr;
void *srtp_crypto_alloc(size_t size)
{
void *ptr;
ptr = malloc(size);
if (ptr) {
debug_print(mod_alloc, "(location: %p) allocated", ptr);
} else {
debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
}
if (!size) {
return NULL;
}
return ptr;
ptr = calloc(1, 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",
size);
}
return ptr;
}
void srtp_crypto_free(void *ptr) {
void srtp_crypto_free(void *ptr)
{
debug_print(srtp_mod_alloc, "(location: %p) freed", ptr);
debug_print(mod_alloc, "(location: %p) freed", ptr);
free(ptr);
free(ptr);
}
#else /* we need to define our own memory allocation routines */
#else /* we need to define our own memory allocation routines */
#error no memory allocation defined yet
#error no memory allocation defined yet
#endif

View File

@ -42,60 +42,22 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "alloc.h"
#include "crypto_kernel.h"
#include "cipher_types.h"
/* the debug module for the crypto_kernel */
srtp_debug_module_t srtp_mod_crypto_kernel = {
0, /* debugging is off by default */
"crypto kernel" /* printable name for module */
0, /* debugging is off by default */
"crypto kernel" /* printable name for module */
};
/*
* other generic debug modules that can be included in the kernel
*/
extern srtp_debug_module_t srtp_mod_auth;
extern srtp_debug_module_t srtp_mod_cipher;
extern srtp_debug_module_t mod_stat;
extern srtp_debug_module_t mod_alloc;
/*
* cipher types that can be included in the kernel
*/
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
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;
#endif
/* debug modules for cipher types */
extern srtp_debug_module_t srtp_mod_aes_icm;
#ifdef OPENSSL
extern srtp_debug_module_t srtp_mod_aes_gcm;
#endif
/*
* auth func types that can be included in the kernel
*/
extern srtp_auth_type_t srtp_null_auth;
extern srtp_auth_type_t srtp_hmac;
/* debug modules for auth types */
extern srtp_debug_module_t srtp_mod_hmac;
/* crypto_kernel is a global variable, the only one of its datatype */
srtp_crypto_kernel_t crypto_kernel = {
@ -107,13 +69,12 @@ srtp_crypto_kernel_t crypto_kernel = {
#define MAX_RNG_TRIALS 25
srtp_err_status_t srtp_crypto_kernel_init ()
srtp_err_status_t srtp_crypto_kernel_init()
{
srtp_err_status_t status;
/* check the security state */
if (crypto_kernel.state == srtp_crypto_kernel_state_secure) {
/*
* we're already in the secure state, but we've been asked to
* re-initialize, so we just re-run the self-tests and then return
@ -140,25 +101,28 @@ srtp_err_status_t srtp_crypto_kernel_init ()
if (status) {
return status;
}
status = srtp_crypto_kernel_load_debug_module(&mod_stat);
status = srtp_crypto_kernel_load_debug_module(&srtp_mod_stat);
if (status) {
return status;
}
status = srtp_crypto_kernel_load_debug_module(&mod_alloc);
status = srtp_crypto_kernel_load_debug_module(&srtp_mod_alloc);
if (status) {
return status;
}
/* load cipher types */
status = srtp_crypto_kernel_load_cipher_type(&srtp_null_cipher, SRTP_NULL_CIPHER);
status = srtp_crypto_kernel_load_cipher_type(&srtp_null_cipher,
SRTP_NULL_CIPHER);
if (status) {
return status;
}
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_128, SRTP_AES_ICM_128);
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_128,
SRTP_AES_ICM_128);
if (status) {
return status;
}
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_256, SRTP_AES_ICM_256);
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_256,
SRTP_AES_ICM_256);
if (status) {
return status;
}
@ -167,15 +131,18 @@ srtp_err_status_t srtp_crypto_kernel_init ()
return status;
}
#ifdef OPENSSL
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_192, SRTP_AES_ICM_192);
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, SRTP_AES_GCM_128);
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128_openssl,
SRTP_AES_GCM_128);
if (status) {
return status;
}
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256_openssl, SRTP_AES_GCM_256);
status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256_openssl,
SRTP_AES_GCM_256);
if (status) {
return status;
}
@ -205,19 +172,21 @@ srtp_err_status_t srtp_crypto_kernel_init ()
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_status ()
srtp_err_status_t srtp_crypto_kernel_status()
{
srtp_err_status_t status;
srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
/* for each cipher type, describe and test */
while (ctype != NULL) {
srtp_err_report(srtp_err_level_info, "cipher: %s\n", ctype->cipher_type->description);
srtp_err_report(srtp_err_level_info, "cipher: %s\n",
ctype->cipher_type->description);
srtp_err_report(srtp_err_level_info, " self-test: ");
status = srtp_cipher_type_self_test(ctype->cipher_type);
if (status) {
srtp_err_report(srtp_err_level_error, "failed with error code %d\n", status);
srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
status);
exit(status);
}
srtp_err_report(srtp_err_level_info, "passed\n");
@ -226,11 +195,13 @@ srtp_err_status_t srtp_crypto_kernel_status ()
/* for each auth type, describe and test */
while (atype != NULL) {
srtp_err_report(srtp_err_level_info, "auth func: %s\n", atype->auth_type->description);
srtp_err_report(srtp_err_level_info, "auth func: %s\n",
atype->auth_type->description);
srtp_err_report(srtp_err_level_info, " self-test: ");
status = srtp_auth_type_self_test(atype->auth_type);
if (status) {
srtp_err_report(srtp_err_level_error, "failed with error code %d\n", status);
srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
status);
exit(status);
}
srtp_err_report(srtp_err_level_info, "passed\n");
@ -242,7 +213,7 @@ srtp_err_status_t srtp_crypto_kernel_status ()
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_list_debug_modules ()
srtp_err_status_t srtp_crypto_kernel_list_debug_modules()
{
srtp_kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
@ -252,7 +223,7 @@ srtp_err_status_t srtp_crypto_kernel_list_debug_modules ()
srtp_err_report(srtp_err_level_info, " %s ", dm->mod->name);
if (dm->mod->on) {
srtp_err_report(srtp_err_level_info, "(on)\n");
} else{
} else {
srtp_err_report(srtp_err_level_info, "(off)\n");
}
dm = dm->next;
@ -261,7 +232,7 @@ srtp_err_status_t srtp_crypto_kernel_list_debug_modules ()
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_shutdown ()
srtp_err_status_t srtp_crypto_kernel_shutdown()
{
/*
* free dynamic memory used in crypto_kernel at present
@ -271,8 +242,7 @@ srtp_err_status_t srtp_crypto_kernel_shutdown ()
while (crypto_kernel.cipher_type_list != NULL) {
srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
crypto_kernel.cipher_type_list = ctype->next;
debug_print(srtp_mod_crypto_kernel,
"freeing memory for cipher %s",
debug_print(srtp_mod_crypto_kernel, "freeing memory for cipher %s",
ctype->cipher_type->description);
srtp_crypto_free(ctype);
}
@ -292,8 +262,7 @@ srtp_err_status_t srtp_crypto_kernel_shutdown ()
srtp_kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
crypto_kernel.debug_module_list = kdm->next;
debug_print(srtp_mod_crypto_kernel,
"freeing memory for debug module %s",
kdm->mod->name);
"freeing memory for debug module %s", kdm->mod->name);
srtp_crypto_free(kdm);
}
@ -303,7 +272,10 @@ srtp_err_status_t srtp_crypto_kernel_shutdown ()
return srtp_err_status_ok;
}
static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type (const srtp_cipher_type_t *new_ct, srtp_cipher_type_id_t id, int replace)
static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type(
const srtp_cipher_type_t *new_ct,
srtp_cipher_type_id_t id,
int replace)
{
srtp_kernel_cipher_type_t *ctype, *new_ctype;
srtp_err_status_t status;
@ -330,13 +302,14 @@ static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type (const sr
if (!replace) {
return srtp_err_status_bad_param;
}
status = srtp_cipher_type_test(new_ct, ctype->cipher_type->test_data);
status =
srtp_cipher_type_test(new_ct, ctype->cipher_type->test_data);
if (status) {
return status;
}
new_ctype = ctype;
break;
}else if (new_ct == ctype->cipher_type) {
} else if (new_ct == ctype->cipher_type) {
return srtp_err_status_bad_param;
}
ctype = ctype->next;
@ -345,7 +318,8 @@ static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type (const sr
/* if not found, put new_ct at the head of the list */
if (ctype == NULL) {
/* allocate memory */
new_ctype = (srtp_kernel_cipher_type_t*)srtp_crypto_alloc(sizeof(srtp_kernel_cipher_type_t));
new_ctype = (srtp_kernel_cipher_type_t *)srtp_crypto_alloc(
sizeof(srtp_kernel_cipher_type_t));
if (new_ctype == NULL) {
return srtp_err_status_alloc_fail;
}
@ -362,17 +336,23 @@ static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type (const sr
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_load_cipher_type (const srtp_cipher_type_t *new_ct, srtp_cipher_type_id_t id)
srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
const srtp_cipher_type_t *new_ct,
srtp_cipher_type_id_t id)
{
return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 0);
}
srtp_err_status_t srtp_replace_cipher_type (const srtp_cipher_type_t *new_ct, srtp_cipher_type_id_t id)
srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *new_ct,
srtp_cipher_type_id_t id)
{
return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 1);
}
srtp_err_status_t srtp_crypto_kernel_do_load_auth_type (const srtp_auth_type_t *new_at, srtp_auth_type_id_t id, int replace)
srtp_err_status_t srtp_crypto_kernel_do_load_auth_type(
const srtp_auth_type_t *new_at,
srtp_auth_type_id_t id,
int replace)
{
srtp_kernel_auth_type_t *atype, *new_atype;
srtp_err_status_t status;
@ -405,7 +385,7 @@ srtp_err_status_t srtp_crypto_kernel_do_load_auth_type (const srtp_auth_type_t *
}
new_atype = atype;
break;
}else if (new_at == atype->auth_type) {
} else if (new_at == atype->auth_type) {
return srtp_err_status_bad_param;
}
atype = atype->next;
@ -414,7 +394,8 @@ srtp_err_status_t srtp_crypto_kernel_do_load_auth_type (const srtp_auth_type_t *
/* if not found, put new_at at the head of the list */
if (atype == NULL) {
/* allocate memory */
new_atype = (srtp_kernel_auth_type_t*)srtp_crypto_alloc(sizeof(srtp_kernel_auth_type_t));
new_atype = (srtp_kernel_auth_type_t *)srtp_crypto_alloc(
sizeof(srtp_kernel_auth_type_t));
if (new_atype == NULL) {
return srtp_err_status_alloc_fail;
}
@ -429,21 +410,23 @@ srtp_err_status_t srtp_crypto_kernel_do_load_auth_type (const srtp_auth_type_t *
new_atype->id = id;
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_load_auth_type (const srtp_auth_type_t *new_at, srtp_auth_type_id_t id)
srtp_err_status_t srtp_crypto_kernel_load_auth_type(
const srtp_auth_type_t *new_at,
srtp_auth_type_id_t id)
{
return srtp_crypto_kernel_do_load_auth_type(new_at, id, 0);
}
srtp_err_status_t srtp_replace_auth_type (const srtp_auth_type_t *new_at, srtp_auth_type_id_t id)
srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *new_at,
srtp_auth_type_id_t id)
{
return srtp_crypto_kernel_do_load_auth_type(new_at, id, 1);
}
const srtp_cipher_type_t * srtp_crypto_kernel_get_cipher_type (srtp_cipher_type_id_t id)
const srtp_cipher_type_t *srtp_crypto_kernel_get_cipher_type(
srtp_cipher_type_id_t id)
{
srtp_kernel_cipher_type_t *ctype;
@ -460,8 +443,10 @@ const srtp_cipher_type_t * srtp_crypto_kernel_get_cipher_type (srtp_cipher_type_
return NULL;
}
srtp_err_status_t srtp_crypto_kernel_alloc_cipher (srtp_cipher_type_id_t id, srtp_cipher_pointer_t *cp, int key_len, int tag_len)
srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id,
srtp_cipher_pointer_t *cp,
int key_len,
int tag_len)
{
const srtp_cipher_type_t *ct;
@ -481,9 +466,7 @@ srtp_err_status_t srtp_crypto_kernel_alloc_cipher (srtp_cipher_type_id_t id, srt
return ((ct)->alloc(cp, key_len, tag_len));
}
const srtp_auth_type_t * srtp_crypto_kernel_get_auth_type (srtp_auth_type_id_t id)
const srtp_auth_type_t *srtp_crypto_kernel_get_auth_type(srtp_auth_type_id_t id)
{
srtp_kernel_auth_type_t *atype;
@ -500,7 +483,10 @@ const srtp_auth_type_t * srtp_crypto_kernel_get_auth_type (srtp_auth_type_id_t i
return NULL;
}
srtp_err_status_t srtp_crypto_kernel_alloc_auth (srtp_auth_type_id_t id, srtp_auth_pointer_t *ap, int key_len, int tag_len)
srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id,
srtp_auth_pointer_t *ap,
int key_len,
int tag_len)
{
const srtp_auth_type_t *at;
@ -520,12 +506,13 @@ srtp_err_status_t srtp_crypto_kernel_alloc_auth (srtp_auth_type_id_t id, srtp_au
return ((at)->alloc(ap, key_len, tag_len));
}
srtp_err_status_t srtp_crypto_kernel_load_debug_module (srtp_debug_module_t *new_dm)
srtp_err_status_t srtp_crypto_kernel_load_debug_module(
srtp_debug_module_t *new_dm)
{
srtp_kernel_debug_module_t *kdm, *new;
/* defensive coding */
if (new_dm == NULL) {
if (new_dm == NULL || new_dm->name == NULL) {
return srtp_err_status_bad_param;
}
@ -540,7 +527,8 @@ srtp_err_status_t srtp_crypto_kernel_load_debug_module (srtp_debug_module_t *new
/* put new_dm at the head of the list */
/* allocate memory */
new = (srtp_kernel_debug_module_t*)srtp_crypto_alloc(sizeof(srtp_kernel_debug_module_t));
new = (srtp_kernel_debug_module_t *)srtp_crypto_alloc(
sizeof(srtp_kernel_debug_module_t));
if (new == NULL) {
return srtp_err_status_alloc_fail;
}
@ -555,7 +543,7 @@ srtp_err_status_t srtp_crypto_kernel_load_debug_module (srtp_debug_module_t *new
return srtp_err_status_ok;
}
srtp_err_status_t srtp_crypto_kernel_set_debug_module (const char *name, int on)
srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *name, int on)
{
srtp_kernel_debug_module_t *kdm;

View File

@ -43,7 +43,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "err.h"
@ -54,7 +54,7 @@
static FILE *srtp_err_file = NULL;
srtp_err_status_t srtp_err_reporting_init ()
srtp_err_status_t srtp_err_reporting_init()
{
#ifdef ERR_REPORTING_STDOUT
srtp_err_file = stdout;
@ -69,15 +69,16 @@ srtp_err_status_t srtp_err_reporting_init ()
return srtp_err_status_ok;
}
static srtp_err_report_handler_func_t * srtp_err_report_handler = NULL;
static srtp_err_report_handler_func_t *srtp_err_report_handler = NULL;
srtp_err_status_t srtp_install_err_report_handler(srtp_err_report_handler_func_t func)
srtp_err_status_t srtp_install_err_report_handler(
srtp_err_report_handler_func_t func)
{
srtp_err_report_handler = func;
return srtp_err_status_ok;
}
void srtp_err_report (srtp_err_reporting_level_t level, const char *format, ...)
void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...)
{
va_list args;
if (srtp_err_file != NULL) {
@ -91,12 +92,13 @@ void srtp_err_report (srtp_err_reporting_level_t level, const char *format, ...)
if (vsnprintf(msg, sizeof(msg), format, args) > 0) {
/* strip trailing \n, callback should not have one */
size_t l = strlen(msg);
if (l && msg[l-1] == '\n') {
msg[l-1] = '\0';
if (l && msg[l - 1] == '\n') {
msg[l - 1] = '\0';
}
srtp_err_report_handler(level, msg);
/*
* NOTE, need to be carefull, there is a potential that octet_string_set_to_zero() could
* NOTE, need to be carefull, there is a potential that
* octet_string_set_to_zero() could
* call srtp_err_report() in the future, leading to recursion
*/
octet_string_set_to_zero(msg, sizeof(msg));

View File

@ -43,14 +43,15 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "key.h"
#define soft_limit 0x10000
srtp_err_status_t srtp_key_limit_set (srtp_key_limit_t key, const srtp_xtd_seq_num_t s)
srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key,
const srtp_xtd_seq_num_t s)
{
#ifdef NO_64BIT_MATH
if (high32(s) == 0 && low32(s) < soft_limit) {
@ -66,7 +67,8 @@ srtp_err_status_t srtp_key_limit_set (srtp_key_limit_t key, const srtp_xtd_seq_n
return srtp_err_status_ok;
}
srtp_err_status_t srtp_key_limit_clone (srtp_key_limit_t original, srtp_key_limit_t *new_key)
srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original,
srtp_key_limit_t *new_key)
{
if (original == NULL) {
return srtp_err_status_bad_param;
@ -75,7 +77,7 @@ srtp_err_status_t srtp_key_limit_clone (srtp_key_limit_t original, srtp_key_limi
return srtp_err_status_ok;
}
srtp_err_status_t srtp_key_limit_check (const srtp_key_limit_t key)
srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key)
{
if (key->state == srtp_key_state_expired) {
return srtp_err_status_key_expired;
@ -83,13 +85,14 @@ srtp_err_status_t srtp_key_limit_check (const srtp_key_limit_t key)
return srtp_err_status_ok;
}
srtp_key_event_t srtp_key_limit_update (srtp_key_limit_t key)
srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key)
{
#ifdef NO_64BIT_MATH
if (low32(key->num_left) == 0) {
// carry
key->num_left = make64(high32(key->num_left) - 1, low32(key->num_left) - 1);
}else {
key->num_left =
make64(high32(key->num_left) - 1, low32(key->num_left) - 1);
} else {
// no carry
key->num_left = make64(high32(key->num_left), low32(key->num_left) - 1);
}
@ -111,10 +114,9 @@ srtp_key_event_t srtp_key_limit_update (srtp_key_limit_t key)
#else
if (key->num_left < 1)
#endif
{ /* we just hit the hard limit */
{ /* we just hit the hard limit */
key->state = srtp_key_state_expired;
return srtp_key_event_hard_limit;
}
return srtp_key_event_soft_limit;
}

View File

@ -8,26 +8,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -44,7 +44,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#ifdef OPENSSL
@ -53,48 +53,24 @@
#include "datatypes.h"
int
octet_weight[256] = {
0, 1, 1, 2, 1, 2, 2, 3,
1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7,
5, 6, 6, 7, 6, 7, 7, 8
static const int8_t octet_weight[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
int
octet_get_weight(uint8_t octet) {
extern int octet_weight[256];
return octet_weight[octet];
}
int octet_get_weight(uint8_t octet)
{
return (int)octet_weight[octet];
}
/*
* bit_string is a buffer that is used to hold output strings, e.g.
@ -105,414 +81,410 @@ octet_get_weight(uint8_t octet) {
char bit_string[MAX_PRINT_STRING_LEN];
uint8_t
srtp_nibble_to_hex_char(uint8_t nibble) {
char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
return buf[nibble & 0xF];
uint8_t srtp_nibble_to_hex_char(uint8_t nibble)
{
char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
return buf[nibble & 0xF];
}
char * srtp_octet_string_hex_string(const void *s, int length) {
const uint8_t *str = (const uint8_t *)s;
int i;
/* double length, since one octet takes two hex characters */
length *= 2;
char *srtp_octet_string_hex_string(const void *s, int length)
{
const uint8_t *str = (const uint8_t *)s;
int i;
/* truncate string if it would be too long */
if (length > MAX_PRINT_STRING_LEN)
length = MAX_PRINT_STRING_LEN-2;
for (i=0; i < length; i+=2) {
bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
bit_string[i+1] = srtp_nibble_to_hex_char(*str++ & 0xF);
}
bit_string[i] = 0; /* null terminate string */
return bit_string;
}
/* double length, since one octet takes two hex characters */
length *= 2;
char *
v128_hex_string(v128_t *x) {
int i, j;
/* truncate string if it would be too long */
if (length > MAX_PRINT_STRING_LEN)
length = MAX_PRINT_STRING_LEN - 2;
for (i=j=0; i < 16; i++) {
bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *
v128_bit_string(v128_t *x) {
int j, i;
uint32_t mask;
for (j=i=0; j < 4; j++) {
for (mask=0x80000000; mask > 0; mask >>= 1) {
if (x->v32[j] & mask)
bit_string[i] = '1';
else
bit_string[i] = '0';
++i;
for (i = 0; i < length; i += 2) {
bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
bit_string[i + 1] = srtp_nibble_to_hex_char(*str++ & 0xF);
}
}
bit_string[128] = 0; /* null terminate string */
return bit_string;
bit_string[i] = 0; /* null terminate string */
return bit_string;
}
void
v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
#ifdef ALIGNMENT_32BIT_REQUIRED
if ((((uint32_t) &s[0]) & 0x3) != 0)
#endif
{
x->v8[0] = s[0];
x->v8[1] = s[1];
x->v8[2] = s[2];
x->v8[3] = s[3];
x->v8[4] = s[4];
x->v8[5] = s[5];
x->v8[6] = s[6];
x->v8[7] = s[7];
x->v8[8] = s[8];
x->v8[9] = s[9];
x->v8[10] = s[10];
x->v8[11] = s[11];
x->v8[12] = s[12];
x->v8[13] = s[13];
x->v8[14] = s[14];
x->v8[15] = s[15];
}
#ifdef ALIGNMENT_32BIT_REQUIRED
else
{
v128_t *v = (v128_t *) &s[0];
char *v128_hex_string(v128_t *x)
{
int i, j;
v128_copy(x,v);
}
for (i = j = 0; i < 16; i++) {
bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *v128_bit_string(v128_t *x)
{
int j, i;
uint32_t mask;
for (j = i = 0; j < 4; j++) {
for (mask = 0x80000000; mask > 0; mask >>= 1) {
if (x->v32[j] & mask)
bit_string[i] = '1';
else
bit_string[i] = '0';
++i;
}
}
bit_string[128] = 0; /* null terminate string */
return bit_string;
}
void v128_copy_octet_string(v128_t *x, const uint8_t s[16])
{
#ifdef ALIGNMENT_32BIT_REQUIRED
if ((((uint32_t)&s[0]) & 0x3) != 0)
#endif
{
x->v8[0] = s[0];
x->v8[1] = s[1];
x->v8[2] = s[2];
x->v8[3] = s[3];
x->v8[4] = s[4];
x->v8[5] = s[5];
x->v8[6] = s[6];
x->v8[7] = s[7];
x->v8[8] = s[8];
x->v8[9] = s[9];
x->v8[10] = s[10];
x->v8[11] = s[11];
x->v8[12] = s[12];
x->v8[13] = s[13];
x->v8[14] = s[14];
x->v8[15] = s[15];
}
#ifdef ALIGNMENT_32BIT_REQUIRED
else {
v128_t *v = (v128_t *)&s[0];
v128_copy(x, v);
}
#endif
}
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
void
v128_set_to_zero(v128_t *x) {
_v128_set_to_zero(x);
void v128_set_to_zero(v128_t *x)
{
_v128_set_to_zero(x);
}
void
v128_copy(v128_t *x, const v128_t *y) {
_v128_copy(x, y);
void v128_copy(v128_t *x, const v128_t *y)
{
_v128_copy(x, y);
}
void
v128_xor(v128_t *z, v128_t *x, v128_t *y) {
_v128_xor(z, x, y);
}
void
v128_and(v128_t *z, v128_t *x, v128_t *y) {
_v128_and(z, x, y);
void v128_xor(v128_t *z, v128_t *x, v128_t *y)
{
_v128_xor(z, x, y);
}
void
v128_or(v128_t *z, v128_t *x, v128_t *y) {
_v128_or(z, x, y);
void v128_and(v128_t *z, v128_t *x, v128_t *y)
{
_v128_and(z, x, y);
}
void
v128_complement(v128_t *x) {
_v128_complement(x);
void v128_or(v128_t *z, v128_t *x, v128_t *y)
{
_v128_or(z, x, y);
}
int
v128_is_eq(const v128_t *x, const v128_t *y) {
return _v128_is_eq(x, y);
void v128_complement(v128_t *x)
{
_v128_complement(x);
}
int
v128_xor_eq(v128_t *x, const v128_t *y) {
return _v128_xor_eq(x, y);
int v128_is_eq(const v128_t *x, const v128_t *y)
{
return _v128_is_eq(x, y);
}
int
v128_get_bit(const v128_t *x, int i) {
return _v128_get_bit(x, i);
int v128_xor_eq(v128_t *x, const v128_t *y)
{
return _v128_xor_eq(x, y);
}
void
v128_set_bit(v128_t *x, int i) {
_v128_set_bit(x, i);
}
void
v128_clear_bit(v128_t *x, int i){
_v128_clear_bit(x, i);
}
void
v128_set_bit_to(v128_t *x, int i, int y){
_v128_set_bit_to(x, i, y);
int v128_get_bit(const v128_t *x, int i)
{
return _v128_get_bit(x, i);
}
void v128_set_bit(v128_t *x, int i)
{
_v128_set_bit(x, i);
}
void v128_clear_bit(v128_t *x, int i)
{
_v128_clear_bit(x, i);
}
void v128_set_bit_to(v128_t *x, int i, int y)
{
_v128_set_bit_to(x, i, y);
}
#endif /* DATATYPES_USE_MACROS */
void
v128_right_shift(v128_t *x, int shift) {
const int base_index = shift >> 5;
const int bit_index = shift & 31;
int i, from;
uint32_t b;
if (shift > 127) {
v128_set_to_zero(x);
return;
}
void v128_right_shift(v128_t *x, int shift)
{
const int base_index = shift >> 5;
const int bit_index = shift & 31;
int i, from;
uint32_t b;
if (bit_index == 0) {
/* copy each word from left size to right side */
x->v32[4-1] = x->v32[4-1-base_index];
for (i=4-1; i > base_index; i--)
x->v32[i-1] = x->v32[i-1-base_index];
} else {
/* set each word to the "or" of the two bit-shifted words */
for (i = 4; i > base_index; i--) {
from = i-1 - base_index;
b = x->v32[from] << bit_index;
if (from > 0)
b |= x->v32[from-1] >> (32-bit_index);
x->v32[i-1] = b;
if (shift > 127) {
v128_set_to_zero(x);
return;
}
}
/* now wrap up the final portion */
for (i=0; i < base_index; i++)
x->v32[i] = 0;
if (bit_index == 0) {
/* copy each word from left size to right side */
x->v32[4 - 1] = x->v32[4 - 1 - base_index];
for (i = 4 - 1; i > base_index; i--)
x->v32[i - 1] = x->v32[i - 1 - base_index];
} else {
/* set each word to the "or" of the two bit-shifted words */
for (i = 4; i > base_index; i--) {
from = i - 1 - base_index;
b = x->v32[from] << bit_index;
if (from > 0)
b |= x->v32[from - 1] >> (32 - bit_index);
x->v32[i - 1] = b;
}
}
/* now wrap up the final portion */
for (i = 0; i < base_index; i++)
x->v32[i] = 0;
}
void
v128_left_shift(v128_t *x, int shift) {
int i;
const int base_index = shift >> 5;
const int bit_index = shift & 31;
void v128_left_shift(v128_t *x, int shift)
{
int i;
const int base_index = shift >> 5;
const int bit_index = shift & 31;
if (shift > 127) {
v128_set_to_zero(x);
return;
}
if (bit_index == 0) {
for (i=0; i < 4 - base_index; i++)
x->v32[i] = x->v32[i+base_index];
} else {
for (i=0; i < 4 - base_index - 1; i++)
x->v32[i] = (x->v32[i+base_index] >> bit_index) ^
(x->v32[i+base_index+1] << (32 - bit_index));
x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index;
}
if (shift > 127) {
v128_set_to_zero(x);
return;
}
/* now wrap up the final portion */
for (i = 4 - base_index; i < 4; i++)
x->v32[i] = 0;
if (bit_index == 0) {
for (i = 0; i < 4 - base_index; i++)
x->v32[i] = x->v32[i + base_index];
} else {
for (i = 0; i < 4 - base_index - 1; i++)
x->v32[i] = (x->v32[i + base_index] >> bit_index) ^
(x->v32[i + base_index + 1] << (32 - bit_index));
x->v32[4 - base_index - 1] = x->v32[4 - 1] >> bit_index;
}
/* now wrap up the final portion */
for (i = 4 - base_index; i < 4; i++)
x->v32[i] = 0;
}
/* functions manipulating bitvector_t */
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
int
bitvector_get_bit(const bitvector_t *v, int bit_index)
int bitvector_get_bit(const bitvector_t *v, int bit_index)
{
return _bitvector_get_bit(v, bit_index);
return _bitvector_get_bit(v, bit_index);
}
void
bitvector_set_bit(bitvector_t *v, int bit_index)
void bitvector_set_bit(bitvector_t *v, int bit_index)
{
_bitvector_set_bit(v, bit_index);
_bitvector_set_bit(v, bit_index);
}
void
bitvector_clear_bit(bitvector_t *v, int bit_index)
void bitvector_clear_bit(bitvector_t *v, int bit_index)
{
_bitvector_clear_bit(v, bit_index);
_bitvector_clear_bit(v, bit_index);
}
#endif /* DATATYPES_USE_MACROS */
int
bitvector_alloc(bitvector_t *v, unsigned long length) {
unsigned long l;
int bitvector_alloc(bitvector_t *v, unsigned long length)
{
unsigned long l;
/* Round length up to a multiple of bits_per_word */
length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
/* Round length up to a multiple of bits_per_word */
length =
(length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
l = length / bits_per_word * bytes_per_word;
l = length / bits_per_word * bytes_per_word;
/* allocate memory, then set parameters */
if (l == 0)
/* allocate memory, then set parameters */
if (l == 0) {
v->word = NULL;
v->length = 0;
return -1;
} else {
v->word = (uint32_t *)srtp_crypto_alloc(l);
if (v->word == NULL) {
v->length = 0;
return -1;
}
}
v->length = length;
/* initialize bitvector to zero */
bitvector_set_to_zero(v);
return 0;
}
void bitvector_dealloc(bitvector_t *v)
{
if (v->word != NULL)
srtp_crypto_free(v->word);
v->word = NULL;
else {
v->word = (uint32_t*)srtp_crypto_alloc(l);
if (v->word == NULL) {
v->word = NULL;
v->length = 0;
return -1;
}
}
v->length = length;
/* initialize bitvector to zero */
bitvector_set_to_zero(v);
return 0;
v->length = 0;
}
void
bitvector_dealloc(bitvector_t *v) {
if (v->word != NULL)
srtp_crypto_free(v->word);
v->word = NULL;
v->length = 0;
}
void
bitvector_set_to_zero(bitvector_t *x)
void bitvector_set_to_zero(bitvector_t *x)
{
/* C99 guarantees that memset(0) will set the value 0 for uint32_t */
memset(x->word, 0, x->length >> 3);
/* C99 guarantees that memset(0) will set the value 0 for uint32_t */
memset(x->word, 0, x->length >> 3);
}
char *
bitvector_bit_string(bitvector_t *x, char* buf, int len) {
int j, i;
uint32_t mask;
for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) {
for (mask=0x80000000; mask > 0; mask >>= 1) {
if (x->word[j] & mask)
buf[i] = '1';
else
buf[i] = '0';
++i;
if (i >= len-1)
break;
}
}
buf[i] = 0; /* null terminate string */
return buf;
}
void
bitvector_left_shift(bitvector_t *x, int shift) {
int i;
const int base_index = shift >> 5;
const int bit_index = shift & 31;
const int word_length = x->length >> 5;
if (shift >= (int)x->length) {
bitvector_set_to_zero(x);
return;
}
if (bit_index == 0) {
for (i=0; i < word_length - base_index; i++)
x->word[i] = x->word[i+base_index];
} else {
for (i=0; i < word_length - base_index - 1; i++)
x->word[i] = (x->word[i+base_index] >> bit_index) ^
(x->word[i+base_index+1] << (32 - bit_index));
x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index;
}
/* now wrap up the final portion */
for (i = word_length - base_index; i < word_length; i++)
x->word[i] = 0;
}
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
uint8_t *end = b + len;
uint8_t accumulator = 0;
/*
* We use this somewhat obscure implementation to try to ensure the running
* time only depends on len, even accounting for compiler optimizations.
* The accumulator ends up zero iff the strings are equal.
*/
while (b < end)
accumulator |= (*a++ ^ *b++);
/* Return 1 if *not* equal. */
return accumulator != 0;
}
void
srtp_cleanse(void *s, size_t len)
char *bitvector_bit_string(bitvector_t *x, char *buf, int len)
{
volatile unsigned char *p = (volatile unsigned char *)s;
while(len--) *p++ = 0;
int j, i;
uint32_t mask;
for (j = i = 0; j < (int)(x->length >> 5) && i < len - 1; j++) {
for (mask = 0x80000000; mask > 0; mask >>= 1) {
if (x->word[j] & mask)
buf[i] = '1';
else
buf[i] = '0';
++i;
if (i >= len - 1)
break;
}
}
buf[i] = 0; /* null terminate string */
return buf;
}
void
octet_string_set_to_zero(void *s, size_t len)
void bitvector_left_shift(bitvector_t *x, int shift)
{
int i;
const int base_index = shift >> 5;
const int bit_index = shift & 31;
const int word_length = x->length >> 5;
if (shift >= (int)x->length) {
bitvector_set_to_zero(x);
return;
}
if (bit_index == 0) {
for (i = 0; i < word_length - base_index; i++)
x->word[i] = x->word[i + base_index];
} else {
for (i = 0; i < word_length - base_index - 1; i++)
x->word[i] = (x->word[i + base_index] >> bit_index) ^
(x->word[i + base_index + 1] << (32 - bit_index));
x->word[word_length - base_index - 1] =
x->word[word_length - 1] >> bit_index;
}
/* now wrap up the final portion */
for (i = word_length - base_index; i < word_length; i++)
x->word[i] = 0;
}
int octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
{
uint8_t *end = b + len;
uint8_t accumulator = 0;
/*
* We use this somewhat obscure implementation to try to ensure the running
* time only depends on len, even accounting for compiler optimizations.
* The accumulator ends up zero iff the strings are equal.
*/
while (b < end)
accumulator |= (*a++ ^ *b++);
/* Return 1 if *not* equal. */
return accumulator != 0;
}
void srtp_cleanse(void *s, size_t len)
{
volatile unsigned char *p = (volatile unsigned char *)s;
while (len--)
*p++ = 0;
}
void octet_string_set_to_zero(void *s, size_t len)
{
#ifdef OPENSSL
OPENSSL_cleanse(s, len);
OPENSSL_cleanse(s, len);
#else
srtp_cleanse(s, len);
srtp_cleanse(s, len);
#endif
}
#ifdef TESTAPP_SOURCE
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
"abcdefghijklmnopqrstuvwxyz0123456789+/";
static int base64_block_to_octet_triple(char *out, char *in) {
unsigned char sextets[4] = {0};
int j = 0;
int i;
static int base64_block_to_octet_triple(char *out, char *in)
{
unsigned char sextets[4] = { 0 };
int j = 0;
int i;
for (i = 0; i < 4; i++) {
char *p = strchr(b64chars, in[i]);
if (p != NULL) sextets[i] = p - b64chars;
else j++;
}
for (i = 0; i < 4; i++) {
char *p = strchr(b64chars, in[i]);
if (p != NULL)
sextets[i] = p - b64chars;
else
j++;
}
out[0] = (sextets[0]<<2)|(sextets[1]>>4);
if (j < 2) out[1] = (sextets[1]<<4)|(sextets[2]>>2);
if (j < 1) out[2] = (sextets[2]<<6)|sextets[3];
return j;
out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
if (j < 2)
out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
if (j < 1)
out[2] = (sextets[2] << 6) | sextets[3];
return j;
}
int base64_string_to_octet_string(char *out, int *pad, char *in, int len) {
int k = 0;
int i = 0;
int j = 0;
if (len % 4 != 0) return 0;
int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
{
int k = 0;
int i = 0;
int j = 0;
if (len % 4 != 0)
return 0;
while (i < len && j == 0) {
j = base64_block_to_octet_triple(out + k, in + i);
k += 3;
i += 4;
}
*pad = j;
return i;
while (i < len && j == 0) {
j = base64_block_to_octet_triple(out + k, in + i);
k += 3;
i += 4;
}
*pad = j;
return i;
}
#endif

View File

@ -1,33 +1,33 @@
/*
* stats.c
*
* statistical tests
*
* statistical tests
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -44,14 +44,14 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "stat.h"
srtp_debug_module_t mod_stat = {
0, /* debugging is off by default */
(char *)"stat test" /* printable module name */
srtp_debug_module_t srtp_mod_stat = {
0, /* debugging is off by default */
(char *)"stat test" /* printable module name */
};
/*
@ -61,166 +61,153 @@ srtp_debug_module_t mod_stat = {
#define STAT_TEST_DATA_LEN 2500
srtp_err_status_t
stat_test_monobit(uint8_t *data) {
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t ones_count;
srtp_err_status_t stat_test_monobit(uint8_t *data)
{
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t ones_count;
ones_count = 0;
while (data < data_end) {
ones_count += octet_get_weight(*data);
data++;
}
ones_count = 0;
while (data < data_end) {
ones_count += octet_get_weight(*data);
data++;
}
debug_print(mod_stat, "bit count: %d", ones_count);
if ((ones_count < 9725) || (ones_count > 10275))
return srtp_err_status_algo_fail;
debug_print(srtp_mod_stat, "bit count: %d", ones_count);
return srtp_err_status_ok;
if ((ones_count < 9725) || (ones_count > 10275))
return srtp_err_status_algo_fail;
return srtp_err_status_ok;
}
srtp_err_status_t
stat_test_poker(uint8_t *data) {
int i;
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
double poker;
uint16_t f[16] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
while (data < data_end) {
f[*data & 0x0f]++; /* increment freq. count for low nibble */
f[(*data) >> 4]++; /* increment freq. count for high nibble */
data++;
}
srtp_err_status_t stat_test_poker(uint8_t *data)
{
int i;
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
double poker;
uint16_t f[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
poker = 0.0;
for (i=0; i < 16; i++)
poker += (double) f[i] * f[i];
while (data < data_end) {
f[*data & 0x0f]++; /* increment freq. count for low nibble */
f[(*data) >> 4]++; /* increment freq. count for high nibble */
data++;
}
poker *= (16.0 / 5000.0);
poker -= 5000.0;
poker = 0.0;
for (i = 0; i < 16; i++)
poker += (double)f[i] * f[i];
debug_print(mod_stat, "poker test: %f\n", poker);
if ((poker < 2.16) || (poker > 46.17))
return srtp_err_status_algo_fail;
return srtp_err_status_ok;
poker *= (16.0 / 5000.0);
poker -= 5000.0;
debug_print(srtp_mod_stat, "poker test: %f\n", poker);
if ((poker < 2.16) || (poker > 46.17))
return srtp_err_status_algo_fail;
return srtp_err_status_ok;
}
/*
* runs[i] holds the number of runs of size (i-1)
*/
srtp_err_status_t
stat_test_runs(uint8_t *data) {
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
int state = 0;
uint16_t mask;
int i;
/*
* the state variable holds the number of bits in the
* current run (or gap, if negative)
*/
while (data < data_end) {
srtp_err_status_t stat_test_runs(uint8_t *data)
{
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
int state = 0;
uint16_t mask;
int i;
/* loop over the bits of this byte */
for (mask = 1; mask < 256; mask <<= 1) {
if (*data & mask) {
/*
* the state variable holds the number of bits in the
* current run (or gap, if negative)
*/
/* next bit is a one */
if (state > 0) {
while (data < data_end) {
/* loop over the bits of this byte */
for (mask = 1; mask < 256; mask <<= 1) {
if (*data & mask) {
/* next bit is a one */
if (state > 0) {
/* prefix is a run, so increment the run-count */
state++;
/* prefix is a run, so increment the run-count */
state++;
/* check for long runs */
if (state > 25) {
debug_print(srtp_mod_stat, ">25 runs: %d", state);
return srtp_err_status_algo_fail;
}
/* check for long runs */
if (state > 25) {
debug_print(mod_stat, ">25 runs: %d", state);
return srtp_err_status_algo_fail;
}
} else if (state < 0) {
/* prefix is a gap */
if (state < -25) {
debug_print(srtp_mod_stat, ">25 gaps: %d", state);
return srtp_err_status_algo_fail; /* long-runs test
failed */
}
if (state < -6) {
state = -6; /* group together gaps > 5 */
}
gaps[-1 - state]++; /* increment gap count */
state = 1; /* set state at one set bit */
} else {
/* state is zero; this happens only at initialization */
state = 1;
}
} else {
/* next bit is a zero */
if (state > 0) {
/* prefix is a run */
if (state > 25) {
debug_print(srtp_mod_stat, ">25 runs (2): %d", state);
return srtp_err_status_algo_fail; /* long-runs test
failed */
}
if (state > 6) {
state = 6; /* group together runs > 5 */
}
runs[state - 1]++; /* increment run count */
state = -1; /* set state at one zero bit */
} else if (state < 0) {
/* prefix is a gap, so increment gap-count (decrement state)
*/
state--;
} else if (state < 0) {
/* check for long gaps */
if (state < -25) {
debug_print(srtp_mod_stat, ">25 gaps (2): %d", state);
return srtp_err_status_algo_fail;
}
/* prefix is a gap */
if (state < -25) {
debug_print(mod_stat, ">25 gaps: %d", state);
return srtp_err_status_algo_fail; /* long-runs test failed */
}
if (state < -6) {
state = -6; /* group together gaps > 5 */
}
gaps[-1-state]++; /* increment gap count */
state = 1; /* set state at one set bit */
} else {
} else {
/* state is zero; this happens only at initialization */
state = -1;
}
}
}
/* state is zero; this happens only at initialization */
state = 1;
}
} else {
/* next bit is a zero */
if (state > 0) {
/* prefix is a run */
if (state > 25) {
debug_print(mod_stat, ">25 runs (2): %d", state);
return srtp_err_status_algo_fail; /* long-runs test failed */
}
if (state > 6) {
state = 6; /* group together runs > 5 */
}
runs[state-1]++; /* increment run count */
state = -1; /* set state at one zero bit */
} else if (state < 0) {
/* prefix is a gap, so increment gap-count (decrement state) */
state--;
/* check for long gaps */
if (state < -25) {
debug_print(mod_stat, ">25 gaps (2): %d", state);
return srtp_err_status_algo_fail;
}
} else {
/* state is zero; this happens only at initialization */
state = -1;
}
}
/* move along to next octet */
data++;
}
/* move along to next octet */
data++;
}
if (srtp_mod_stat.on) {
debug_print(srtp_mod_stat, "runs test", NULL);
for (i = 0; i < 6; i++)
debug_print(srtp_mod_stat, " runs[]: %d", runs[i]);
for (i = 0; i < 6; i++)
debug_print(srtp_mod_stat, " gaps[]: %d", gaps[i]);
}
if (mod_stat.on) {
debug_print(mod_stat, "runs test", NULL);
for (i=0; i < 6; i++)
debug_print(mod_stat, " runs[]: %d", runs[i]);
for (i=0; i < 6; i++)
debug_print(mod_stat, " gaps[]: %d", gaps[i]);
}
/* check run and gap counts against the fixed limits */
for (i = 0; i < 6; i++)
if ((runs[i] < lo_value[i]) || (runs[i] > hi_value[i]) ||
(gaps[i] < lo_value[i]) || (gaps[i] > hi_value[i]))
return srtp_err_status_algo_fail;
/* check run and gap counts against the fixed limits */
for (i=0; i < 6; i++)
if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
return srtp_err_status_algo_fail;
return srtp_err_status_ok;
return srtp_err_status_ok;
}

View File

@ -43,14 +43,12 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "rdb.h"
/*
* this implementation of a replay database works as follows:
*
@ -61,7 +59,7 @@
*/
/* srtp_rdb_init initalizes rdb */
srtp_err_status_t srtp_rdb_init (srtp_rdb_t *rdb)
srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb)
{
v128_set_to_zero(&rdb->bitmask);
rdb->window_start = 0;
@ -71,9 +69,8 @@ srtp_err_status_t srtp_rdb_init (srtp_rdb_t *rdb)
/*
* srtp_rdb_check checks to see if index appears in rdb
*/
srtp_err_status_t srtp_rdb_check (const srtp_rdb_t *rdb, uint32_t p_index)
srtp_err_status_t srtp_rdb_check(const srtp_rdb_t *rdb, uint32_t p_index)
{
/* if the index appears after (or at very end of) the window, its good */
if (p_index >= rdb->window_start + rdb_bits_in_bitmask) {
return srtp_err_status_ok;
@ -101,35 +98,32 @@ srtp_err_status_t srtp_rdb_check (const srtp_rdb_t *rdb, uint32_t p_index)
* indicated that the index does not appear in the rdb, e.g., a mutex
* should protect the rdb between these calls
*/
srtp_err_status_t srtp_rdb_add_index (srtp_rdb_t *rdb, uint32_t p_index)
srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t p_index)
{
int delta;
unsigned int delta;
/* here we *assume* that p_index > rdb->window_start */
if (p_index < rdb->window_start)
return srtp_err_status_replay_fail;
delta = (p_index - rdb->window_start);
if (delta < rdb_bits_in_bitmask) {
/* if the p_index is within the window, set the appropriate bit */
v128_set_bit(&rdb->bitmask, delta);
} else {
delta -= rdb_bits_in_bitmask - 1;
/* shift the window forward by delta bits*/
v128_left_shift(&rdb->bitmask, delta);
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask - 1);
rdb->window_start += delta;
}
return srtp_err_status_ok;
}
srtp_err_status_t srtp_rdb_increment (srtp_rdb_t *rdb)
srtp_err_status_t srtp_rdb_increment(srtp_rdb_t *rdb)
{
if (rdb->window_start >= 0x7fffffff) {
return srtp_err_status_key_expired;
}
@ -137,7 +131,7 @@ srtp_err_status_t srtp_rdb_increment (srtp_rdb_t *rdb)
return srtp_err_status_ok;
}
uint32_t srtp_rdb_get_value (const srtp_rdb_t *rdb)
uint32_t srtp_rdb_get_value(const srtp_rdb_t *rdb)
{
return rdb->window_start;
}

View File

@ -44,12 +44,11 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "rdbx.h"
/*
* from RFC 3711:
*
@ -64,8 +63,6 @@
* incremented by one (if the packet containing s is authentic).
*/
/*
* rdbx implementation notes
*
@ -83,14 +80,13 @@
* srtp_index_advance(&guess, delta), where delta is the difference.
*
*
* A srtp_rdbx_t consists of a srtp_xtd_seq_num_t and a bitmask. The index is highest
* sequence number that has been received, and the bitmask indicates
* A srtp_rdbx_t consists of a srtp_xtd_seq_num_t and a bitmask. The index is
* highest sequence number that has been received, and the bitmask indicates
* which of the recent indicies have been received as well. The
* highest bit in the bitmask corresponds to the index in the bitmask.
*/
void srtp_index_init (srtp_xtd_seq_num_t *pi)
void srtp_index_init(srtp_xtd_seq_num_t *pi)
{
#ifdef NO_64BIT_MATH
*pi = make64(0, 0);
@ -99,7 +95,7 @@ void srtp_index_init (srtp_xtd_seq_num_t *pi)
#endif
}
void srtp_index_advance (srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
void srtp_index_advance(srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
{
#ifdef NO_64BIT_MATH
/* a > ~b means a+b will generate a carry */
@ -110,7 +106,6 @@ void srtp_index_advance (srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
#endif
}
/*
* srtp_index_guess(local, guess, s)
*
@ -124,24 +119,19 @@ void srtp_index_advance (srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
* unsigned integer!
*/
int32_t srtp_index_guess (const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s)
int32_t srtp_index_guess(const srtp_xtd_seq_num_t *local,
srtp_xtd_seq_num_t *guess,
srtp_sequence_number_t s)
{
#ifdef NO_64BIT_MATH
uint32_t local_roc = ((high32(*local) << 16) |
(low32(*local) >> 16));
uint32_t local_roc = ((high32(*local) << 16) | (low32(*local) >> 16));
uint16_t local_seq = (uint16_t)(low32(*local));
#else
uint32_t local_roc = (uint32_t)(*local >> 16);
uint16_t local_seq = (uint16_t)*local;
#endif
#ifdef NO_64BIT_MATH
uint32_t guess_roc = ((high32(*guess) << 16) |
(low32(*guess) >> 16));
uint16_t guess_seq = (uint16_t)(low32(*guess));
#else
uint32_t guess_roc = (uint32_t)(*guess >> 16);
uint16_t guess_seq = (uint16_t)*guess;
#endif
uint32_t guess_roc;
uint16_t guess_seq;
int32_t difference;
if (local_seq < seq_num_median) {
@ -163,10 +153,9 @@ int32_t srtp_index_guess (const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *g
}
guess_seq = s;
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
#ifdef NO_64BIT_MATH
*guess = make64(guess_roc >> 16,
(guess_roc << 16) | guess_seq);
*guess = make64(guess_roc >> 16, (guess_roc << 16) | guess_seq);
#else
*guess = (((uint64_t)guess_roc) << 16) | guess_seq;
#endif
@ -179,11 +168,11 @@ int32_t srtp_index_guess (const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *g
*
*/
/*
* srtp_rdbx_init(&r, ws) initializes the srtp_rdbx_t pointed to by r with window size ws
* srtp_rdbx_init(&r, ws) initializes the srtp_rdbx_t pointed to by r with
* window size ws
*/
srtp_err_status_t srtp_rdbx_init (srtp_rdbx_t *rdbx, unsigned long ws)
srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws)
{
if (ws == 0) {
return srtp_err_status_bad_param;
@ -201,7 +190,7 @@ srtp_err_status_t srtp_rdbx_init (srtp_rdbx_t *rdbx, unsigned long ws)
/*
* srtp_rdbx_dealloc(&r) frees memory for the srtp_rdbx_t pointed to by r
*/
srtp_err_status_t srtp_rdbx_dealloc (srtp_rdbx_t *rdbx)
srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx)
{
bitvector_dealloc(&rdbx->bitmask);
@ -215,12 +204,12 @@ srtp_err_status_t srtp_rdbx_dealloc (srtp_rdbx_t *rdbx)
* srtp_err_status_replay_old; otherwise, srtp_err_status_ok is returned.
*
*/
srtp_err_status_t srtp_rdbx_set_roc (srtp_rdbx_t *rdbx, uint32_t roc)
srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc)
{
bitvector_set_to_zero(&rdbx->bitmask);
#ifdef NO_64BIT_MATH
#error not yet implemented
#error not yet implemented
#else
/* make sure that we're not moving backwards */
@ -240,7 +229,7 @@ srtp_err_status_t srtp_rdbx_set_roc (srtp_rdbx_t *rdbx, uint32_t roc)
* for the srtp_rdbx_t pointed to by rdbx
*
*/
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index (const srtp_rdbx_t *rdbx)
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx)
{
return rdbx->index;
}
@ -250,7 +239,7 @@ srtp_xtd_seq_num_t srtp_rdbx_get_packet_index (const srtp_rdbx_t *rdbx)
* for the srtp_rdbx_t pointed to by rdbx
*
*/
unsigned long srtp_rdbx_get_window_size (const srtp_rdbx_t *rdbx)
unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx)
{
return bitvector_get_length(&rdbx->bitmask);
}
@ -259,16 +248,17 @@ unsigned long srtp_rdbx_get_window_size (const srtp_rdbx_t *rdbx)
* srtp_rdbx_check(&r, delta) checks to see if the srtp_xtd_seq_num_t
* which is at rdbx->index + delta is in the rdb
*/
srtp_err_status_t srtp_rdbx_check (const srtp_rdbx_t *rdbx, int delta)
srtp_err_status_t srtp_rdbx_check(const srtp_rdbx_t *rdbx, int delta)
{
if (delta > 0) { /* if delta is positive, it's good */
if (delta > 0) { /* if delta is positive, it's good */
return srtp_err_status_ok;
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
/* if delta is lower than the bitmask, it's bad */
return srtp_err_status_replay_old;
} else if (bitvector_get_bit(&rdbx->bitmask,
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
} else if (bitvector_get_bit(
&rdbx->bitmask,
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) ==
1) {
/* delta is within the window, so check the bitmask */
return srtp_err_status_replay_fail;
}
@ -285,17 +275,18 @@ srtp_err_status_t srtp_rdbx_check (const srtp_rdbx_t *rdbx, int delta)
* indicated that the index does not appear in the rdbx, e.g., a mutex
* should protect the rdbx between these calls if need be
*/
srtp_err_status_t srtp_rdbx_add_index (srtp_rdbx_t *rdbx, int delta)
srtp_err_status_t srtp_rdbx_add_index(srtp_rdbx_t *rdbx, int delta)
{
if (delta > 0) {
/* shift forward by delta */
srtp_index_advance(&rdbx->index, delta);
bitvector_left_shift(&rdbx->bitmask, delta);
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
bitvector_set_bit(&rdbx->bitmask,
bitvector_get_length(&rdbx->bitmask) - 1);
} else {
/* delta is in window */
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1 + delta);
bitvector_set_bit(&rdbx->bitmask,
bitvector_get_length(&rdbx->bitmask) - 1 + delta);
}
/* note that we need not consider the case that delta == 0 */
@ -303,8 +294,6 @@ srtp_err_status_t srtp_rdbx_add_index (srtp_rdbx_t *rdbx, int delta)
return srtp_err_status_ok;
}
/*
* srtp_rdbx_estimate_index(rdbx, guess, s)
*
@ -313,25 +302,27 @@ srtp_err_status_t srtp_rdbx_add_index (srtp_rdbx_t *rdbx, int delta)
* index to which s corresponds, and returns the difference between
* *guess and the locally stored synch info
*/
int32_t srtp_rdbx_estimate_index (const srtp_rdbx_t *rdbx, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s)
int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx,
srtp_xtd_seq_num_t *guess,
srtp_sequence_number_t s)
{
/*
* if the sequence number and rollover counter in the rdbx are
* non-zero, then use the srtp_index_guess(...) function, otherwise, just
* set the rollover counter to zero (since the srtp_index_guess(...)
* function might incorrectly guess that the rollover counter is
* 0xffffffff)
*/
/*
* if the sequence number and rollover counter in the rdbx are
* non-zero, then use the srtp_index_guess(...) function, otherwise, just
* set the rollover counter to zero (since the srtp_index_guess(...)
* function might incorrectly guess that the rollover counter is
* 0xffffffff)
*/
#ifdef NO_64BIT_MATH
/* seq_num_median = 0x8000 */
if (high32(rdbx->index) > 0 ||
low32(rdbx->index) > seq_num_median)
if (high32(rdbx->index) > 0 || low32(rdbx->index) > seq_num_median)
#else
if (rdbx->index > seq_num_median)
#endif
{ return srtp_index_guess(&rdbx->index, guess, s); }
{
return srtp_index_guess(&rdbx->index, guess, s);
}
#ifdef NO_64BIT_MATH
*guess = make64(0, (uint32_t)s);
@ -372,12 +363,12 @@ uint32_t srtp_rdbx_get_roc(const srtp_rdbx_t *rdbx)
* rollover counter value, then the function returns
* srtp_err_status_replay_old, otherwise, srtp_err_status_ok is returned.
*/
srtp_err_status_t srtp_rdbx_set_roc_seq (srtp_rdbx_t *rdbx,
uint32_t roc,
uint16_t seq)
srtp_err_status_t srtp_rdbx_set_roc_seq(srtp_rdbx_t *rdbx,
uint32_t roc,
uint16_t seq)
{
#ifdef NO_64BIT_MATH
#error not yet implemented
#error not yet implemented
#else
/* make sure that we're not moving backwards */
@ -393,4 +384,3 @@ srtp_err_status_t srtp_rdbx_set_roc_seq (srtp_rdbx_t *rdbx,
return srtp_err_status_ok;
}

View File

@ -3,32 +3,32 @@
*
* an unreliable transport simulator
* (for testing replay databases and suchlike)
*
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -44,66 +44,61 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "ut_sim.h"
int
ut_compar(const void *a, const void *b) {
return rand() > (RAND_MAX/2) ? -1 : 1;
int ut_compar(const void *a, const void *b)
{
return rand() > (RAND_MAX / 2) ? -1 : 1;
}
void
ut_init(ut_connection *utc) {
int i;
utc->index = 0;
void ut_init(ut_connection *utc)
{
int i;
utc->index = 0;
for (i=0; i < UT_BUF; i++)
utc->buffer[i] = i;
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
for (i = 0; i < UT_BUF; i++)
utc->buffer[i] = i;
utc->index = UT_BUF - 1;
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
utc->index = UT_BUF - 1;
}
uint32_t
ut_next_index(ut_connection *utc) {
uint32_t tmp;
uint32_t ut_next_index(ut_connection *utc)
{
uint32_t tmp;
tmp = utc->buffer[0];
utc->index++;
utc->buffer[0] = utc->index;
tmp = utc->buffer[0];
utc->index++;
utc->buffer[0] = utc->index;
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
return tmp;
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
return tmp;
}
#ifdef UT_TEST
#include <stdio.h>
int
main() {
uint32_t i, irecvd, idiff;
ut_connection utc;
int main()
{
uint32_t i, irecvd, idiff;
ut_connection utc;
ut_init(&utc);
ut_init(&utc);
for (i=0; i < 1000; i++) {
irecvd = ut_next_index(&utc);
idiff = i - irecvd;
printf("%lu\t%lu\t%d\n", i, irecvd, idiff);
}
return 0;
for (i = 0; i < 1000; i++) {
irecvd = ut_next_index(&utc);
idiff = i - irecvd;
printf("%lu\t%lu\t%d\n", i, irecvd, idiff);
}
return 0;
}
#endif

View File

@ -1,6 +1,6 @@
/*
* aes_calc.c
*
*
* A simple AES calculator for generating AES encryption values
*
* David A. McGrew
@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -44,10 +44,12 @@
*/
/*
Example usage (with first NIST FIPS 197 test case):
[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v
[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f \
00112233445566778899aabbccddeeff -v
plaintext: 00112233445566778899aabbccddeeff
key: 000102030405060708090a0b0c0d0e0f
ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a
@ -55,7 +57,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include "aes.h"
@ -63,98 +65,93 @@
#include <string.h>
#include "util.h"
void
usage(char *prog_name) {
printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
exit(255);
void usage(char *prog_name)
{
printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
exit(255);
}
#define AES_MAX_KEY_LEN 32
int
main (int argc, char *argv[]) {
v128_t data;
uint8_t key[AES_MAX_KEY_LEN];
srtp_aes_expanded_key_t exp_key;
int key_len, len;
int verbose = 0;
srtp_err_status_t status;
int main(int argc, char *argv[])
{
v128_t data;
uint8_t key[AES_MAX_KEY_LEN];
srtp_aes_expanded_key_t exp_key;
int key_len, len;
int verbose = 0;
srtp_err_status_t status;
if (argc == 3) {
/* we're not in verbose mode */
verbose = 0;
} else if (argc == 4) {
if (strncmp(argv[3], "-v", 2) == 0) {
/* we're in verbose mode */
verbose = 1;
if (argc == 3) {
/* we're not in verbose mode */
verbose = 0;
} else if (argc == 4) {
if (strncmp(argv[3], "-v", 2) == 0) {
/* we're in verbose mode */
verbose = 1;
} else {
/* unrecognized flag, complain and exit */
usage(argv[0]);
}
} else {
/* unrecognized flag, complain and exit */
usage(argv[0]);
/* we've been fed the wrong number of arguments - compain and exit */
usage(argv[0]);
}
} else {
/* we've been fed the wrong number of arguments - compain and exit */
usage(argv[0]);
}
/* read in key, checking length */
if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) {
fprintf(stderr,
"error: too many digits in key "
"(should be at most %d hexadecimal digits, found %u)\n",
AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1]));
exit(1);
}
len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2);
/* check that hex string is the right length */
if (len != 32 && len != 48 && len != 64) {
fprintf(stderr,
"error: bad number of digits in key "
"(should be 32/48/64 hexadecimal digits, found %d)\n",
len);
exit(1);
}
key_len = len/2;
/* read in plaintext, checking length */
if (strlen(argv[2]) > 16*2) {
fprintf(stderr,
"error: too many digits in plaintext "
"(should be %d hexadecimal digits, found %u)\n",
16*2, (unsigned)strlen(argv[2]));
exit(1);
}
len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2);
/* check that hex string is the right length */
if (len < 16*2) {
fprintf(stderr,
"error: too few digits in plaintext "
"(should be %d hexadecimal digits, found %d)\n",
16*2, len);
exit(1);
}
if (verbose) {
/* print out plaintext */
printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16));
}
/* read in key, checking length */
if (strlen(argv[1]) > AES_MAX_KEY_LEN * 2) {
fprintf(stderr, "error: too many digits in key "
"(should be at most %d hexadecimal digits, found %u)\n",
AES_MAX_KEY_LEN * 2, (unsigned)strlen(argv[1]));
exit(1);
}
len = hex_string_to_octet_string((char *)key, argv[1], AES_MAX_KEY_LEN * 2);
/* check that hex string is the right length */
if (len != 32 && len != 48 && len != 64) {
fprintf(stderr, "error: bad number of digits in key "
"(should be 32/48/64 hexadecimal digits, found %d)\n",
len);
exit(1);
}
key_len = len / 2;
/* encrypt plaintext */
status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
if (status) {
fprintf(stderr,
"error: AES key expansion failed.\n");
exit(1);
}
/* read in plaintext, checking length */
if (strlen(argv[2]) > 16 * 2) {
fprintf(stderr, "error: too many digits in plaintext "
"(should be %d hexadecimal digits, found %u)\n",
16 * 2, (unsigned)strlen(argv[2]));
exit(1);
}
len = hex_string_to_octet_string((char *)(&data), argv[2], 16 * 2);
/* check that hex string is the right length */
if (len < 16 * 2) {
fprintf(stderr, "error: too few digits in plaintext "
"(should be %d hexadecimal digits, found %d)\n",
16 * 2, len);
exit(1);
}
srtp_aes_encrypt(&data, &exp_key);
if (verbose) {
/* print out plaintext */
printf("plaintext:\t%s\n",
octet_string_hex_string((uint8_t *)&data, 16));
}
/* write ciphertext to output */
if (verbose) {
printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
printf("ciphertext:\t");
}
printf("%s\n", v128_hex_string(&data));
/* encrypt plaintext */
status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
if (status) {
fprintf(stderr, "error: AES key expansion failed.\n");
exit(1);
}
return 0;
srtp_aes_encrypt(&data, &exp_key);
/* write ciphertext to output */
if (verbose) {
printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
printf("ciphertext:\t");
}
printf("%s\n", v128_hex_string(&data));
return 0;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -44,12 +44,11 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */
#include <string.h> /* for memset() */
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */
#include "getopt_s.h"
#include "cipher.h"
#ifdef OPENSSL
@ -61,12 +60,9 @@
#define PRINT_DEBUG 0
void
cipher_driver_test_throughput(srtp_cipher_t *c);
srtp_err_status_t
cipher_driver_self_test(srtp_cipher_type_t *ct);
void cipher_driver_test_throughput(srtp_cipher_t *c);
srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct);
/*
* cipher_driver_test_buffering(ct) tests the cipher's output
@ -74,44 +70,43 @@ cipher_driver_self_test(srtp_cipher_type_t *ct);
* calls
*/
srtp_err_status_t
cipher_driver_test_buffering(srtp_cipher_t *c);
srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c);
/*
* functions for testing cipher cache thrash
*/
srtp_err_status_t
cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen, int num_cipher);
srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen,
int num_cipher);
void
cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
uint64_t
cipher_array_bits_per_second(srtp_cipher_t *cipher_array[], int num_cipher,
unsigned octets_in_buffer, int num_trials);
uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
int num_cipher,
unsigned octets_in_buffer,
int num_trials);
srtp_err_status_t
cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher);
srtp_err_status_t cipher_array_delete(srtp_cipher_t *cipher_array[],
int num_cipher);
srtp_err_status_t
cipher_array_alloc_init(srtp_cipher_t ***cipher_array, int num_ciphers,
srtp_cipher_type_t *ctype, int klen);
srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***cipher_array,
int num_ciphers,
srtp_cipher_type_t *ctype,
int klen);
void
usage(char *prog_name) {
printf("usage: %s [ -t | -v | -a ]\n", prog_name);
exit(255);
void usage(char *prog_name)
{
printf("usage: %s [ -t | -v | -a ]\n", prog_name);
exit(255);
}
void
check_status(srtp_err_status_t s) {
if (s) {
printf("error (code %d)\n", s);
exit(s);
}
return;
void check_status(srtp_err_status_t s)
{
if (s) {
printf("error (code %d)\n", s);
exit(s);
}
return;
}
/*
@ -129,151 +124,163 @@ extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
#endif
int
main(int argc, char *argv[]) {
srtp_cipher_t *c = NULL;
srtp_err_status_t status;
unsigned char test_key[48] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
};
int q;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
unsigned do_array_timing_test = 0;
int main(int argc, char *argv[])
{
srtp_cipher_t *c = NULL;
srtp_err_status_t status;
/* clang-format off */
unsigned char test_key[48] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
};
/* clang-format on */
int q;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
unsigned do_array_timing_test = 0;
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "tva");
if (q == -1)
break;
switch (q) {
case 't':
do_timing_test = 1;
break;
case 'v':
do_validation = 1;
break;
case 'a':
do_array_timing_test = 1;
break;
default:
usage(argv[0]);
}
}
printf("cipher test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
if (!do_validation && !do_timing_test && !do_array_timing_test)
usage(argv[0]);
/* arry timing (cache thrash) test */
if (do_array_timing_test) {
int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */
int num_cipher;
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&srtp_null_cipher, 0, num_cipher);
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&srtp_aes_icm_128, SRTP_AES_ICM_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_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
#ifdef OPENSSL
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);
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "tva");
if (q == -1)
break;
switch (q) {
case 't':
do_timing_test = 1;
break;
case 'v':
do_validation = 1;
break;
case 'a':
do_array_timing_test = 1;
break;
default:
usage(argv[0]);
}
}
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);
}
#endif
}
printf("cipher test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
if (!do_validation && !do_timing_test && !do_array_timing_test)
usage(argv[0]);
/* arry timing (cache thrash) test */
if (do_array_timing_test) {
int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */
int num_cipher;
for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
cipher_driver_test_array_throughput(&srtp_null_cipher, 0,
num_cipher);
for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
cipher_driver_test_array_throughput(
&srtp_aes_icm_128, SRTP_AES_ICM_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_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
if (do_validation) {
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
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);
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);
}
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);
}
#endif
}
}
/* do timing and/or buffer_test on srtp_null_cipher */
status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
check_status(status);
if (do_validation) {
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
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);
#endif
}
status = srtp_cipher_init(c, NULL);
check_status(status);
if (do_timing_test)
cipher_driver_test_throughput(c);
if (do_validation) {
status = cipher_driver_test_buffering(c);
/* do timing and/or buffer_test on srtp_null_cipher */
status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
check_status(status);
}
status = srtp_cipher_dealloc(c);
check_status(status);
/* run the throughput test on the aes_icm cipher (128-bit key) */
status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c, SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
}
status = srtp_cipher_init(c, test_key);
status = srtp_cipher_init(c, NULL);
check_status(status);
if (do_timing_test)
cipher_driver_test_throughput(c);
cipher_driver_test_throughput(c);
if (do_validation) {
status = cipher_driver_test_buffering(c);
check_status(status);
status = cipher_driver_test_buffering(c);
check_status(status);
}
status = srtp_cipher_dealloc(c);
check_status(status);
/* repeat the tests with 256-bit keys */
status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
/* run the throughput test on the aes_icm cipher (128-bit key) */
status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
}
status = srtp_cipher_init(c, test_key);
check_status(status);
if (do_timing_test)
cipher_driver_test_throughput(c);
cipher_driver_test_throughput(c);
if (do_validation) {
status = cipher_driver_test_buffering(c);
check_status(status);
status = cipher_driver_test_buffering(c);
check_status(status);
}
status = srtp_cipher_dealloc(c);
check_status(status);
/* repeat the tests with 256-bit keys */
status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
if (status) {
fprintf(stderr, "error: can't allocate cipher\n");
exit(status);
}
status = srtp_cipher_init(c, test_key);
check_status(status);
if (do_timing_test)
cipher_driver_test_throughput(c);
if (do_validation) {
status = cipher_driver_test_buffering(c);
check_status(status);
}
status = 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, SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
status = srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c,
SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
if (status) {
fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
exit(status);
@ -292,7 +299,8 @@ main(int argc, char *argv[]) {
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, SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
status = srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
if (status) {
fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
exit(status);
@ -309,39 +317,39 @@ main(int argc, char *argv[]) {
}
status = srtp_cipher_dealloc(c);
check_status(status);
#endif
#endif
return 0;
}
void
cipher_driver_test_throughput(srtp_cipher_t *c) {
int i;
int min_enc_len = 32;
int max_enc_len = 2048; /* should be a power of two */
int num_trials = 1000000;
printf("timing %s throughput, key length %d:\n", c->type->description, c->key_len);
fflush(stdout);
for (i=min_enc_len; i <= max_enc_len; i = i * 2)
printf("msg len: %d\tgigabits per second: %f\n",
i, srtp_cipher_bits_per_second(c, i, num_trials) / 1e9);
void cipher_driver_test_throughput(srtp_cipher_t *c)
{
int i;
int min_enc_len = 32;
int max_enc_len = 2048; /* should be a power of two */
int num_trials = 1000000;
printf("timing %s throughput, key length %d:\n", c->type->description,
c->key_len);
fflush(stdout);
for (i = min_enc_len; i <= max_enc_len; i = i * 2)
printf("msg len: %d\tgigabits per second: %f\n", i,
srtp_cipher_bits_per_second(c, i, num_trials) / 1e9);
}
srtp_err_status_t
cipher_driver_self_test(srtp_cipher_type_t *ct) {
srtp_err_status_t status;
printf("running cipher self-test for %s...", ct->description);
status = srtp_cipher_type_self_test(ct);
if (status) {
printf("failed with error code %d\n", status);
exit(status);
}
printf("passed\n");
return srtp_err_status_ok;
srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct)
{
srtp_err_status_t status;
printf("running cipher self-test for %s...", ct->description);
status = srtp_cipher_type_self_test(ct);
if (status) {
printf("failed with error code %d\n", status);
exit(status);
}
printf("passed\n");
return srtp_err_status_ok;
}
/*
@ -351,168 +359,166 @@ cipher_driver_self_test(srtp_cipher_type_t *ct) {
*/
#define INITIAL_BUFLEN 1024
srtp_err_status_t
cipher_driver_test_buffering(srtp_cipher_t *c) {
int i, j, num_trials = 1000;
unsigned len, buflen = INITIAL_BUFLEN;
uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
uint8_t idx[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34
};
srtp_err_status_t status;
printf("testing output buffering for cipher %s...",
c->type->description);
srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c)
{
int i, j, num_trials = 1000;
unsigned len, buflen = INITIAL_BUFLEN;
uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
uint8_t idx[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 };
srtp_err_status_t status;
for (i=0; i < num_trials; i++) {
printf("testing output buffering for cipher %s...", c->type->description);
/* set buffers to zero */
for (j=0; j < (int) buflen; j++) {
buffer0[j] = buffer1[j] = 0;
}
/* initialize cipher */
status = srtp_cipher_set_iv(c, (uint8_t*)idx, srtp_direction_encrypt);
if (status)
return status;
for (i = 0; i < num_trials; i++) {
/* set buffers to zero */
for (j = 0; j < (int)buflen; j++) {
buffer0[j] = buffer1[j] = 0;
}
/* generate 'reference' value by encrypting all at once */
status = srtp_cipher_encrypt(c, buffer0, &buflen);
if (status)
return status;
/* initialize cipher */
status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
if (status)
return status;
/* re-initialize cipher */
status = srtp_cipher_set_iv(c, (uint8_t*)idx, srtp_direction_encrypt);
if (status)
return status;
/* now loop over short lengths until buffer1 is encrypted */
current = buffer1;
end = buffer1 + buflen;
while (current < end) {
/* generate 'reference' value by encrypting all at once */
status = srtp_cipher_encrypt(c, buffer0, &buflen);
if (status)
return status;
/* choose a short length */
len = rand() & 0x01f;
/* re-initialize cipher */
status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
if (status)
return status;
/* make sure that len doesn't cause us to overreach the buffer */
if (current + len > end)
len = end - current;
/* now loop over short lengths until buffer1 is encrypted */
current = buffer1;
end = buffer1 + buflen;
while (current < end) {
/* choose a short length */
len = rand() & 0x01f;
status = srtp_cipher_encrypt(c, current, &len);
if (status)
return status;
/* advance pointer into buffer1 to reflect encryption */
current += len;
/* if buffer1 is all encrypted, break out of loop */
if (current == end)
break;
}
/* make sure that len doesn't cause us to overreach the buffer */
if (current + len > end)
len = end - current;
/* compare buffers */
for (j=0; j < (int) buflen; j++) {
if (buffer0[j] != buffer1[j]) {
status = srtp_cipher_encrypt(c, current, &len);
if (status)
return status;
/* advance pointer into buffer1 to reflect encryption */
current += len;
/* if buffer1 is all encrypted, break out of loop */
if (current == end)
break;
}
/* compare buffers */
for (j = 0; j < (int)buflen; j++) {
if (buffer0[j] != buffer1[j]) {
#if PRINT_DEBUG
printf("test case %d failed at byte %d\n", i, j);
printf("computed: %s\n", octet_string_hex_string(buffer1, buflen));
printf("expected: %s\n", octet_string_hex_string(buffer0, buflen));
#endif
return srtp_err_status_algo_fail;
}
printf("test case %d failed at byte %d\n", i, j);
printf("computed: %s\n",
octet_string_hex_string(buffer1, buflen));
printf("expected: %s\n",
octet_string_hex_string(buffer0, buflen));
#endif
return srtp_err_status_algo_fail;
}
}
}
}
printf("passed\n");
return srtp_err_status_ok;
printf("passed\n");
return srtp_err_status_ok;
}
/*
* The function cipher_test_throughput_array() tests the effect of CPU
* cache thrash on cipher throughput.
* cache thrash on cipher throughput.
*
* cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
* of srtp_cipher_t of type ctype
*/
srtp_err_status_t
cipher_array_alloc_init(srtp_cipher_t ***ca, int num_ciphers,
srtp_cipher_type_t *ctype, int klen) {
int i, j;
srtp_err_status_t status;
uint8_t *key;
srtp_cipher_t **cipher_array;
/* pad klen allocation, to handle aes_icm reading 16 bytes for the
14-byte salt */
int klen_pad = ((klen + 15) >> 4) << 4;
srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***ca,
int num_ciphers,
srtp_cipher_type_t *ctype,
int klen)
{
int i, j;
srtp_err_status_t status;
uint8_t *key;
srtp_cipher_t **cipher_array;
/* pad klen allocation, to handle aes_icm reading 16 bytes for the
14-byte salt */
int klen_pad = ((klen + 15) >> 4) << 4;
/* allocate array of pointers to ciphers */
cipher_array = (srtp_cipher_t **) malloc(sizeof(srtp_cipher_t *) * num_ciphers);
if (cipher_array == NULL)
return srtp_err_status_alloc_fail;
/* allocate array of pointers to ciphers */
cipher_array = (srtp_cipher_t **)srtp_crypto_alloc(sizeof(srtp_cipher_t *) *
num_ciphers);
if (cipher_array == NULL)
return srtp_err_status_alloc_fail;
/* set ca to location of cipher_array */
*ca = cipher_array;
/* set ca to location of cipher_array */
*ca = cipher_array;
/* allocate key */
key = srtp_crypto_alloc(klen_pad);
if (key == NULL) {
free(cipher_array);
return srtp_err_status_alloc_fail;
}
/* allocate and initialize an array of ciphers */
for (i=0; i < num_ciphers; i++) {
/* allocate key */
key = srtp_crypto_alloc(klen_pad);
if (key == NULL) {
srtp_crypto_free(cipher_array);
return srtp_err_status_alloc_fail;
}
/* allocate cipher */
status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
if (status)
return status;
/* generate random key and initialize cipher */
for (j=0; j < klen; j++)
key[j] = (uint8_t) rand();
for (; j < klen_pad; j++)
key[j] = 0;
status = srtp_cipher_init(*cipher_array, key);
if (status)
return status;
/* allocate and initialize an array of ciphers */
for (i = 0; i < num_ciphers; i++) {
/* allocate cipher */
status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
if (status)
return status;
/* printf("%dth cipher is at %p\n", i, *cipher_array); */
/* printf("%dth cipher description: %s\n", i, */
/* (*cipher_array)->type->description); */
/* advance cipher array pointer */
cipher_array++;
}
/* generate random key and initialize cipher */
for (j = 0; j < klen; j++)
key[j] = (uint8_t)rand();
for (; j < klen_pad; j++)
key[j] = 0;
status = srtp_cipher_init(*cipher_array, key);
if (status)
return status;
srtp_crypto_free(key);
/* printf("%dth cipher is at %p\n", i, *cipher_array); */
/* printf("%dth cipher description: %s\n", i, */
/* (*cipher_array)->type->description); */
return srtp_err_status_ok;
/* advance cipher array pointer */
cipher_array++;
}
srtp_crypto_free(key);
return srtp_err_status_ok;
}
srtp_err_status_t
cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher) {
int i;
for (i=0; i < num_cipher; i++) {
srtp_cipher_dealloc(cipher_array[i]);
}
srtp_err_status_t cipher_array_delete(srtp_cipher_t *cipher_array[],
int num_cipher)
{
int i;
free(cipher_array);
return srtp_err_status_ok;
for (i = 0; i < num_cipher; i++) {
srtp_cipher_dealloc(cipher_array[i]);
}
srtp_crypto_free(cipher_array);
return srtp_err_status_ok;
}
/*
* cipher_array_bits_per_second(c, l, t) computes (an estimate of) the
* number of bits that a cipher implementation can encrypt in a second
* when distinct keys are used to encrypt distinct messages
*
*
* c is a cipher (which MUST be allocated an initialized already), l
* is the length in octets of the test data to be encrypted, and t is
* the number of trials
@ -520,80 +526,85 @@ cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher) {
* if an error is encountered, the value 0 is returned
*/
uint64_t
cipher_array_bits_per_second(srtp_cipher_t *cipher_array[], int num_cipher,
unsigned octets_in_buffer, int num_trials) {
int i;
v128_t nonce;
clock_t timer;
unsigned char *enc_buf;
int cipher_index = rand() % num_cipher;
uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
int num_cipher,
unsigned octets_in_buffer,
int num_trials)
{
int i;
v128_t nonce;
clock_t timer;
unsigned char *enc_buf;
int cipher_index = rand() % num_cipher;
/* Over-alloc, for NIST CBC padding */
enc_buf = srtp_crypto_alloc(octets_in_buffer+17);
if (enc_buf == NULL)
return 0; /* indicate bad parameters by returning null */
memset(enc_buf, 0, octets_in_buffer);
/* time repeated trials */
v128_set_to_zero(&nonce);
timer = clock();
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
/* length parameter to srtp_cipher_encrypt is in/out -- out is total, padded
* length -- so reset it each time. */
unsigned octets_to_encrypt = octets_in_buffer;
/* Over-alloc, for NIST CBC padding */
enc_buf = srtp_crypto_alloc(octets_in_buffer + 17);
if (enc_buf == NULL)
return 0; /* indicate bad parameters by returning null */
/* encrypt buffer with cipher */
srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t*)&nonce, srtp_direction_encrypt);
srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
/* time repeated trials */
v128_set_to_zero(&nonce);
timer = clock();
for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
/* length parameter to srtp_cipher_encrypt is in/out -- out is total,
* padded
* length -- so reset it each time. */
unsigned octets_to_encrypt = octets_in_buffer;
/* choose a cipher at random from the array*/
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
}
timer = clock() - timer;
/* encrypt buffer with cipher */
srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t *)&nonce,
srtp_direction_encrypt);
srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf,
&octets_to_encrypt);
free(enc_buf);
/* choose a cipher at random from the array*/
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
}
timer = clock() - timer;
if (timer == 0) {
/* Too fast! */
return 0;
}
srtp_crypto_free(enc_buf);
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
if (timer == 0) {
/* Too fast! */
return 0;
}
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
}
void
cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher) {
int i;
int min_enc_len = 16;
int max_enc_len = 2048; /* should be a power of two */
int num_trials = 1000000;
printf("timing %s throughput with key length %d, array size %d:\n",
(ca[0])->type->description, (ca[0])->key_len, num_cipher);
fflush(stdout);
for (i=min_enc_len; i <= max_enc_len; i = i * 4)
printf("msg len: %d\tgigabits per second: %f\n", i,
cipher_array_bits_per_second(ca, num_cipher, i, num_trials) / 1e9);
void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher)
{
int i;
int min_enc_len = 16;
int max_enc_len = 2048; /* should be a power of two */
int num_trials = 1000000;
printf("timing %s throughput with key length %d, array size %d:\n",
(ca[0])->type->description, (ca[0])->key_len, num_cipher);
fflush(stdout);
for (i = min_enc_len; i <= max_enc_len; i = i * 4)
printf("msg len: %d\tgigabits per second: %f\n", i,
cipher_array_bits_per_second(ca, num_cipher, i, num_trials) /
1e9);
}
srtp_err_status_t
cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen, int num_cipher) {
srtp_cipher_t **ca = NULL;
srtp_err_status_t status;
srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen,
int num_cipher)
{
srtp_cipher_t **ca = NULL;
srtp_err_status_t status;
status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
if (status) {
printf("error: cipher_array_alloc_init() failed with error code %d\n",
status);
return status;
}
cipher_array_test_throughput(ca, num_cipher);
cipher_array_delete(ca, num_cipher);
return srtp_err_status_ok;
status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
if (status) {
printf("error: cipher_array_alloc_init() failed with error code %d\n",
status);
return status;
}
cipher_array_test_throughput(ca, num_cipher);
cipher_array_delete(ca, num_cipher);
return srtp_err_status_ok;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -43,117 +43,108 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h> /* for printf() */
#include <string.h> /* for strlen() */
#include <stdio.h> /* for printf() */
#include <string.h> /* for strlen() */
#include "datatypes.h"
#include "util.h"
void
byte_order(void);
void byte_order(void);
void
test_hex_string_funcs(void);
void test_hex_string_funcs(void);
void
print_string(char *s);
void print_string(char *s);
void
test_bswap(void);
void test_bswap(void);
int
main (void) {
/*
* this program includes various and sundry tests for fundamental
* datatypes. it's a grab-bag of throwaway code, retained only in
* case of future problems
*/
int main(void)
{
/*
* this program includes various and sundry tests for fundamental
* datatypes. it's a grab-bag of throwaway code, retained only in
* case of future problems
*/
int i, j;
v128_t x;
char *r =
"The Moving Finger writes; and, having writ,\n"
"Moves on: nor all thy Piety nor Wit\n"
"Shall lure it back to cancel half a Line,\n"
"Nor all thy Tears wash out a Word of it.";
char *s = "incomplet";
print_string(r);
print_string(s);
byte_order();
test_hex_string_funcs();
int i, j;
v128_t x;
char *r = "The Moving Finger writes; and, having writ,\n"
"Moves on: nor all thy Piety nor Wit\n"
"Shall lure it back to cancel half a Line,\n"
"Nor all thy Tears wash out a Word of it.";
char *s = "incomplet";
for (j=0; j < 128; j++) {
print_string(r);
print_string(s);
byte_order();
test_hex_string_funcs();
for (j = 0; j < 128; j++) {
v128_set_to_zero(&x);
/* x.v32[0] = (1 << j); */
v128_set_bit(&x, j);
printf("%s\n", v128_bit_string(&x));
v128_clear_bit(&x, j);
printf("%s\n", v128_bit_string(&x));
}
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
/* x.v32[0] = (1 << j); */
v128_set_bit(&x, j);
printf("%s\n", v128_bit_string(&x));
v128_clear_bit(&x, j);
printf("%s\n", v128_bit_string(&x));
}
for (i = 0; i < 128; i++) {
v128_set_bit(&x, i);
}
printf("%s\n", v128_bit_string(&x));
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
for (i=0; i < 128; i++) {
v128_set_bit(&x, i);
}
printf("%s\n", v128_bit_string(&x));
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
v128_set_bit(&x, 0);
for (i=0; i < 128; i++) {
printf("%s\n", v128_bit_string(&x));
v128_right_shift(&x, 1);
}
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
v128_set_bit(&x, 127);
for (i=0; i < 128; i++) {
printf("%s\n", v128_bit_string(&x));
v128_left_shift(&x, 1);
}
printf("----------------------------------------------\n");
for (i=0; i < 128; i++) {
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
v128_set_bit(&x, 0);
for (i = 0; i < 128; i++) {
printf("%s\n", v128_bit_string(&x));
v128_right_shift(&x, 1);
}
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
v128_set_bit(&x, 127);
v128_left_shift(&x, i);
printf("%s\n", v128_bit_string(&x));
}
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
for (i=0; i < 128; i+=2) {
v128_set_bit(&x, i);
}
printf("bit_string: { %s }\n", v128_bit_string(&x));
printf("get_bit: { ");
for (i=0; i < 128; i++) {
if (v128_get_bit(&x, i) == 1)
printf("1");
else
printf("0");
}
printf(" } \n");
for (i = 0; i < 128; i++) {
printf("%s\n", v128_bit_string(&x));
v128_left_shift(&x, 1);
}
printf("----------------------------------------------\n");
for (i = 0; i < 128; i++) {
v128_set_to_zero(&x);
v128_set_bit(&x, 127);
v128_left_shift(&x, i);
printf("%s\n", v128_bit_string(&x));
}
printf("----------------------------------------------\n");
v128_set_to_zero(&x);
for (i = 0; i < 128; i += 2) {
v128_set_bit(&x, i);
}
printf("bit_string: { %s }\n", v128_bit_string(&x));
printf("get_bit: { ");
for (i = 0; i < 128; i++) {
if (v128_get_bit(&x, i) == 1)
printf("1");
else
printf("0");
}
printf(" } \n");
test_bswap();
test_bswap();
return 0;
return 0;
}
/* byte_order() prints out byte ordering of datatypes */
void
byte_order(void) {
int i;
v128_t e;
void byte_order(void)
{
int i;
v128_t e;
#if 0
v16_t b;
v32_t c;
@ -180,63 +171,60 @@ byte_order(void) {
c.value = 0x00010002;
printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]);
#endif
#endif
printf("byte ordering of crypto/math datatypes:\n");
for (i=0; i < sizeof(e); i++)
e.v8[i] = i;
printf("v128_t: %s\n", v128_hex_string(&e));
printf("byte ordering of crypto/math datatypes:\n");
for (i = 0; i < sizeof(e); i++)
e.v8[i] = i;
printf("v128_t: %s\n", v128_hex_string(&e));
}
void
test_hex_string_funcs(void) {
char hex1[] = "abadcafe";
char hex2[] = "0123456789abcdefqqqqq";
char raw[10];
int len;
void test_hex_string_funcs(void)
{
char hex1[] = "abadcafe";
char hex2[] = "0123456789abcdefqqqqq";
char raw[10];
int len;
len = hex_string_to_octet_string(raw, hex1, strlen(hex1));
printf("computed length: %d\tstring: %s\n", len,
octet_string_hex_string(raw, len/2));
printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1);
len = hex_string_to_octet_string(raw, hex2, strlen(hex2));
printf("computed length: %d\tstring: %s\n", len,
octet_string_hex_string(raw, len/2));
printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
len = hex_string_to_octet_string(raw, hex1, strlen(hex1));
printf("computed length: %d\tstring: %s\n", len,
octet_string_hex_string(raw, len / 2));
printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1);
len = hex_string_to_octet_string(raw, hex2, strlen(hex2));
printf("computed length: %d\tstring: %s\n", len,
octet_string_hex_string(raw, len / 2));
printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
}
void
print_string(char *s) {
size_t i;
printf("%s\n", s);
printf("strlen(s) = %u\n", (unsigned)strlen(s));
printf("{ ");
for (i=0; i < strlen(s); i++) {
printf("0x%x, ", s[i]);
if (((i+1) % 8) == 0)
printf("\n ");
}
printf("}\n");
void print_string(char *s)
{
size_t i;
printf("%s\n", s);
printf("strlen(s) = %u\n", (unsigned)strlen(s));
printf("{ ");
for (i = 0; i < strlen(s); i++) {
printf("0x%x, ", s[i]);
if (((i + 1) % 8) == 0)
printf("\n ");
}
printf("}\n");
}
void
test_bswap(void) {
uint32_t x = 0x11223344;
uint64_t y = 0x1122334455667788LL;
void test_bswap(void)
{
uint32_t x = 0x11223344;
uint64_t y = 0x1122334455667788LL;
printf("before: %0x\nafter: %0x\n", x, (unsigned int)be32_to_cpu(x));
printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y,
(unsigned long long)be64_to_cpu(y));
printf("before: %0x\nafter: %0x\n", x, (unsigned int)be32_to_cpu(x));
printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y,
(unsigned long long)be64_to_cpu(y));
y = 1234;
y = 1234;
printf("1234: %0llx\n", (unsigned long long)y);
printf("as octet string: %s\n",
octet_string_hex_string((uint8_t *) &y, 8));
y = be64_to_cpu(y);
printf("bswapped octet string: %s\n",
octet_string_hex_string((uint8_t *) &y, 8));
printf("1234: %0llx\n", (unsigned long long)y);
printf("as octet string: %s\n", octet_string_hex_string((uint8_t *)&y, 8));
y = be64_to_cpu(y);
printf("bswapped octet string: %s\n",
octet_string_hex_string((uint8_t *)&y, 8));
}

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -43,45 +43,47 @@
*/
#include <stdio.h>
#include <string.h> /* for srtcmp() */
#include <string.h> /* for srtcmp() */
#include "config.h"
int
main(void) {
int err_count = 0;
int main(void)
{
int err_count = 0;
#ifdef WORDS_BIGENDIAN
printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
#else
printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n");
printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n");
#endif
#ifdef CPU_RISC
printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n");
printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n");
#elif defined(CPU_CISC)
printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n");
printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n");
#else
printf("CPU set to an unknown type, probably due to a configuration error\n");
err_count++;
printf(
"CPU set to an unknown type, probably due to a configuration error\n");
err_count++;
#endif
#ifdef CPU_ALTIVEC
printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n");
printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n");
#endif
#ifndef NO_64BIT_MATH
printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n");
printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n");
#else
printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n");
printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n");
#endif
#ifdef ERR_REPORTING_STDOUT
printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
#endif
if (err_count)
printf("warning: configuration is probably in error "
"(found %d problems)\n", err_count);
if (err_count)
printf("warning: configuration is probably in error "
"(found %d problems)\n",
err_count);
return err_count;
return err_count;
}

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -42,77 +42,76 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h> /* for printf() */
#include <stdio.h> /* for printf() */
#include "getopt_s.h"
#include "crypto_kernel.h"
void
usage(char *prog_name) {
printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name);
exit(255);
void usage(char *prog_name)
{
printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name);
exit(255);
}
int
main (int argc, char *argv[]) {
int q;
int do_validation = 0;
srtp_err_status_t status;
int main(int argc, char *argv[])
{
int q;
int do_validation = 0;
srtp_err_status_t status;
if (argc == 1)
usage(argv[0]);
if (argc == 1)
usage(argv[0]);
/* initialize kernel - we need to do this before anything else */
status = srtp_crypto_kernel_init();
if (status) {
printf("error: srtp_crypto_kernel init failed\n");
exit(1);
}
printf("srtp_crypto_kernel successfully initalized\n");
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "vd:");
if (q == -1)
break;
switch (q) {
case 'v':
do_validation = 1;
break;
case 'd':
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
default:
usage(argv[0]);
}
}
if (do_validation) {
printf("checking srtp_crypto_kernel status...\n");
status = srtp_crypto_kernel_status();
/* initialize kernel - we need to do this before anything else */
status = srtp_crypto_kernel_init();
if (status) {
printf("failed\n");
exit(1);
printf("error: srtp_crypto_kernel init failed\n");
exit(1);
}
printf("srtp_crypto_kernel passed self-tests\n");
}
printf("srtp_crypto_kernel successfully initalized\n");
status = srtp_crypto_kernel_shutdown();
if (status) {
printf("error: srtp_crypto_kernel shutdown failed\n");
exit(1);
}
printf("srtp_crypto_kernel successfully shut down\n");
return 0;
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "vd:");
if (q == -1)
break;
switch (q) {
case 'v':
do_validation = 1;
break;
case 'd':
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
default:
usage(argv[0]);
}
}
if (do_validation) {
printf("checking srtp_crypto_kernel status...\n");
status = srtp_crypto_kernel_status();
if (status) {
printf("failed\n");
exit(1);
}
printf("srtp_crypto_kernel passed self-tests\n");
}
status = srtp_crypto_kernel_shutdown();
if (status) {
printf("error: srtp_crypto_kernel shutdown failed\n");
exit(1);
}
printf("srtp_crypto_kernel successfully shut down\n");
return 0;
}
/*
@ -120,10 +119,9 @@ main (int argc, char *argv[]) {
* of the crypto_kernel
*/
srtp_err_status_t
crypto_kernel_cipher_test(void) {
srtp_err_status_t crypto_kernel_cipher_test(void)
{
/* not implemented yet! */
/* not implemented yet! */
return srtp_err_status_ok;
return srtp_err_status_ok;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -44,7 +44,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h>
@ -56,505 +56,332 @@
#define SHA_FAIL 1
#define MAX_HASH_DATA_LEN 1024
#define MAX_HASH_OUT_LEN 20
#define MAX_HASH_OUT_LEN 20
typedef struct hash_test_case_t {
unsigned data_len; /* number of octets in data */
unsigned hash_len; /* number of octets output by hash */
uint8_t data[MAX_HASH_DATA_LEN]; /* message data */
uint8_t hash[MAX_HASH_OUT_LEN]; /* expected hash output */
struct hash_test_case_t *next_test_case;
unsigned data_len; /* number of octets in data */
unsigned hash_len; /* number of octets output by hash */
uint8_t data[MAX_HASH_DATA_LEN]; /* message data */
uint8_t hash[MAX_HASH_OUT_LEN]; /* expected hash output */
struct hash_test_case_t *next_test_case;
} hash_test_case_t;
hash_test_case_t *sha1_test_case_list;
srtp_err_status_t
hash_test_case_add(hash_test_case_t **list_ptr,
char *hex_data,
unsigned data_len,
char *hex_hash,
unsigned hash_len) {
hash_test_case_t *list_head = *list_ptr;
hash_test_case_t *test_case;
unsigned tmp_len;
srtp_err_status_t hash_test_case_add(hash_test_case_t **list_ptr,
char *hex_data,
unsigned data_len,
char *hex_hash,
unsigned hash_len)
{
hash_test_case_t *list_head = *list_ptr;
hash_test_case_t *test_case;
unsigned tmp_len;
test_case = malloc(sizeof(hash_test_case_t));
if (test_case == NULL)
return srtp_err_status_alloc_fail;
tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2);
if (tmp_len != data_len*2) {
free(test_case);
return srtp_err_status_parse_err;
}
test_case = malloc(sizeof(hash_test_case_t));
if (test_case == NULL)
return srtp_err_status_alloc_fail;
tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2);
if (tmp_len != hash_len*2) {
free(test_case);
return srtp_err_status_parse_err;
}
tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data,
data_len * 2);
if (tmp_len != data_len * 2) {
free(test_case);
return srtp_err_status_parse_err;
}
test_case->data_len = data_len;
test_case->hash_len = hash_len;
tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash,
hash_len * 2);
if (tmp_len != hash_len * 2) {
free(test_case);
return srtp_err_status_parse_err;
}
/* add the new test case to the head of the list */
test_case->next_test_case = list_head;
*list_ptr = test_case;
test_case->data_len = data_len;
test_case->hash_len = hash_len;
return srtp_err_status_ok;
/* add the new test case to the head of the list */
test_case->next_test_case = list_head;
*list_ptr = test_case;
return srtp_err_status_ok;
}
srtp_err_status_t
sha1_test_case_validate(const hash_test_case_t *test_case) {
srtp_sha1_ctx_t ctx;
uint32_t hash_value[5];
srtp_err_status_t sha1_test_case_validate(const hash_test_case_t *test_case)
{
srtp_sha1_ctx_t ctx;
uint32_t hash_value[5];
if (test_case == NULL)
return srtp_err_status_bad_param;
if (test_case == NULL)
return srtp_err_status_bad_param;
if (test_case->hash_len != 20)
return srtp_err_status_bad_param;
if (test_case->data_len > MAX_HASH_DATA_LEN)
return srtp_err_status_bad_param;
if (test_case->hash_len != 20)
return srtp_err_status_bad_param;
if (test_case->data_len > MAX_HASH_DATA_LEN)
return srtp_err_status_bad_param;
srtp_sha1_init(&ctx);
srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
srtp_sha1_final(&ctx, hash_value);
if (0 == memcmp(test_case->hash, hash_value, 20)) {
srtp_sha1_init(&ctx);
srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
srtp_sha1_final(&ctx, hash_value);
if (0 == memcmp(test_case->hash, hash_value, 20)) {
#if VERBOSE
printf("PASSED: reference value: %s\n",
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("PASSED: computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20));
#endif
return srtp_err_status_ok;
}
printf("PASSED: reference value: %s\n",
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("PASSED: computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20));
#endif
return srtp_err_status_ok;
}
printf("reference value: %s\n",
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20));
printf("reference value: %s\n",
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
printf("computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20));
return srtp_err_status_algo_fail;
return srtp_err_status_algo_fail;
}
struct hex_sha1_test_case_t {
unsigned bit_len;
char hex_data[MAX_HASH_DATA_LEN*2];
char hex_hash[40];
unsigned bit_len;
char hex_data[MAX_HASH_DATA_LEN * 2];
char hex_hash[40];
};
srtp_err_status_t
sha1_add_test_cases(void) {
int i;
srtp_err_status_t err;
srtp_err_status_t sha1_add_test_cases(void)
{
int i;
srtp_err_status_t err;
/*
* these test cases are taken from the "SHA-1 Sample Vectors"
* provided by NIST at http://csrc.nist.gov/cryptval/shs.html
*/
/*
* these test cases are taken from the "SHA-1 Sample Vectors"
* provided by NIST at http://csrc.nist.gov/cryptval/shs.html
*/
struct hex_sha1_test_case_t tc[] = {
{
0,
"",
"da39a3ee5e6b4b0d3255bfef95601890afd80709"
},
{
8,
"a8",
"99f2aa95e36f95c2acb0eaf23998f030638f3f15"
},
{
16,
"3000",
"f944dcd635f9801f7ac90a407fbc479964dec024"
},
{
24,
"42749e",
"a444319e9b6cc1e8464c511ec0969c37d6bb2619"
},
{
32,
"9fc3fe08",
"16a0ff84fcc156fd5d3ca3a744f20a232d172253"
},
{
40,
"b5c1c6f1af",
"fec9deebfcdedaf66dda525e1be43597a73a1f93"
},
{
48,
"e47571e5022e",
"8ce051181f0ed5e9d0c498f6bc4caf448d20deb5"
},
{
56,
"3e1b28839fb758",
"67da53837d89e03bf652ef09c369a3415937cfd3"
},
{
64,
"a81350cbb224cb90",
"305e4ff9888ad855a78573cddf4c5640cce7e946"
},
{
72, "c243d167923dec3ce1",
"5902b77b3265f023f9bbc396ba1a93fa3509bde7"
},
{
80,
"50ac18c59d6a37a29bf4",
"fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab"
},
{
88,
"98e2b611ad3b1cccf634f6",
"1d20fbe00533c10e3cbd6b27088a5de0c632c4b5"
},
{
96,
"73fe9afb68e1e8712e5d4eec",
"7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93"
},
{
104,
"9e701ed7d412a9226a2a130e66",
"706f0677146307b20bb0e8d6311e329966884d13"
},
{
112,
"6d3ee90413b0a7cbf69e5e6144ca",
"a7241a703aaf0d53fe142f86bf2e849251fa8dff"
},
{
120,
"fae24d56514efcb530fd4802f5e71f",
"400f53546916d33ad01a5e6df66822dfbdc4e9e6"
},
{
128,
"c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
"fac8ab93c1ae6c16f0311872b984f729dc928ccd"
},
{
136,
"d98cded2adabf08fda356445c781802d95",
"fba6d750c18da58f6e2aab10112b9a5ef3301b3b"
},
{
144,
"bcc6d7087a84f00103ccb32e5f5487a751a2",
"29d27c2d44c205c8107f0351b05753ac708226b6"
},
{
152,
"36ecacb1055434190dbbc556c48bafcb0feb0d",
"b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845"
},
{
160,
"5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
"96d08c430094b9fcc164ad2fb6f72d0a24268f68"
},
{
168, "c95b441d8270822a46a798fae5defcf7b26abace36",
"a287ea752a593d5209e287881a09c49fa3f0beb1"
},
{
176,
"83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
"a06c713779cbd88519ed4a585ac0cb8a5e9d612b"
},
{
184,
"755175528d55c39c56493d697b790f099a5ce741f7754b",
"bff7d52c13a3688132a1d407b1ab40f5b5ace298"
},
{
192,
"088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
"c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9"
},
{
200,
"a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
"ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1"
},
{
208,
"8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
"29e66ed23e914351e872aa761df6e4f1a07f4b81"
},
{
216,
"a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
"b28cf5e5b806a01491d41f69bd9248765c5dc292"
},
{
224,
"589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
"60224fb72c46069652cd78bcd08029ef64da62f3"
},
{
232,
"a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
"b72c4a86f72608f24c05f3b9088ef92fba431df7"
},
{
240,
"82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
"73779ad5d6b71b9b8328ef7220ff12eb167076ac"
},
{
248,
"9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
"a09671d4452d7cf50015c914a1e31973d20cc1a0"
},
{
256,
"041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
"e88cdcd233d99184a6fd260b8fca1b7f7687aee0"
},
{
264,
"17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
"010def22850deb1168d525e8c84c28116cb8a269"
},
{
272,
"d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77",
"aeaa40ba1717ed5439b1e6ea901b294ba500f9ad"
},
{
280,
"09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f",
"c6433791238795e34f080a5f1f1723f065463ca0"
},
{
288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d",
"e21e22b89c1bb944a32932e6b2a2f20d491982c3"
},
{
296,
"b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22",
"575323a9661f5d28387964d2ba6ab92c17d05a8a"
},
{
304,
"5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910",
"feb44494af72f245bfe68e86c4d7986d57c11db7"
},
{
312,
"498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5",
"cff2290b3648ba2831b98dde436a72f9ebf51eee"
},
{
320,
"3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e",
"9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c"
},
{
328,
"dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f",
"afedb0ff156205bcd831cbdbda43db8b0588c113"
},
{
336,
"5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33",
"8deb1e858f88293a5e5e4d521a34b2a4efa70fc4"
},
{
344,
"df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab",
"95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf"
},
{
352,
"1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc",
"f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2"
},
{
360,
"ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54",
"7b13bb0dbf14964bd63b133ac85e22100542ef55"
},
{
368,
"d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258",
"c314d2b6cf439be678d2a74e890d96cfac1c02ed"
},
{
376,
"32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6",
"4d0be361e410b47a9d67d8ce0bb6a8e01c53c078"
},
{
384,
"e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02",
"e5353431ffae097f675cbf498869f6fbb6e1c9f2"
},
{
392,
"e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9",
"b8720a7068a085c018ab18961de2765aa6cd9ac4"
},
{
400,
"bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475",
"b0732181568543ba85f2b6da602b4b065d9931aa"
},
{
408,
"235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944",
"9c22674cf3222c3ba921672694aafee4ce67b96b"
},
{
416,
"07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709",
"d128335f4cecca9066cdae08958ce656ff0b4cfc"
},
{
424,
"65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f",
"0b67c57ac578de88a2ae055caeaec8bb9b0085a0"
},
{
432,
"dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
"c766f912a89d4ccda88e0cce6a713ef5f178b596"
},
{
440,
"4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
"9aa3925a9dcb177b15ccff9b78e70cf344858779"
},
{
448,
"ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
"4811fa30042fc076acf37c8e2274d025307e5943"
},
{
456,
"8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
"6743018450c9730761ee2b130df9b91c1e118150"
},
{
464,
"497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
"71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645"
},
{
472,
"72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
"a7d9dc68dacefb7d6116186048cb355cc548e11d"
},
{
480,
"7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
"142e429f0522ba5abf5131fa81df82d355b96909"
},
{
488,
"74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
"ef72db70dcbcab991e9637976c6faf00d22caae9"
},
{
496,
"46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
"f220a7457f4588d639dc21407c942e9843f8e26b"
},
{
504,
"836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645",
"ddd2117b6e309c233ede85f962a0c2fc215e5c69"
},
{
512,
"7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116",
"a3054427cdb13f164a610b348702724c808a0dcc"
struct hex_sha1_test_case_t tc[] = {
{ 0, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709" },
{ 8, "a8", "99f2aa95e36f95c2acb0eaf23998f030638f3f15" },
{ 16, "3000", "f944dcd635f9801f7ac90a407fbc479964dec024" },
{ 24, "42749e", "a444319e9b6cc1e8464c511ec0969c37d6bb2619" },
{ 32, "9fc3fe08", "16a0ff84fcc156fd5d3ca3a744f20a232d172253" },
{ 40, "b5c1c6f1af", "fec9deebfcdedaf66dda525e1be43597a73a1f93" },
{ 48, "e47571e5022e", "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5" },
{ 56, "3e1b28839fb758", "67da53837d89e03bf652ef09c369a3415937cfd3" },
{ 64, "a81350cbb224cb90", "305e4ff9888ad855a78573cddf4c5640cce7e946" },
{ 72, "c243d167923dec3ce1",
"5902b77b3265f023f9bbc396ba1a93fa3509bde7" },
{ 80, "50ac18c59d6a37a29bf4",
"fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab" },
{ 88, "98e2b611ad3b1cccf634f6",
"1d20fbe00533c10e3cbd6b27088a5de0c632c4b5" },
{ 96, "73fe9afb68e1e8712e5d4eec",
"7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93" },
{ 104, "9e701ed7d412a9226a2a130e66",
"706f0677146307b20bb0e8d6311e329966884d13" },
{ 112, "6d3ee90413b0a7cbf69e5e6144ca",
"a7241a703aaf0d53fe142f86bf2e849251fa8dff" },
{ 120, "fae24d56514efcb530fd4802f5e71f",
"400f53546916d33ad01a5e6df66822dfbdc4e9e6" },
{ 128, "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
"fac8ab93c1ae6c16f0311872b984f729dc928ccd" },
{ 136, "d98cded2adabf08fda356445c781802d95",
"fba6d750c18da58f6e2aab10112b9a5ef3301b3b" },
{ 144, "bcc6d7087a84f00103ccb32e5f5487a751a2",
"29d27c2d44c205c8107f0351b05753ac708226b6" },
{ 152, "36ecacb1055434190dbbc556c48bafcb0feb0d",
"b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845" },
{ 160, "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
"96d08c430094b9fcc164ad2fb6f72d0a24268f68" },
{ 168, "c95b441d8270822a46a798fae5defcf7b26abace36",
"a287ea752a593d5209e287881a09c49fa3f0beb1" },
{ 176, "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
"a06c713779cbd88519ed4a585ac0cb8a5e9d612b" },
{ 184, "755175528d55c39c56493d697b790f099a5ce741f7754b",
"bff7d52c13a3688132a1d407b1ab40f5b5ace298" },
{ 192, "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
"c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9" },
{ 200, "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
"ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1" },
{ 208, "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
"29e66ed23e914351e872aa761df6e4f1a07f4b81" },
{ 216, "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
"b28cf5e5b806a01491d41f69bd9248765c5dc292" },
{ 224, "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
"60224fb72c46069652cd78bcd08029ef64da62f3" },
{ 232, "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
"b72c4a86f72608f24c05f3b9088ef92fba431df7" },
{ 240, "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
"73779ad5d6b71b9b8328ef7220ff12eb167076ac" },
{ 248, "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
"a09671d4452d7cf50015c914a1e31973d20cc1a0" },
{ 256,
"041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
"e88cdcd233d99184a6fd260b8fca1b7f7687aee0" },
{ 264,
"17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
"010def22850deb1168d525e8c84c28116cb8a269" },
{ 272, "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc9862"
"0cf77",
"aeaa40ba1717ed5439b1e6ea901b294ba500f9ad" },
{ 280, "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838"
"443328f",
"c6433791238795e34f080a5f1f1723f065463ca0" },
{ 288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b2659"
"4a25c709d",
"e21e22b89c1bb944a32932e6b2a2f20d491982c3" },
{ 296, "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d"
"79f4f195b22",
"575323a9661f5d28387964d2ba6ab92c17d05a8a" },
{ 304, "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d2"
"34cc1c5002910",
"feb44494af72f245bfe68e86c4d7986d57c11db7" },
{ 312, "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8"
"ba8a621fd6e3be5",
"cff2290b3648ba2831b98dde436a72f9ebf51eee" },
{ 320, "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15c"
"b5c83afb4b570376e",
"9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c" },
{ 328, "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99ca"
"c34dfca38910db2678f",
"afedb0ff156205bcd831cbdbda43db8b0588c113" },
{ 336, "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c"
"2fcf9716d3fad261dff33",
"8deb1e858f88293a5e5e4d521a34b2a4efa70fc4" },
{ 344, "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f"
"20fd697c3e4c8b8c5f590ab",
"95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf" },
{ 352, "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b"
"48c68d7f7057e5675cd96fcfc",
"f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2" },
{ 360, "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e179"
"0e888e09fbe3a70412176cb3b54",
"7b13bb0dbf14964bd63b133ac85e22100542ef55" },
{ 368, "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b08"
"4d3741afb8d24aaa8ab9c104f7258",
"c314d2b6cf439be678d2a74e890d96cfac1c02ed" },
{ 376, "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a"
"6c0d615c2ac8ad04b213cc589541cf6",
"4d0be361e410b47a9d67d8ce0bb6a8e01c53c078" },
{ 384, "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d"
"29688a65e2e3f3da47a45ac14343c9c02",
"e5353431ffae097f675cbf498869f6fbb6e1c9f2" },
{ 392, "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97a"
"b506ee05aebebc1eed09fc0e357109818b9",
"b8720a7068a085c018ab18961de2765aa6cd9ac4" },
{ 400, "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a"
"0d96e9e33326ccb7747cfff0852b961bfd475",
"b0732181568543ba85f2b6da602b4b065d9931aa" },
{ 408, "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7da"
"d814bce8dabb611790a6abe56030b798b75c944",
"9c22674cf3222c3ba921672694aafee4ce67b96b" },
{ 416, "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9"
"ee07cb169ec5186292e44c27e5696a967f5e67709",
"d128335f4cecca9066cdae08958ce656ff0b4cfc" },
{ 424, "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241"
"822bf67e6335a6d8b5ed06abf8841884c636a25733f",
"0b67c57ac578de88a2ae055caeaec8bb9b0085a0" },
{ 432, "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b759"
"41d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
"c766f912a89d4ccda88e0cce6a713ef5f178b596" },
{ 440, "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373"
"dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
"9aa3925a9dcb177b15ccff9b78e70cf344858779" },
{ 448, "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8a"
"a7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
"4811fa30042fc076acf37c8e2274d025307e5943" },
{ 456, "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be"
"22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
"6743018450c9730761ee2b130df9b91c1e118150" },
{ 464, "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623"
"d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
"71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645" },
{ 472, "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e7"
"3e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
"a7d9dc68dacefb7d6116186048cb355cc548e11d" },
{ 480, "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb"
"66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
"142e429f0522ba5abf5131fa81df82d355b96909" },
{ 488, "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd69"
"13c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
"ef72db70dcbcab991e9637976c6faf00d22caae9" },
{ 496, "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc409"
"75c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
"f220a7457f4588d639dc21407c942e9843f8e26b" },
{ 504, "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc03"
"48e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c864"
"5",
"ddd2117b6e309c233ede85f962a0c2fc215e5c69" },
{ 512, "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2"
"438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c61"
"16",
"a3054427cdb13f164a610b348702724c808a0dcc" }
};
for (i = 0; i < 65; i++) {
err = hash_test_case_add(&sha1_test_case_list, tc[i].hex_data,
tc[i].bit_len / 8, tc[i].hex_hash, 20);
if (err) {
printf("error adding hash test case (code %d)\n", err);
return err;
}
}
};
for (i=0; i < 65; i++) {
err = hash_test_case_add(&sha1_test_case_list,
tc[i].hex_data,
tc[i].bit_len/8,
tc[i].hex_hash, 20);
return srtp_err_status_ok;
}
srtp_err_status_t sha1_dealloc_test_cases(void)
{
hash_test_case_t *t, *next;
for (t = sha1_test_case_list; t != NULL; t = next) {
next = t->next_test_case;
free(t);
}
sha1_test_case_list = NULL;
return srtp_err_status_ok;
}
srtp_err_status_t sha1_validate(void)
{
hash_test_case_t *test_case;
srtp_err_status_t err;
err = sha1_add_test_cases();
if (err) {
printf("error adding hash test case (code %d)\n", err);
return err;
printf("error adding SHA1 test cases (error code %d)\n", err);
return err;
}
}
return srtp_err_status_ok;
if (sha1_test_case_list == NULL)
return srtp_err_status_cant_check;
test_case = sha1_test_case_list;
while (test_case != NULL) {
err = sha1_test_case_validate(test_case);
if (err) {
printf("error validating hash test case (error code %d)\n", err);
return err;
}
test_case = test_case->next_test_case;
}
sha1_dealloc_test_cases();
return srtp_err_status_ok;
}
srtp_err_status_t
sha1_dealloc_test_cases(void) {
hash_test_case_t *t, *next;
int main(void)
{
srtp_err_status_t err;
for (t = sha1_test_case_list; t != NULL; t = next) {
next = t->next_test_case;
free(t);
}
printf("sha1 test driver\n");
sha1_test_case_list = NULL;
return srtp_err_status_ok;
}
srtp_err_status_t
sha1_validate(void) {
hash_test_case_t *test_case;
srtp_err_status_t err;
err = sha1_add_test_cases();
if (err) {
printf("error adding SHA1 test cases (error code %d)\n", err);
return err;
}
if (sha1_test_case_list == NULL)
return srtp_err_status_cant_check;
test_case = sha1_test_case_list;
while (test_case != NULL) {
err = sha1_test_case_validate(test_case);
err = sha1_validate();
if (err) {
printf("error validating hash test case (error code %d)\n", err);
return err;
printf("SHA1 did not pass validation testing\n");
return 1;
}
test_case = test_case->next_test_case;
}
sha1_dealloc_test_cases();
return srtp_err_status_ok;
}
int
main (void) {
srtp_err_status_t err;
printf("sha1 test driver\n");
err = sha1_validate();
if (err) {
printf("SHA1 did not pass validation testing\n");
return 1;
}
printf("SHA1 passed validation tests\n");
return 0;
printf("SHA1 passed validation tests\n");
return 0;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -44,10 +44,10 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h> /* for printf() */
#include <stdio.h> /* for printf() */
#include "err.h"
#include "stat.h"
@ -56,192 +56,203 @@
#include "cipher.h"
typedef struct {
void *state;
void *state;
} random_source_t;
srtp_err_status_t
random_source_alloc(void);
srtp_err_status_t random_source_alloc(void);
void
err_check(srtp_err_status_t s) {
if (s) {
printf("error (code %d)\n", s);
exit(1);
}
void err_check(srtp_err_status_t s)
{
if (s) {
printf("error (code %d)\n", s);
exit(1);
}
}
int
main (int argc, char *argv[]) {
uint8_t buffer[2532];
unsigned int buf_len = 2500;
int i, j;
extern srtp_cipher_type_t srtp_aes_icm_128;
extern srtp_cipher_type_t srtp_aes_icm_256;
int main(int argc, char *argv[])
{
uint8_t buffer[2532];
unsigned int buf_len = 2500;
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;
extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
#endif
srtp_cipher_t *c;
uint8_t key[46] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
srtp_cipher_t *c;
/* clang-format off */
uint8_t key[46] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
};
v128_t nonce;
int num_trials = 500;
int num_fail;
/* clang-format on */
v128_t nonce;
int num_trials = 500;
int num_fail;
printf("statistical tests driver\n");
printf("statistical tests driver\n");
v128_set_to_zero(&nonce);
for (i=0; i < 2500; i++)
buffer[i] = 0;
v128_set_to_zero(&nonce);
for (i = 0; i < 2500; i++)
buffer[i] = 0;
/* run tests */
printf("running stat_tests on all-null buffer, expecting failure\n");
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
/* run tests */
printf("running stat_tests on all-null buffer, expecting failure\n");
printf("monobit %d\n", stat_test_monobit(buffer));
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();
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));
printf("runs %d\n", stat_test_runs(buffer));
for (i = 0; i < 2500; i++)
buffer[i] = rand();
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));
printf("runs %d\n", stat_test_runs(buffer));
printf("running stat_tests on AES-128-ICM, 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_icm_128, &c, SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
printf("runs test (please be patient): ");
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for(j=0; j < num_trials; j++) {
for (i=0; i < 2500; i++)
buffer[i] = 0;
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
printf("running stat_tests on AES-128-ICM, 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_icm_128, &c,
SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) {
num_fail++;
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
printf("runs test (please be patient): ");
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for (j = 0; j < num_trials; j++) {
for (i = 0; i < 2500; i++)
buffer[i] = 0;
nonce.v32[3] = i;
err_check(
srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) {
num_fail++;
}
}
}
printf("%d failures in %d tests\n", num_fail, num_trials);
printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n");
printf("%d failures in %d tests\n", num_fail, num_trials);
printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n");
err_check(srtp_cipher_dealloc(c));
err_check(srtp_cipher_dealloc(c));
printf("running stat_tests on AES-256-ICM, expecting success\n");
/* set buffer to cipher output */
for (i=0; i < 2500; i++)
buffer[i] = 0;
err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
printf("runs test (please be patient): ");
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for(j=0; j < num_trials; j++) {
for (i=0; i < 2500; i++)
buffer[i] = 0;
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
printf("running stat_tests on AES-256-ICM, expecting success\n");
/* set buffer to cipher output */
for (i = 0; i < 2500; i++)
buffer[i] = 0;
err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) {
num_fail++;
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
printf("runs test (please be patient): ");
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for (j = 0; j < num_trials; j++) {
for (i = 0; i < 2500; i++)
buffer[i] = 0;
nonce.v32[3] = i;
err_check(
srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) {
num_fail++;
}
}
}
#ifdef OPENSSL
{
printf("running stat_tests on AES-128-GCM, expecting success\n");
/* set buffer to cipher output */
for (i=0; i < 2500; i++) {
buffer[i] = 0;
}
err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c, SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for(j=0; j < num_trials; j++) {
for (i=0; i < 2500; i++) {
buffer[i] = 0;
}
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500;
if (stat_test_runs(buffer)) {
num_fail++;
}
}
{
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,
SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
err_check(srtp_cipher_init(c, key));
err_check(
srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for (j = 0; j < num_trials; j++) {
for (i = 0; i < 2500; i++) {
buffer[i] = 0;
}
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500;
if (stat_test_runs(buffer)) {
num_fail++;
}
}
printf("running stat_tests on AES-256-GCM, expecting success\n");
/* set buffer to cipher output */
for (i=0; i < 2500; i++) {
buffer[i] = 0;
printf("running stat_tests on AES-256-GCM, expecting success\n");
/* set buffer to cipher output */
for (i = 0; i < 2500; i++) {
buffer[i] = 0;
}
err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
err_check(srtp_cipher_init(c, key));
err_check(
srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for (j = 0; j < num_trials; j++) {
for (i = 0; i < 2500; i++) {
buffer[i] = 0;
}
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500;
if (stat_test_runs(buffer)) {
num_fail++;
}
}
}
err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c, SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
err_check(srtp_cipher_init(c, key));
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer));
printf("runs %d\n", stat_test_runs(buffer));
fflush(stdout);
num_fail = 0;
v128_set_to_zero(&nonce);
for(j=0; j < num_trials; j++) {
for (i=0; i < 2500; i++) {
buffer[i] = 0;
}
nonce.v32[3] = i;
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500;
if (stat_test_runs(buffer)) {
num_fail++;
}
}
}
#endif
printf("%d failures in %d tests\n", num_fail, num_trials);
printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n");
printf("%d failures in %d tests\n", num_fail, num_trials);
printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n");
err_check(srtp_cipher_dealloc(c));
err_check(srtp_cipher_dealloc(c));
return 0;
return 0;
}

Binary file not shown.

35
libs/srtp/format.sh Normal file
View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# format.sh
#
# run clang-format on each .c & .h file
#
# assumes git tree is clean when reporting status
if [ -z "${CLANG_FORMAT}" ]; then
CLANG_FORMAT=clang-format
fi
a=`git ls-files '*.h' '*.c'`
for x in $a; do
if [ $x != "config_in.h" ]; then
$CLANG_FORMAT -i -style=file $x
fi
done
m=`git ls-files -m`
if [ -n "$m" ]; then
v=`$CLANG_FORMAT -version`
echo "Fromatting required when checking with $v"
echo
echo "The following files required formatting:"
for f in $m; do
echo $f
done
if [ "$1" = "-d" ]; then
echo
git diff
fi
exit 1
fi
exit 0

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -42,15 +42,13 @@
*
*/
/*
* EKT implementation strategy
*
* EKT implementation strategy
*
* use stream_template approach
*
* in srtp_unprotect, when a new stream appears, check if template has
* EKT defined, and if it does, then apply EKT processing
* EKT defined, and if it does, then apply EKT processing
*
* question: will we want to allow key-sharing templates in addition
* to EKT templates? could define a new ssrc_type_t that's associated
@ -69,14 +67,13 @@
extern "C" {
#endif
#define SRTP_EKT_CIPHER_DEFAULT 1
#define SRTP_EKT_CIPHER_AES_128_ECB 1
#define SRTP_EKT_CIPHER_AES_192_KEY_WRAP 2
#define SRTP_EKT_CIPHER_AES_256_KEY_WRAP 3
#define SRTP_EKT_CIPHER_DEFAULT 1
#define SRTP_EKT_CIPHER_AES_128_ECB 1
#define SRTP_EKT_CIPHER_AES_192_KEY_WRAP 2
#define SRTP_EKT_CIPHER_AES_256_KEY_WRAP 3
typedef uint16_t srtp_ekt_spi_t;
unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt);
/*
@ -88,24 +85,23 @@ unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt);
*/
typedef struct srtp_ekt_policy_ctx_t {
srtp_ekt_spi_t spi; /* security parameter index */
uint8_t ekt_cipher_type;
uint8_t *ekt_key;
struct srtp_ekt_policy_ctx_t *next_ekt_policy;
srtp_ekt_spi_t spi; /* security parameter index */
uint8_t ekt_cipher_type;
uint8_t *ekt_key;
struct srtp_ekt_policy_ctx_t *next_ekt_policy;
} srtp_ekt_policy_ctx_t;
/*
* an srtp_ekt_data_t structure holds the data corresponding to an ekt key,
* spi, and so on
*/
typedef struct srtp_ekt_data_t {
srtp_ekt_spi_t spi;
uint8_t ekt_cipher_type;
srtp_aes_expanded_key_t ekt_enc_key;
srtp_aes_expanded_key_t ekt_dec_key;
struct ekt_data_t *next_ekt_data;
srtp_ekt_spi_t spi;
uint8_t ekt_cipher_type;
srtp_aes_expanded_key_t ekt_enc_key;
srtp_aes_expanded_key_t ekt_dec_key;
struct ekt_data_t *next_ekt_data;
} srtp_ekt_data_t;
/*
@ -116,25 +112,31 @@ typedef struct srtp_ekt_data_t {
*/
typedef struct srtp_ekt_stream_ctx_t {
srtp_ekt_data_t *data;
uint16_t isn; /* initial sequence number */
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
srtp_ekt_data_t *data;
uint16_t isn; /* initial sequence number */
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
} srtp_ekt_stream_ctx_t;
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data,
srtp_ekt_policy_t policy);
srtp_err_status_t srtp_ekt_stream_init(srtp_ekt_stream_t e,
srtp_ekt_spi_t spi,
void *ekt_key,
unsigned ekt_cipher_type);
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data, srtp_ekt_policy_t policy);
srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t e,
srtp_ekt_policy_t p);
srtp_err_status_t srtp_ekt_stream_init(srtp_ekt_stream_t e, srtp_ekt_spi_t spi, void *ekt_key, unsigned ekt_cipher_type);
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
const void *srtcp_hdr,
unsigned pkt_octet_len);
srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t e, srtp_ekt_policy_t p);
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream, const void *srtcp_hdr, unsigned pkt_octet_len);
void srtp_ekt_write_data(srtp_ekt_stream_t ekt, uint8_t *base_tag, unsigned base_tag_len, int *packet_len, srtp_xtd_seq_num_t pkt_index);
void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
uint8_t *base_tag,
unsigned base_tag_len,
int *packet_len,
srtp_xtd_seq_num_t pkt_index);
/*
* We handle EKT by performing some additional steps before
@ -144,10 +146,13 @@ void srtp_ekt_write_data(srtp_ekt_stream_t ekt, uint8_t *base_tag, unsigned base
* With EKT, the tag_len parameter is actually the base tag
* length
*/
srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag, uint8_t *pkt_tag_copy, unsigned tag_len);
srtp_err_status_t srtp_ekt_tag_verification_postproces(uint8_t *pkt_tag, uint8_t *pkt_tag_copy, unsigned tag_len);
srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag,
uint8_t *pkt_tag_copy,
unsigned tag_len);
srtp_err_status_t srtp_ekt_tag_verification_postproces(uint8_t *pkt_tag,
uint8_t *pkt_tag_copy,
unsigned tag_len);
/*
* @brief EKT pre-processing for srtcp tag generation
@ -157,16 +162,18 @@ srtp_err_status_t srtp_ekt_tag_verification_postproces(uint8_t *pkt_tag, uint8_t
* Master Key, the SRTP ROC, the Initial Sequence Number, and SPI
* fields. The Base Authentication Tag field is set to the all-zero
* value
*
*
* When EKT is not used, this function is a no-op.
*
*
*/
srtp_err_status_t srtp_stream_srtcp_auth_tag_generation_preprocess(const srtp_stream_t *s, uint8_t *pkt_tag, unsigned pkt_octet_len);
srtp_err_status_t srtp_stream_srtcp_auth_tag_generation_preprocess(
const srtp_stream_t *s,
uint8_t *pkt_tag,
unsigned pkt_octet_len);
/* it's not clear that a tag_generation_postprocess function is needed */
srtp_err_status_t srtcp_auth_tag_generation_postprocess(void);
#ifdef __cplusplus
}
#endif

View File

@ -7,26 +7,26 @@
*
*/
/*
*
*
* 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
@ -49,17 +49,16 @@
extern "C" {
#endif
/*
/*
* getopt_s(), optarg_s, and optind_s are small, locally defined
* versions of the POSIX standard getopt() interface.
*/
int
getopt_s(int argc, char * const argv[], const char *optstring);
extern char *optarg_s; /* defined in getopt.c */
int getopt_s(int argc, char *const argv[], const char *optstring);
extern int optind_s; /* defined in getopt.c */
extern char *optarg_s; /* defined in getopt.c */
extern int optind_s; /* defined in getopt.c */
#ifdef __cplusplus
}

View File

@ -1,139 +0,0 @@
/*
* rtp.h
*
* rtp interface for srtp reference implementation
*
* David A. McGrew
* Cisco Systems, Inc.
*
* data types:
*
* rtp_msg_t an rtp message (the data that goes on the wire)
* rtp_sender_t sender side socket and rtp info
* rtp_receiver_t receiver side socket and rtp info
*
*/
/*
*
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef RTP_H
#define RTP_H
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#elif defined HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#include "srtp.h"
typedef struct rtp_sender_ctx_t *rtp_sender_t;
typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
int
rtp_sendto(rtp_sender_t sender, const void* msg, int len);
int
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
int
rtp_receiver_init(rtp_receiver_t rcvr, int sock,
struct sockaddr_in addr, unsigned int ssrc);
int
rtp_sender_init(rtp_sender_t sender, int sock,
struct sockaddr_in addr, unsigned int ssrc);
/*
* srtp_sender_init(...) initializes an rtp_sender_t
*/
int
srtp_sender_init(rtp_sender_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int
srtp_receiver_init(rtp_receiver_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int
rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
int
rtp_sender_deinit_srtp(rtp_sender_t sender);
int
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
int
rtp_receiver_deinit_srtp(rtp_receiver_t sender);
rtp_sender_t
rtp_sender_alloc(void);
void
rtp_sender_dealloc(rtp_sender_t rtp_ctx);
rtp_receiver_t
rtp_receiver_alloc(void);
void
rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
/*
* RTP_HEADER_LEN indicates the size of an RTP header
*/
#define RTP_HEADER_LEN 12
/*
* RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
*/
#define RTP_MAX_BUF_LEN 16384
#endif /* RTP_H */

File diff suppressed because it is too large Load Diff

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -62,14 +62,14 @@
extern "C" {
#endif
#define SRTP_VER_STRING PACKAGE_STRING
#define SRTP_VERSION PACKAGE_VERSION
#define SRTP_VER_STRING PACKAGE_STRING
#define SRTP_VERSION PACKAGE_VERSION
typedef struct srtp_stream_ctx_t_ srtp_stream_ctx_t;
typedef srtp_stream_ctx_t *srtp_stream_t;
/*
* the following declarations are libSRTP internal functions
* the following declarations are libSRTP internal functions
*/
/*
@ -78,7 +78,6 @@ typedef srtp_stream_ctx_t *srtp_stream_t;
*/
srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
/*
* srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by
* deriving all of the needed keys using the KDF and the key k.
@ -88,29 +87,29 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
const unsigned int current_mki_index);
/*
* srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s by
* deriving all of the needed keys for all the master keys using the KDF and the keys from k.
* srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s
* by deriving all of the needed keys for all the master keys using the KDF and
* the keys from k.
*/
srtp_err_status_t srtp_steam_init_all_master_keys(srtp_stream_ctx_t *srtp,
unsigned char *key,
srtp_master_key_t **keys,
const unsigned int max_master_keys);
srtp_err_status_t srtp_steam_init_all_master_keys(
srtp_stream_ctx_t *srtp,
unsigned char *key,
srtp_master_key_t **keys,
const unsigned int max_master_keys);
/*
* srtp_stream_init(s, p) initializes the srtp_stream_t s to
* srtp_stream_init(s, p) initializes the srtp_stream_t s to
* use the policy at the location p
*/
srtp_err_status_t srtp_stream_init(srtp_stream_t srtp, const srtp_policy_t *p);
/*
* libsrtp internal datatypes
* libsrtp internal datatypes
*/
typedef enum direction_t {
dir_unknown = 0,
dir_srtp_sender = 1,
dir_srtp_receiver = 2
typedef enum direction_t {
dir_unknown = 0,
dir_srtp_sender = 1,
dir_srtp_receiver = 2
} direction_t;
/*
@ -119,56 +118,52 @@ typedef enum direction_t {
* MKI ID which is used to identify the session keys.
*/
typedef struct srtp_session_keys_t {
srtp_cipher_t *rtp_cipher;
srtp_cipher_t *rtp_xtn_hdr_cipher;
srtp_auth_t *rtp_auth;
srtp_cipher_t *rtcp_cipher;
srtp_auth_t *rtcp_auth;
uint8_t salt[SRTP_AEAD_SALT_LEN];
uint8_t c_salt[SRTP_AEAD_SALT_LEN];
uint8_t *mki_id;
unsigned int mki_size;
srtp_key_limit_ctx_t *limit;
srtp_cipher_t *rtp_cipher;
srtp_cipher_t *rtp_xtn_hdr_cipher;
srtp_auth_t *rtp_auth;
srtp_cipher_t *rtcp_cipher;
srtp_auth_t *rtcp_auth;
uint8_t salt[SRTP_AEAD_SALT_LEN];
uint8_t c_salt[SRTP_AEAD_SALT_LEN];
uint8_t *mki_id;
unsigned int mki_size;
srtp_key_limit_ctx_t *limit;
} srtp_session_keys_t;
/*
/*
* an srtp_stream_t has its own SSRC, encryption key, authentication
* key, sequence number, and replay database
*
*
* note that the keys might not actually be unique, in which case the
* srtp_cipher_t and srtp_auth_t pointers will point to the same structures
*/
typedef struct srtp_stream_ctx_t_ {
uint32_t ssrc;
srtp_session_keys_t *session_keys;
unsigned int num_master_keys;
srtp_rdbx_t rtp_rdbx;
srtp_sec_serv_t rtp_services;
srtp_rdb_t rtcp_rdb;
srtp_sec_serv_t rtcp_services;
direction_t direction;
int allow_repeat_tx;
srtp_ekt_stream_t ekt;
int *enc_xtn_hdr;
int enc_xtn_hdr_count;
uint32_t pending_roc;
struct srtp_stream_ctx_t_ *next; /* linked list of streams */
uint32_t ssrc;
srtp_session_keys_t *session_keys;
unsigned int num_master_keys;
srtp_rdbx_t rtp_rdbx;
srtp_sec_serv_t rtp_services;
srtp_rdb_t rtcp_rdb;
srtp_sec_serv_t rtcp_services;
direction_t direction;
int allow_repeat_tx;
srtp_ekt_stream_t ekt;
int *enc_xtn_hdr;
int enc_xtn_hdr_count;
uint32_t pending_roc;
struct srtp_stream_ctx_t_ *next; /* linked list of streams */
} strp_stream_ctx_t_;
/*
* an srtp_ctx_t holds a stream list and a service description
*/
typedef struct srtp_ctx_t_ {
struct srtp_stream_ctx_t_ *stream_list; /* linked list of streams */
struct srtp_stream_ctx_t_ *stream_template; /* act as template for other streams */
void *user_data; /* user custom data */
struct srtp_stream_ctx_t_ *stream_list; /* linked list of streams */
struct srtp_stream_ctx_t_ *stream_template; /* act as template for other */
/* streams */
void *user_data; /* user custom data */
} srtp_ctx_t_;
/*
* srtp_hdr_t represents an RTP or SRTP header. The bit-fields in
* this structure should be declared "unsigned int" instead of
@ -181,10 +176,6 @@ typedef struct srtp_ctx_t_ {
* is not identical)
*/
#ifdef _MSC_VER
#pragma pack(push, r1, 1)
#endif
#ifndef WORDS_BIGENDIAN
typedef struct {
@ -194,9 +185,9 @@ typedef struct {
unsigned version : 2; /* protocol version */
unsigned pt : 7; /* payload type */
unsigned m : 1; /* marker bit */
unsigned seq : 16; /* sequence number */
unsigned ts : 32; /* timestamp */
uint32_t ssrc; /* synchronization source */
uint16_t seq; /* sequence number */
uint32_t ts; /* timestamp */
uint32_t ssrc; /* synchronization source */
} srtp_hdr_t;
#else /* BIG_ENDIAN */
@ -208,19 +199,18 @@ typedef struct {
unsigned cc : 4; /* CSRC count */
unsigned m : 1; /* marker bit */
unsigned pt : 7; /* payload type */
unsigned seq: 16; /* sequence number */
unsigned ts : 32; /* timestamp */
uint32_t ssrc; /* synchronization source */
uint16_t seq; /* sequence number */
uint32_t ts; /* timestamp */
uint32_t ssrc; /* synchronization source */
} srtp_hdr_t;
#endif
typedef struct {
uint16_t profile_specific; /* profile-specific info */
uint16_t length; /* number of 32-bit words in extension */
uint16_t profile_specific; /* profile-specific info */
uint16_t length; /* number of 32-bit words in extension */
} srtp_hdr_xtnd_t;
/*
* srtcp_hdr_t represents a secure rtcp header
*
@ -231,61 +221,57 @@ typedef struct {
#ifndef WORDS_BIGENDIAN
typedef struct {
unsigned rc : 5; /* reception report count */
unsigned p : 1; /* padding flag */
unsigned version : 2; /* protocol version */
unsigned pt : 8; /* payload type */
unsigned len : 16; /* length */
unsigned rc : 5; /* reception report count */
unsigned p : 1; /* padding flag */
unsigned version : 2; /* protocol version */
unsigned pt : 8; /* payload type */
uint16_t len; /* length */
uint32_t ssrc; /* synchronization source */
} srtcp_hdr_t;
typedef struct {
unsigned int index : 31; /* srtcp packet index in network order! */
unsigned int e : 1; /* encrypted? 1=yes */
/* optional mikey/etc go here */
/* and then the variable-length auth tag */
unsigned int index : 31; /* srtcp packet index in network order! */
unsigned int e : 1; /* encrypted? 1=yes */
/* optional mikey/etc go here */
/* and then the variable-length auth tag */
} srtcp_trailer_t;
#else /* BIG_ENDIAN */
typedef struct {
unsigned version : 2; /* protocol version */
unsigned p : 1; /* padding flag */
unsigned rc : 5; /* reception report count */
unsigned pt : 8; /* payload type */
unsigned len : 16; /* length */
unsigned version : 2; /* protocol version */
unsigned p : 1; /* padding flag */
unsigned rc : 5; /* reception report count */
unsigned pt : 8; /* payload type */
uint16_t len; /* length */
uint32_t ssrc; /* synchronization source */
} srtcp_hdr_t;
typedef struct {
unsigned int e : 1; /* encrypted? 1=yes */
unsigned int index : 31; /* srtcp packet index */
/* optional mikey/etc go here */
/* and then the variable-length auth tag */
unsigned int e : 1; /* encrypted? 1=yes */
unsigned int index : 31; /* srtcp packet index */
/* optional mikey/etc go here */
/* and then the variable-length auth tag */
} srtcp_trailer_t;
#endif
#ifdef _MSC_VER
#pragma pack(pop, r1)
#endif
/*
* srtp_handle_event(srtp, srtm, evnt) calls the event handling
* function, if there is one.
*
* This macro is not included in the documentation as it is
* This macro is not included in the documentation as it is
* an internal-only function.
*/
#define srtp_handle_event(srtp, strm, evnt) \
if(srtp_event_handler) { \
srtp_event_data_t data; \
data.session = srtp; \
data.ssrc = ntohl(strm->ssrc); \
data.event = evnt; \
srtp_event_handler(&data); \
}
#define srtp_handle_event(srtp, strm, evnt) \
if (srtp_event_handler) { \
srtp_event_data_t data; \
data.session = srtp; \
data.ssrc = ntohl(strm->ssrc); \
data.event = evnt; \
srtp_event_handler(&data); \
}
#ifdef __cplusplus
}

View File

@ -9,26 +9,26 @@
*/
/*
*
*
* 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
@ -44,41 +44,37 @@
*
*/
#ifndef UT_SIM_H
#define UT_SIM_H
#include "integers.h" /* for uint32_t */
#include "integers.h" /* for uint32_t */
#ifdef __cplusplus
extern "C" {
#endif
#define UT_BUF 160 /* maximum amount of packet reorder */
#define UT_BUF 160 /* maximum amount of packet reorder */
typedef struct {
uint32_t index;
uint32_t buffer[UT_BUF];
uint32_t index;
uint32_t buffer[UT_BUF];
} ut_connection;
/*
* ut_init(&u) initializes the ut_connection
* ut_init(&u) initializes the ut_connection
*
* this function should always be the first one called on a new
* ut_connection
*/
void
ut_init(ut_connection *utc);
void ut_init(ut_connection *utc);
/*
* ut_next_index(&u) returns the next index from the simulated
* unreliable connection
*/
uint32_t
ut_next_index(ut_connection *utc);
uint32_t ut_next_index(ut_connection *utc);
#ifdef __cplusplus
}

View File

@ -392,6 +392,7 @@
<ClInclude Include="crypto\include\alloc.h" />
<ClInclude Include="crypto\include\auth.h" />
<ClInclude Include="crypto\include\cipher.h" />
<ClInclude Include="crypto\include\cipher_types.h" />
<ClInclude Include="crypto\include\config.h" />
<ClInclude Include="crypto\include\crypto_kernel.h" />
<ClInclude Include="crypto\include\crypto_types.h" />

View File

@ -1,10 +0,0 @@
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
includedir = @includedir@
Name: srtp
Description: Secure RTP (SRTP) and UST Reference Implementations
Version: @VERSION@
Libs: -L${libdir} -lsrtp.so
Cflags: -I${includedir}/srtp

View File

@ -2,31 +2,31 @@
* ekt.c
*
* Encrypted Key Transport for SRTP
*
*
* David McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -42,7 +42,6 @@
*
*/
#include "srtp_priv.h"
#include "err.h"
#include "ekt.h"
@ -64,195 +63,219 @@ extern srtp_debug_module_t mod_srtp;
* | Initial Sequence Number | Security Parameter Index |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
*/
#define EKT_OCTETS_AFTER_BASE_TAG 24
#define EKT_OCTETS_AFTER_EMK 8
#define EKT_OCTETS_AFTER_ROC 4
#define EKT_SPI_LEN 2
#define EKT_OCTETS_AFTER_EMK 8
#define EKT_OCTETS_AFTER_ROC 4
#define EKT_SPI_LEN 2
unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt) {
/*
* if the pointer ekt is NULL, then EKT is not in effect, so we
* indicate this by returning zero
*/
if (!ekt)
unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt)
{
/*
* if the pointer ekt is NULL, then EKT is not in effect, so we
* indicate this by returning zero
*/
if (!ekt)
return 0;
switch (ekt->data->ekt_cipher_type) {
case SRTP_EKT_CIPHER_AES_128_ECB:
return 16 + EKT_OCTETS_AFTER_EMK;
break;
default:
break;
}
return 0;
switch(ekt->data->ekt_cipher_type) {
case SRTP_EKT_CIPHER_AES_128_ECB:
return 16 + EKT_OCTETS_AFTER_EMK;
break;
default:
break;
}
return 0;
}
static inline srtp_ekt_spi_t srtcp_packet_get_ekt_spi(const uint8_t *packet_start, unsigned pkt_octet_len) {
const uint8_t *spi_location;
spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
return *((const srtp_ekt_spi_t *)spi_location);
static inline srtp_ekt_spi_t srtcp_packet_get_ekt_spi(
const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *spi_location;
spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
return *((const srtp_ekt_spi_t *)spi_location);
}
static inline uint32_t srtcp_packet_get_ekt_roc(const uint8_t *packet_start, unsigned pkt_octet_len) {
const uint8_t *roc_location;
roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
return *((const uint32_t *)roc_location);
static inline uint32_t srtcp_packet_get_ekt_roc(const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *roc_location;
roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
return *((const uint32_t *)roc_location);
}
static inline const uint8_t * srtcp_packet_get_emk_location(const uint8_t *packet_start, unsigned pkt_octet_len) {
const uint8_t *location;
location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
static inline const uint8_t *srtcp_packet_get_emk_location(
const uint8_t *packet_start,
unsigned pkt_octet_len)
{
const uint8_t *location;
return location;
location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
return location;
}
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data,
srtp_ekt_policy_t policy)
{
/*
* if the policy pointer is NULL, then EKT is not in use
* so we just set the EKT stream data pointer to NULL
*/
if (!policy) {
*stream_data = NULL;
return srtp_err_status_ok;
}
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data, srtp_ekt_policy_t policy) {
/*
* if the policy pointer is NULL, then EKT is not in use
* so we just set the EKT stream data pointer to NULL
*/
if (!policy) {
/* TODO */
*stream_data = NULL;
return srtp_err_status_ok;
}
/* TODO */
*stream_data = NULL;
return srtp_err_status_ok;
}
srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t stream_data, srtp_ekt_policy_t policy) {
if (!stream_data)
return srtp_err_status_ok;
srtp_err_status_t srtp_ekt_stream_init_from_policy(
srtp_ekt_stream_t stream_data,
srtp_ekt_policy_t policy)
{
if (!stream_data)
return srtp_err_status_ok;
return srtp_err_status_ok;
return srtp_err_status_ok;
}
void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len) {
void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len)
{
#ifndef OPENSSL
//FIXME: need to get this working through the crypto module interface
srtp_aes_expanded_key_t expanded_key;
// FIXME: need to get this working through the crypto module interface
srtp_aes_expanded_key_t expanded_key;
srtp_aes_expand_decryption_key(key, key_len, &expanded_key);
srtp_aes_decrypt(ciphertext, &expanded_key);
srtp_aes_expand_decryption_key(key, key_len, &expanded_key);
srtp_aes_decrypt(ciphertext, &expanded_key);
#endif
}
/*
* The function srtp_stream_init_from_ekt() initializes a stream using
* the EKT data from an SRTCP trailer.
* the EKT data from an SRTCP trailer.
*/
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream, const void *srtcp_hdr, unsigned pkt_octet_len) {
srtp_err_status_t err;
const uint8_t *master_key;
srtp_policy_t srtp_policy;
uint32_t roc;
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
const void *srtcp_hdr,
unsigned pkt_octet_len)
{
srtp_err_status_t err;
const uint8_t *master_key;
srtp_policy_t srtp_policy;
uint32_t roc;
/*
* NOTE: at present, we only support a single ekt_policy at a time.
*/
if (stream->ekt->data->spi !=
srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
return srtp_err_status_no_ctx;
/*
* NOTE: at present, we only support a single ekt_policy at a time.
*/
if (stream->ekt->data->spi !=
srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
return srtp_err_status_no_ctx;
if (stream->ekt->data->ekt_cipher_type != SRTP_EKT_CIPHER_AES_128_ECB)
return srtp_err_status_bad_param;
if (stream->ekt->data->ekt_cipher_type != SRTP_EKT_CIPHER_AES_128_ECB)
return srtp_err_status_bad_param;
/* decrypt the Encrypted Master Key field */
master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
/* FIX!? This decrypts the master key in-place, and never uses it */
/* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
* to a function which expects a raw (unexpanded) key */
aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16);
/* decrypt the Encrypted Master Key field */
master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
/* FIX!? This decrypts the master key in-place, and never uses it */
/* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
* to a function which expects a raw (unexpanded) key */
aes_decrypt_with_raw_key((void *)master_key,
&stream->ekt->data->ekt_dec_key, 16);
/* set the SRTP ROC */
roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
err = srtp_rdbx_set_roc(&stream->rtp_rdbx, roc);
if (err) return err;
/* set the SRTP ROC */
roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
err = srtp_rdbx_set_roc(&stream->rtp_rdbx, roc);
if (err)
return err;
err = srtp_stream_init(stream, &srtp_policy);
if (err) return err;
err = srtp_stream_init(stream, &srtp_policy);
if (err)
return err;
return srtp_err_status_ok;
return srtp_err_status_ok;
}
void srtp_ekt_write_data(srtp_ekt_stream_t ekt, uint8_t *base_tag, unsigned base_tag_len, int *packet_len, srtp_xtd_seq_num_t pkt_index) {
uint32_t roc;
uint16_t isn;
unsigned emk_len;
uint8_t *packet;
void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
uint8_t *base_tag,
unsigned base_tag_len,
int *packet_len,
srtp_xtd_seq_num_t pkt_index)
{
uint32_t roc;
uint16_t isn;
unsigned emk_len;
uint8_t *packet;
/* if the pointer ekt is NULL, then EKT is not in effect */
if (!ekt) {
debug_print(mod_srtp, "EKT not in use", NULL);
return;
}
/* if the pointer ekt is NULL, then EKT is not in effect */
if (!ekt) {
debug_print(mod_srtp, "EKT not in use", NULL);
return;
}
/* write zeros into the location of the base tag */
octet_string_set_to_zero(base_tag, base_tag_len);
packet = base_tag + base_tag_len;
/* write zeros into the location of the base tag */
octet_string_set_to_zero(base_tag, base_tag_len);
packet = base_tag + base_tag_len;
/* copy encrypted master key into packet */
emk_len = srtp_ekt_octets_after_base_tag(ekt);
memcpy(packet, ekt->encrypted_master_key, emk_len);
debug_print(mod_srtp, "writing EKT EMK: %s,",
srtp_octet_string_hex_string(packet, emk_len));
packet += emk_len;
/* copy encrypted master key into packet */
emk_len = srtp_ekt_octets_after_base_tag(ekt);
memcpy(packet, ekt->encrypted_master_key, emk_len);
debug_print(mod_srtp, "writing EKT EMK: %s,",
srtp_octet_string_hex_string(packet, emk_len));
packet += emk_len;
/* copy ROC into packet */
roc = (uint32_t)(pkt_index >> 16);
*((uint32_t *)packet) = be32_to_cpu(roc);
debug_print(mod_srtp, "writing EKT ROC: %s,",
srtp_octet_string_hex_string(packet, sizeof(roc)));
packet += sizeof(roc);
/* copy ROC into packet */
roc = (uint32_t)(pkt_index >> 16);
*((uint32_t *)packet) = be32_to_cpu(roc);
debug_print(mod_srtp, "writing EKT ROC: %s,",
srtp_octet_string_hex_string(packet, sizeof(roc)));
packet += sizeof(roc);
/* copy ISN into packet */
isn = (uint16_t)pkt_index;
*((uint16_t *)packet) = htons(isn);
debug_print(mod_srtp, "writing EKT ISN: %s,",
srtp_octet_string_hex_string(packet, sizeof(isn)));
packet += sizeof(isn);
/* copy ISN into packet */
isn = (uint16_t)pkt_index;
*((uint16_t *)packet) = htons(isn);
debug_print(mod_srtp, "writing EKT ISN: %s,",
srtp_octet_string_hex_string(packet, sizeof(isn)));
packet += sizeof(isn);
/* copy SPI into packet */
*((uint16_t *)packet) = htons(ekt->data->spi);
debug_print(mod_srtp, "writing EKT SPI: %s,",
srtp_octet_string_hex_string(packet, sizeof(ekt->data->spi)));
/* copy SPI into packet */
*((uint16_t *)packet) = htons(ekt->data->spi);
debug_print(mod_srtp, "writing EKT SPI: %s,",
srtp_octet_string_hex_string(packet, sizeof(ekt->data->spi)));
/* increase packet length appropriately */
*packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
/* increase packet length appropriately */
*packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
}
/*
* The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag )
*
*
* If the pointer ekt is NULL, then the other inputs are unaffected.
*
* auth_tag is a pointer to the pointer to the location of the
* authentication tag in the packet. If EKT is in effect, then the
* auth_tag pointer is set to the location
* auth_tag pointer is set to the location
*/
void srtcp_ekt_trailer(srtp_ekt_stream_t ekt, unsigned *auth_len, void **auth_tag, void *tag_copy) {
/*
* if there is no EKT policy, then the other inputs are unaffected
*/
if (!ekt)
return;
/* copy auth_tag into temporary location */
}
void srtcp_ekt_trailer(srtp_ekt_stream_t ekt,
unsigned *auth_len,
void **auth_tag,
void *tag_copy)
{
/*
* if there is no EKT policy, then the other inputs are unaffected
*/
if (!ekt)
return;
/* copy auth_tag into temporary location */
}

File diff suppressed because it is too large Load Diff

View File

@ -370,6 +370,7 @@
<ClInclude Include="crypto\include\alloc.h" />
<ClInclude Include="crypto\include\auth.h" />
<ClInclude Include="crypto\include\cipher.h" />
<ClInclude Include="crypto\include\cipher_types.h" />
<ClInclude Include="crypto\include\config.h" />
<ClInclude Include="crypto\include\crypto.h" />
<ClInclude Include="crypto\include\cryptoalg.h" />
@ -401,4 +402,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -107,6 +107,9 @@
<ClInclude Include="crypto\include\cipher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="crypto\include\cipher_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="crypto\include\config.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -183,4 +186,4 @@
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
</Project>

View File

@ -10,10 +10,10 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -26,7 +26,6 @@
#ifndef CUTEST_H__
#define CUTEST_H__
/************************
*** Public interface ***
************************/
@ -56,8 +55,7 @@
*
* void test_func(void);
*/
#define TEST_LIST const struct test__ test_list__[]
#define TEST_LIST const struct test__ test_list__[]
/* Macros for testing whether an unit test succeeds or fails. These macros
* can be used arbitrarily in functions implementing the unit tests.
@ -78,9 +76,9 @@
* TEST_CHECK(ptr->member2 > 200);
* }
*/
#define TEST_CHECK_(cond,...) test_check__((cond), __FILE__, __LINE__, __VA_ARGS__)
#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, "%s", #cond)
#define TEST_CHECK_(cond, ...) \
test_check__((cond), __FILE__, __LINE__, __VA_ARGS__)
#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, "%s", #cond)
/**********************
*** Implementation ***
@ -94,47 +92,43 @@
#include <string.h>
#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
#define CUTEST_UNIX__ 1
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#define CUTEST_UNIX__ 1
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#endif
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define CUTEST_WIN__ 1
#include <windows.h>
#include <io.h>
#define CUTEST_WIN__ 1
#include <windows.h>
#include <io.h>
#endif
#ifdef __cplusplus
#include <exception>
#include <exception>
#endif
/* Note our global private identifiers end with '__' to mitigate risk of clash
* with the unit tests implementation. */
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
struct test__ {
const char* name;
const char *name;
void (*func)(void);
};
extern const struct test__ test_list__[];
int test_check__(int cond, const char* file, int line, const char* fmt, ...);
int test_check__(int cond, const char *file, int line, const char *fmt, ...);
#ifndef TEST_NO_MAIN
static char* test_argv0__ = NULL;
static char *test_argv0__ = NULL;
static int test_count__ = 0;
static int test_no_exec__ = 0;
static int test_no_summary__ = 0;
@ -143,21 +137,20 @@ static int test_skip_mode__ = 0;
static int test_stat_failed_units__ = 0;
static int test_stat_run_units__ = 0;
static const struct test__* test_current_unit__ = NULL;
static const struct test__ *test_current_unit__ = NULL;
static int test_current_already_logged__ = 0;
static int test_verbose_level__ = 2;
static int test_current_failures__ = 0;
static int test_colorize__ = 0;
#define CUTEST_COLOR_DEFAULT__ 0
#define CUTEST_COLOR_GREEN__ 1
#define CUTEST_COLOR_RED__ 2
#define CUTEST_COLOR_DEFAULT_INTENSIVE__ 3
#define CUTEST_COLOR_GREEN_INTENSIVE__ 4
#define CUTEST_COLOR_RED_INTENSIVE__ 5
#define CUTEST_COLOR_DEFAULT__ 0
#define CUTEST_COLOR_GREEN__ 1
#define CUTEST_COLOR_RED__ 2
#define CUTEST_COLOR_DEFAULT_INTENSIVE__ 3
#define CUTEST_COLOR_GREEN_INTENSIVE__ 4
#define CUTEST_COLOR_RED_INTENSIVE__ 5
static size_t
test_print_in_color__(int color, const char* fmt, ...)
static size_t test_print_in_color__(int color, const char *fmt, ...)
{
va_list args;
char buffer[256];
@ -166,22 +159,34 @@ test_print_in_color__(int color, const char* fmt, ...)
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
buffer[sizeof(buffer)-1] = '\0';
buffer[sizeof(buffer) - 1] = '\0';
if(!test_colorize__) {
if (!test_colorize__) {
return printf("%s", buffer);
}
#if defined CUTEST_UNIX__
{
const char* col_str;
switch(color) {
case CUTEST_COLOR_GREEN__: col_str = "\033[0;32m"; break;
case CUTEST_COLOR_RED__: col_str = "\033[0;31m"; break;
case CUTEST_COLOR_GREEN_INTENSIVE__: col_str = "\033[1;32m"; break;
case CUTEST_COLOR_RED_INTENSIVE__: col_str = "\033[1;30m"; break;
case CUTEST_COLOR_DEFAULT_INTENSIVE__: col_str = "\033[1m"; break;
default: col_str = "\033[0m"; break;
const char *col_str;
switch (color) {
case CUTEST_COLOR_GREEN__:
col_str = "\033[0;32m";
break;
case CUTEST_COLOR_RED__:
col_str = "\033[0;31m";
break;
case CUTEST_COLOR_GREEN_INTENSIVE__:
col_str = "\033[1;32m";
break;
case CUTEST_COLOR_RED_INTENSIVE__:
col_str = "\033[1;30m";
break;
case CUTEST_COLOR_DEFAULT_INTENSIVE__:
col_str = "\033[1m";
break;
default:
col_str = "\033[0m";
break;
}
printf("%s", col_str);
n = printf("%s", buffer);
@ -197,15 +202,28 @@ test_print_in_color__(int color, const char* fmt, ...)
h = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(h, &info);
switch(color) {
case CUTEST_COLOR_GREEN__: attr = FOREGROUND_GREEN; break;
case CUTEST_COLOR_RED__: attr = FOREGROUND_RED; break;
case CUTEST_COLOR_GREEN_INTENSIVE__: attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; break;
case CUTEST_COLOR_RED_INTENSIVE__: attr = FOREGROUND_RED | FOREGROUND_INTENSITY; break;
case CUTEST_COLOR_DEFAULT_INTENSIVE__: attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; break;
default: attr = 0; break;
switch (color) {
case CUTEST_COLOR_GREEN__:
attr = FOREGROUND_GREEN;
break;
case CUTEST_COLOR_RED__:
attr = FOREGROUND_RED;
break;
case CUTEST_COLOR_GREEN_INTENSIVE__:
attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case CUTEST_COLOR_RED_INTENSIVE__:
attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
break;
case CUTEST_COLOR_DEFAULT_INTENSIVE__:
attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED |
FOREGROUND_INTENSITY;
break;
default:
attr = 0;
break;
}
if(attr != 0)
if (attr != 0)
SetConsoleTextAttribute(h, attr);
n = printf("%s", buffer);
SetConsoleTextAttribute(h, info.wAttributes);
@ -217,19 +235,18 @@ test_print_in_color__(int color, const char* fmt, ...)
#endif
}
int
test_check__(int cond, const char* file, int line, const char* fmt, ...)
int test_check__(int cond, const char *file, int line, const char *fmt, ...)
{
const char *result_str;
int result_color;
int verbose_level;
if(cond) {
if (cond) {
result_str = "ok";
result_color = CUTEST_COLOR_GREEN__;
verbose_level = 3;
} else {
if(!test_current_already_logged__ && test_current_unit__ != NULL) {
if (!test_current_already_logged__ && test_current_unit__ != NULL) {
printf("[ ");
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
printf(" ]\n");
@ -241,13 +258,13 @@ test_check__(int cond, const char* file, int line, const char* fmt, ...)
test_current_already_logged__++;
}
if(test_verbose_level__ >= verbose_level) {
if (test_verbose_level__ >= verbose_level) {
size_t n = 0;
va_list args;
printf(" ");
if(file != NULL)
if (file != NULL)
n += printf("%s:%d: Check ", file, line);
va_start(args, fmt);
@ -263,23 +280,21 @@ test_check__(int cond, const char* file, int line, const char* fmt, ...)
return (cond != 0);
}
static void
test_list_names__(void)
static void test_list_names__(void)
{
const struct test__* test;
const struct test__ *test;
printf("Unit tests:\n");
for(test = &test_list__[0]; test->func != NULL; test++)
for (test = &test_list__[0]; test->func != NULL; test++)
printf(" %s\n", test->name);
}
static const struct test__*
test_by_name__(const char* name)
static const struct test__ *test_by_name__(const char *name)
{
const struct test__* test;
const struct test__ *test;
for(test = &test_list__[0]; test->func != NULL; test++) {
if(strcmp(test->name, name) == 0)
for (test = &test_list__[0]; test->func != NULL; test++) {
if (strcmp(test->name, name) == 0)
return test;
}
@ -287,24 +302,25 @@ test_by_name__(const char* name)
}
/* Call directly the given test unit function. */
static int
test_do_run__(const struct test__* test)
static int test_do_run__(const struct test__ *test)
{
test_current_unit__ = test;
test_current_failures__ = 0;
test_current_already_logged__ = 0;
if(test_verbose_level__ >= 3) {
test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s:\n", test->name);
if (test_verbose_level__ >= 3) {
test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s:\n",
test->name);
test_current_already_logged__++;
} else if(test_verbose_level__ >= 1) {
} else if (test_verbose_level__ >= 1) {
size_t n;
char spaces[32];
n = test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s... ", test->name);
n = test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__,
"Test %s... ", test->name);
memset(spaces, ' ', sizeof(spaces));
if(n < sizeof(spaces))
printf("%.*s", (int) (sizeof(spaces) - n), spaces);
if (n < sizeof(spaces))
printf("%.*s", (int)(sizeof(spaces) - n), spaces);
} else {
test_current_already_logged__ = 1;
}
@ -320,24 +336,34 @@ test_do_run__(const struct test__* test)
test->func();
#ifdef __cplusplus
} catch(std::exception& e) {
const char* what = e.what();
if(what != NULL)
} catch (std::exception &e) {
const char *what = e.what();
if (what != NULL)
test_check__(0, NULL, 0, "Threw std::exception: %s", what);
else
test_check__(0, NULL, 0, "Threw std::exception");
} catch(...) {
} catch (...) {
test_check__(0, NULL, 0, "Threw an exception");
}
#endif
if(test_verbose_level__ >= 3) {
switch(test_current_failures__) {
case 0: test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__, " All conditions have passed.\n\n"); break;
case 1: test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, " One condition has FAILED.\n\n"); break;
default: test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, " %d conditions have FAILED.\n\n", test_current_failures__); break;
if (test_verbose_level__ >= 3) {
switch (test_current_failures__) {
case 0:
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
" All conditions have passed.\n\n");
break;
case 1:
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
" One condition has FAILED.\n\n");
break;
default:
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
" %d conditions have FAILED.\n\n",
test_current_failures__);
break;
}
} else if(test_verbose_level__ >= 1 && test_current_failures__ == 0) {
} else if (test_verbose_level__ >= 1 && test_current_failures__ == 0) {
printf("[ ");
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__, "OK");
printf(" ]\n");
@ -351,21 +377,21 @@ test_do_run__(const struct test__* test)
/* Called if anything goes bad in cutest, or if the unit test ends in other
* way then by normal returning from its function (e.g. exception or some
* abnormal child process termination). */
static void
test_error__(const char* fmt, ...)
static void test_error__(const char *fmt, ...)
{
va_list args;
if(test_verbose_level__ == 0)
if (test_verbose_level__ == 0)
return;
if(test_verbose_level__ <= 2 && !test_current_already_logged__ && test_current_unit__ != NULL) {
if (test_verbose_level__ <= 2 && !test_current_already_logged__ &&
test_current_unit__ != NULL) {
printf("[ ");
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
printf(" ]\n");
}
if(test_verbose_level__ >= 2) {
if (test_verbose_level__ >= 2) {
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, " Error: ");
va_start(args, fmt);
vprintf(fmt, args);
@ -378,51 +404,73 @@ test_error__(const char* fmt, ...)
/* Trigger the unit test. If possible (and not suppressed) it starts a child
* process who calls test_do_run__(), otherwise it calls test_do_run__()
* directly. */
static void
test_run__(const struct test__* test)
static void test_run__(const struct test__ *test)
{
int failed = 1;
test_current_unit__ = test;
test_current_already_logged__ = 0;
if(!test_no_exec__) {
if (!test_no_exec__) {
#if defined(CUTEST_UNIX__)
pid_t pid;
int exit_code;
pid = fork();
if(pid == (pid_t)-1) {
if (pid == (pid_t)-1) {
test_error__("Cannot fork. %s [%d]", strerror(errno), errno);
failed = 1;
} else if(pid == 0) {
} else if (pid == 0) {
/* Child: Do the test. */
failed = (test_do_run__(test) != 0);
exit(failed ? 1 : 0);
} else {
/* Parent: Wait until child terminates and analyze its exit code. */
waitpid(pid, &exit_code, 0);
if(WIFEXITED(exit_code)) {
switch(WEXITSTATUS(exit_code)) {
case 0: failed = 0; break; /* test has passed. */
case 1: /* noop */ break; /* "normal" failure. */
default: test_error__("Unexpected exit code [%d]", WEXITSTATUS(exit_code));
if (WIFEXITED(exit_code)) {
switch (WEXITSTATUS(exit_code)) {
case 0:
failed = 0;
break; /* test has passed. */
case 1: /* noop */
break; /* "normal" failure. */
default:
test_error__("Unexpected exit code [%d]",
WEXITSTATUS(exit_code));
}
} else if(WIFSIGNALED(exit_code)) {
} else if (WIFSIGNALED(exit_code)) {
char tmp[32];
const char* signame;
switch(WTERMSIG(exit_code)) {
case SIGINT: signame = "SIGINT"; break;
case SIGHUP: signame = "SIGHUP"; break;
case SIGQUIT: signame = "SIGQUIT"; break;
case SIGABRT: signame = "SIGABRT"; break;
case SIGKILL: signame = "SIGKILL"; break;
case SIGSEGV: signame = "SIGSEGV"; break;
case SIGILL: signame = "SIGILL"; break;
case SIGTERM: signame = "SIGTERM"; break;
default: sprintf(tmp, "signal %d", WTERMSIG(exit_code)); signame = tmp; break;
const char *signame;
switch (WTERMSIG(exit_code)) {
case SIGINT:
signame = "SIGINT";
break;
case SIGHUP:
signame = "SIGHUP";
break;
case SIGQUIT:
signame = "SIGQUIT";
break;
case SIGABRT:
signame = "SIGABRT";
break;
case SIGKILL:
signame = "SIGKILL";
break;
case SIGSEGV:
signame = "SIGSEGV";
break;
case SIGILL:
signame = "SIGILL";
break;
case SIGTERM:
signame = "SIGTERM";
break;
default:
sprintf(tmp, "signal %d", WTERMSIG(exit_code));
signame = tmp;
break;
}
test_error__("Test interrupted by %s", signame);
} else {
@ -432,26 +480,28 @@ test_run__(const struct test__* test)
#elif defined(CUTEST_WIN__)
char buffer[512] = {0};
STARTUPINFOA startupInfo = {0};
char buffer[512] = { 0 };
STARTUPINFOA startupInfo = { 0 };
PROCESS_INFORMATION processInfo;
DWORD exitCode;
/* Windows has no fork(). So we propagate all info into the child
* through a command line arguments. */
_snprintf(buffer, sizeof(buffer)-1,
"%s --no-exec --no-summary --verbose=%d --color=%s -- \"%s\"",
test_argv0__, test_verbose_level__,
test_colorize__ ? "always" : "never", test->name);
_snprintf(buffer, sizeof(buffer) - 1,
"%s --no-exec --no-summary --verbose=%d --color=%s -- \"%s\"",
test_argv0__, test_verbose_level__,
test_colorize__ ? "always" : "never", test->name);
startupInfo.cb = sizeof(STARTUPINFO);
if(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) {
if (CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL,
&startupInfo, &processInfo)) {
WaitForSingleObject(processInfo.hProcess, INFINITE);
GetExitCodeProcess(processInfo.hProcess, &exitCode);
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
failed = (exitCode != 0);
} else {
test_error__("Cannot create unit test subprocess [%ld].", GetLastError());
test_error__("Cannot create unit test subprocess [%ld].",
GetLastError());
failed = 1;
}
@ -470,14 +520,13 @@ test_run__(const struct test__* test)
test_current_unit__ = NULL;
test_stat_run_units__++;
if(failed)
if (failed)
test_stat_failed_units__++;
}
#if defined(CUTEST_WIN__)
/* Callback for SEH events. */
static LONG CALLBACK
test_exception_filter__(EXCEPTION_POINTERS *ptrs)
static LONG CALLBACK test_exception_filter__(EXCEPTION_POINTERS *ptrs)
{
test_error__("Unhandled SEH exception %08lx at %p.",
ptrs->ExceptionRecord->ExceptionCode,
@ -488,35 +537,42 @@ test_exception_filter__(EXCEPTION_POINTERS *ptrs)
}
#endif
static void
test_help__(void)
static void test_help__(void)
{
printf("Usage: %s [options] [test...]\n", test_argv0__);
printf("Run the specified unit tests; or if the option '--skip' is used, run all\n");
printf("tests in the suite but those listed. By default, if no tests are specified\n");
printf("Run the specified unit tests; or if the option '--skip' is used, "
"run all\n");
printf("tests in the suite but those listed. By default, if no tests are "
"specified\n");
printf("on the command line, all unit tests in the suite are run.\n");
printf("\n");
printf("Options:\n");
printf(" -s, --skip Execute all unit tests but the listed ones\n");
printf(" --no-exec Do not execute unit tests as child processes\n");
printf(" --no-summary Suppress printing of test results summary\n");
printf(
" -s, --skip Execute all unit tests but the listed ones\n");
printf(" --no-exec Do not execute unit tests as child "
"processes\n");
printf(
" --no-summary Suppress printing of test results summary\n");
printf(" -l, --list List unit tests in the suite and exit\n");
printf(" -v, --verbose Enable more verbose output\n");
printf(" --verbose=LEVEL Set verbose level to LEVEL:\n");
printf(" 0 ... Be silent\n");
printf(" 1 ... Output one line per test (and summary)\n");
printf(" 2 ... As 1 and failed conditions (this is default)\n");
printf(" 3 ... As 1 and all conditions (and extended summary)\n");
printf(" --color=WHEN Enable colorized output (WHEN is one of 'auto', 'always', 'never')\n");
printf(" 1 ... Output one line per test (and "
"summary)\n");
printf(" 2 ... As 1 and failed conditions (this "
"is default)\n");
printf(" 3 ... As 1 and all conditions (and "
"extended summary)\n");
printf(" --color=WHEN Enable colorized output (WHEN is one of "
"'auto', 'always', 'never')\n");
printf(" -h, --help Display this help and exit\n");
printf("\n");
test_list_names__();
}
int
main(int argc, char** argv)
int main(int argc, char **argv)
{
const struct test__** tests = NULL;
const struct test__ **tests = NULL;
int i, j, n = 0;
int seen_double_dash = 0;
@ -531,42 +587,50 @@ main(int argc, char** argv)
#endif
/* Parse options */
for(i = 1; i < argc; i++) {
if(seen_double_dash || argv[i][0] != '-') {
tests = (const struct test__**) realloc((void*)tests, (n+1) * sizeof(const struct test__*));
if(tests == NULL) {
for (i = 1; i < argc; i++) {
if (seen_double_dash || argv[i][0] != '-') {
tests = (const struct test__ **)realloc(
(void *)tests, (n + 1) * sizeof(const struct test__ *));
if (tests == NULL) {
fprintf(stderr, "Out of memory.\n");
exit(2);
}
tests[n] = test_by_name__(argv[i]);
if(tests[n] == NULL) {
fprintf(stderr, "%s: Unrecognized unit test '%s'\n", argv[0], argv[i]);
fprintf(stderr, "Try '%s --list' for list of unit tests.\n", argv[0]);
if (tests[n] == NULL) {
fprintf(stderr, "%s: Unrecognized unit test '%s'\n", argv[0],
argv[i]);
fprintf(stderr, "Try '%s --list' for list of unit tests.\n",
argv[0]);
exit(2);
}
n++;
} else if(strcmp(argv[i], "--") == 0) {
} else if (strcmp(argv[i], "--") == 0) {
seen_double_dash = 1;
} else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
} else if (strcmp(argv[i], "--help") == 0 ||
strcmp(argv[i], "-h") == 0) {
test_help__();
exit(0);
} else if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
} else if (strcmp(argv[i], "--verbose") == 0 ||
strcmp(argv[i], "-v") == 0) {
test_verbose_level__++;
} else if(strncmp(argv[i], "--verbose=", 10) == 0) {
} else if (strncmp(argv[i], "--verbose=", 10) == 0) {
test_verbose_level__ = atoi(argv[i] + 10);
} else if(strcmp(argv[i], "--color=auto") == 0) {
} else if (strcmp(argv[i], "--color=auto") == 0) {
/* noop (set from above) */
} else if(strcmp(argv[i], "--color=always") == 0 || strcmp(argv[i], "--color") == 0) {
} else if (strcmp(argv[i], "--color=always") == 0 ||
strcmp(argv[i], "--color") == 0) {
test_colorize__ = 1;
} else if(strcmp(argv[i], "--color=never") == 0) {
} else if (strcmp(argv[i], "--color=never") == 0) {
test_colorize__ = 0;
} else if(strcmp(argv[i], "--skip") == 0 || strcmp(argv[i], "-s") == 0) {
} else if (strcmp(argv[i], "--skip") == 0 ||
strcmp(argv[i], "-s") == 0) {
test_skip_mode__ = 1;
} else if(strcmp(argv[i], "--no-exec") == 0) {
} else if (strcmp(argv[i], "--no-exec") == 0) {
test_no_exec__ = 1;
} else if(strcmp(argv[i], "--no-summary") == 0) {
} else if (strcmp(argv[i], "--no-summary") == 0) {
test_no_summary__ = 1;
} else if(strcmp(argv[i], "--list") == 0 || strcmp(argv[i], "-l") == 0) {
} else if (strcmp(argv[i], "--list") == 0 ||
strcmp(argv[i], "-l") == 0) {
test_list_names__();
exit(0);
} else {
@ -582,66 +646,68 @@ main(int argc, char** argv)
/* Count all test units */
test_count__ = 0;
for(i = 0; test_list__[i].func != NULL; i++)
for (i = 0; test_list__[i].func != NULL; i++)
test_count__++;
/* Run the tests */
if(n == 0) {
if (n == 0) {
/* Run all tests */
for(i = 0; test_list__[i].func != NULL; i++)
for (i = 0; test_list__[i].func != NULL; i++)
test_run__(&test_list__[i]);
} else if(!test_skip_mode__) {
} else if (!test_skip_mode__) {
/* Run the listed tests */
for(i = 0; i < n; i++)
for (i = 0; i < n; i++)
test_run__(tests[i]);
} else {
/* Run all tests except those listed */
for(i = 0; test_list__[i].func != NULL; i++) {
for (i = 0; test_list__[i].func != NULL; i++) {
int want_skip = 0;
for(j = 0; j < n; j++) {
if(tests[j] == &test_list__[i]) {
for (j = 0; j < n; j++) {
if (tests[j] == &test_list__[i]) {
want_skip = 1;
break;
}
}
if(!want_skip)
if (!want_skip)
test_run__(&test_list__[i]);
}
}
/* Write a summary */
if(!test_no_summary__ && test_verbose_level__ >= 1) {
if (!test_no_summary__ && test_verbose_level__ >= 1) {
test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "\nSummary:\n");
if(test_verbose_level__ >= 3) {
if (test_verbose_level__ >= 3) {
printf(" Count of all unit tests: %4d\n", test_count__);
printf(" Count of run unit tests: %4d\n", test_stat_run_units__);
printf(" Count of failed unit tests: %4d\n", test_stat_failed_units__);
printf(" Count of skipped unit tests: %4d\n", test_count__ - test_stat_run_units__);
printf(" Count of run unit tests: %4d\n",
test_stat_run_units__);
printf(" Count of failed unit tests: %4d\n",
test_stat_failed_units__);
printf(" Count of skipped unit tests: %4d\n",
test_count__ - test_stat_run_units__);
}
if(test_stat_failed_units__ == 0) {
if (test_stat_failed_units__ == 0) {
test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
" SUCCESS: All unit tests have passed.\n");
" SUCCESS: All unit tests have passed.\n");
} else {
test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
" FAILED: %d of %d unit tests have failed.\n",
test_stat_failed_units__, test_stat_run_units__);
test_print_in_color__(
CUTEST_COLOR_RED_INTENSIVE__,
" FAILED: %d of %d unit tests have failed.\n",
test_stat_failed_units__, test_stat_run_units__);
}
}
if(tests != NULL)
free((void*)tests);
if (tests != NULL)
free((void *)tests);
return (test_stat_failed_units__ == 0) ? 0 : 1;
}
#endif /* #ifndef TEST_NO_MAIN */
#endif /* #ifndef TEST_NO_MAIN */
#ifdef __cplusplus
} /* extern "C" */
} /* extern "C" */
#endif
#endif /* #ifndef CUTEST_H__ */
#endif /* #ifndef CUTEST_H__ */

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -46,172 +46,171 @@
#include "getopt_s.h" /* for local getopt() */
#include "srtp_priv.h"
srtp_err_status_t
test_dtls_srtp(void);
srtp_err_status_t test_dtls_srtp(void);
srtp_hdr_t *
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
void
usage(char *prog_name) {
printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
" -d <mod> turn on debugging module <mod>\n"
" -l list debugging modules\n", prog_name);
exit(1);
void usage(char *prog_name)
{
printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
" -d <mod> turn on debugging module <mod>\n"
" -l list debugging modules\n",
prog_name);
exit(1);
}
int
main(int argc, char *argv[]) {
unsigned do_list_mods = 0;
int q;
srtp_err_status_t err;
int main(int argc, char *argv[])
{
unsigned do_list_mods = 0;
int q;
srtp_err_status_t err;
printf("dtls_srtp_driver\n");
printf("dtls_srtp_driver\n");
/* initialize srtp library */
err = srtp_init();
if (err) {
printf("error: srtp init failed with error code %d\n", err);
exit(1);
}
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "ld:");
if (q == -1)
break;
switch (q) {
case 'l':
do_list_mods = 1;
break;
case 'd':
err = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (err) {
printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
default:
usage(argv[0]);
}
}
if (do_list_mods) {
err = srtp_crypto_kernel_list_debug_modules();
/* initialize srtp library */
err = srtp_init();
if (err) {
printf("error: list of debug modules failed\n");
exit(1);
printf("error: srtp init failed with error code %d\n", err);
exit(1);
}
}
printf("testing dtls_srtp...");
err = test_dtls_srtp();
if (err) {
printf("\nerror (code %d)\n", err);
exit(1);
}
printf("passed\n");
/* shut down srtp library */
err = srtp_shutdown();
if (err) {
printf("error: srtp shutdown failed with error code %d\n", err);
exit(1);
}
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "ld:");
if (q == -1)
break;
switch (q) {
case 'l':
do_list_mods = 1;
break;
case 'd':
err = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (err) {
printf("error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
default:
usage(argv[0]);
}
}
return 0;
if (do_list_mods) {
err = srtp_crypto_kernel_list_debug_modules();
if (err) {
printf("error: list of debug modules failed\n");
exit(1);
}
}
printf("testing dtls_srtp...");
err = test_dtls_srtp();
if (err) {
printf("\nerror (code %d)\n", err);
exit(1);
}
printf("passed\n");
/* shut down srtp library */
err = srtp_shutdown();
if (err) {
printf("error: srtp shutdown failed with error code %d\n", err);
exit(1);
}
return 0;
}
srtp_err_status_t test_dtls_srtp(void)
{
srtp_hdr_t *test_packet;
int test_packet_len = 80;
srtp_t s;
srtp_policy_t policy;
uint8_t key[SRTP_MAX_KEY_LEN];
uint8_t salt[SRTP_MAX_KEY_LEN];
unsigned int key_len, salt_len;
srtp_profile_t profile;
srtp_err_status_t err;
srtp_err_status_t
test_dtls_srtp(void) {
srtp_hdr_t *test_packet;
int test_packet_len = 80;
srtp_t s;
srtp_policy_t policy;
uint8_t key[SRTP_MAX_KEY_LEN];
uint8_t salt[SRTP_MAX_KEY_LEN];
unsigned int key_len, salt_len;
srtp_profile_t profile;
srtp_err_status_t err;
memset(&policy, 0x0, sizeof(srtp_policy_t));
memset(&policy, 0x0, sizeof(srtp_policy_t));
/* create a 'null' SRTP session */
err = srtp_create(&s, NULL);
if (err)
return err;
/* create a 'null' SRTP session */
err = srtp_create(&s, NULL);
if (err)
return err;
/*
* verify that packet-processing functions behave properly - we
* expect that these functions will return srtp_err_status_no_ctx
*/
test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
if (test_packet == NULL)
return srtp_err_status_alloc_fail;
/*
* verify that packet-processing functions behave properly - we
* expect that these functions will return srtp_err_status_no_ctx
*/
test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
if (test_packet == NULL)
return srtp_err_status_alloc_fail;
err = srtp_protect(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_protect() (got code %d)\n",
err);
return srtp_err_status_fail;
}
err = srtp_unprotect(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_unprotect() (got code %d)\n",
err);
return srtp_err_status_fail;
}
err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
err);
return srtp_err_status_fail;
}
err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
err);
return srtp_err_status_fail;
}
err = srtp_protect(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_protect() (got code %d)\n", err);
return srtp_err_status_fail;
}
err = srtp_unprotect(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_unprotect() (got code %d)\n", err);
return srtp_err_status_fail;
}
/*
* set keys to known values for testing
*/
profile = srtp_profile_aes128_cm_sha1_80;
key_len = srtp_profile_get_master_key_length(profile);
salt_len = srtp_profile_get_master_salt_length(profile);
memset(key, 0xff, key_len);
memset(salt, 0xee, salt_len);
srtp_append_salt_to_key(key, key_len, salt, salt_len);
policy.key = key;
err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
err);
return srtp_err_status_fail;
}
/* initialize SRTP policy from profile */
err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
if (err) return err;
err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
if (err) return err;
policy.ssrc.type = ssrc_any_inbound;
policy.ekt = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.next = NULL;
err = srtp_add_stream(s, &policy);
if (err)
return err;
err = srtp_dealloc(s);
if (err)
return err;
err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
if (err != srtp_err_status_no_ctx) {
printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
err);
return srtp_err_status_fail;
}
free(test_packet);
/*
* set keys to known values for testing
*/
profile = srtp_profile_aes128_cm_sha1_80;
key_len = srtp_profile_get_master_key_length(profile);
salt_len = srtp_profile_get_master_salt_length(profile);
memset(key, 0xff, key_len);
memset(salt, 0xee, salt_len);
srtp_append_salt_to_key(key, key_len, salt, salt_len);
policy.key = key;
return srtp_err_status_ok;
/* initialize SRTP policy from profile */
err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
if (err)
return err;
err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
if (err)
return err;
policy.ssrc.type = ssrc_any_inbound;
policy.ekt = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.next = NULL;
err = srtp_add_stream(s, &policy);
if (err)
return err;
err = srtp_dealloc(s);
if (err)
return err;
free(test_packet);
return srtp_err_status_ok;
}
/*
* srtp_create_test_packet(len, ssrc) returns a pointer to a
* (malloced) example RTP packet whose data field has the length given
@ -225,39 +224,38 @@ test_dtls_srtp(void) {
* deallocated with the free() call once it is no longer needed.
*/
srtp_hdr_t *
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
int i;
uint8_t *buffer;
srtp_hdr_t *hdr;
int bytes_in_hdr = 12;
srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc)
{
int i;
uint8_t *buffer;
srtp_hdr_t *hdr;
int bytes_in_hdr = 12;
/* allocate memory for test packet */
hdr = malloc(pkt_octet_len + bytes_in_hdr
+ SRTP_MAX_TRAILER_LEN + 4);
if (!hdr)
return NULL;
hdr->version = 2; /* RTP version two */
hdr->p = 0; /* no padding needed */
hdr->x = 0; /* no header extension */
hdr->cc = 0; /* no CSRCs */
hdr->m = 0; /* marker bit */
hdr->pt = 0xf; /* payload type */
hdr->seq = htons(0x1234); /* sequence number */
hdr->ts = htonl(0xdecafbad); /* timestamp */
hdr->ssrc = htonl(ssrc); /* synch. source */
/* allocate memory for test packet */
hdr = malloc(pkt_octet_len + bytes_in_hdr + SRTP_MAX_TRAILER_LEN + 4);
if (!hdr)
return NULL;
buffer = (uint8_t *)hdr;
buffer += bytes_in_hdr;
hdr->version = 2; /* RTP version two */
hdr->p = 0; /* no padding needed */
hdr->x = 0; /* no header extension */
hdr->cc = 0; /* no CSRCs */
hdr->m = 0; /* marker bit */
hdr->pt = 0xf; /* payload type */
hdr->seq = htons(0x1234); /* sequence number */
hdr->ts = htonl(0xdecafbad); /* timestamp */
hdr->ssrc = htonl(ssrc); /* synch. source */
/* set RTP data to 0xab */
for (i=0; i < pkt_octet_len; i++)
*buffer++ = 0xab;
buffer = (uint8_t *)hdr;
buffer += bytes_in_hdr;
/* set post-data value to 0xffff to enable overrun checking */
for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
*buffer++ = 0xff;
/* set RTP data to 0xab */
for (i = 0; i < pkt_octet_len; i++)
*buffer++ = 0xab;
return hdr;
/* set post-data value to 0xffff to enable overrun checking */
for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++)
*buffer++ = 0xff;
return hdr;
}

View File

@ -3,30 +3,30 @@
*
* a minimal implementation of the getopt() function, written so that
* test applications that use that function can run on non-POSIX
* platforms
* platforms
*
*/
/*
*
*
* 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
@ -42,71 +42,67 @@
*
*/
#include <stdlib.h> /* for NULL */
#include <stdlib.h> /* for NULL */
int optind_s = 0;
char *optarg_s;
#define GETOPT_FOUND_WITHOUT_ARGUMENT 2
#define GETOPT_FOUND_WITH_ARGUMENT 1
#define GETOPT_NOT_FOUND 0
#define GETOPT_FOUND_WITHOUT_ARGUMENT 2
#define GETOPT_FOUND_WITH_ARGUMENT 1
#define GETOPT_NOT_FOUND 0
static int
getopt_check_character(char c, const char *string) {
unsigned int max_string_len = 128;
static int getopt_check_character(char c, const char *string)
{
unsigned int max_string_len = 128;
while (*string != 0) {
if (max_string_len == 0) {
return '?';
while (*string != 0) {
if (max_string_len == 0) {
return '?';
}
if (*string++ == c) {
if (*string == ':') {
return GETOPT_FOUND_WITH_ARGUMENT;
} else {
return GETOPT_FOUND_WITHOUT_ARGUMENT;
}
}
}
if (*string++ == c) {
if (*string == ':') {
return GETOPT_FOUND_WITH_ARGUMENT;
} else {
return GETOPT_FOUND_WITHOUT_ARGUMENT;
}
}
}
return GETOPT_NOT_FOUND;
return GETOPT_NOT_FOUND;
}
int
getopt_s(int argc,
char * const argv[],
const char *optstring) {
int getopt_s(int argc, char *const argv[], const char *optstring)
{
while (optind_s + 1 < argc) {
char *string;
/* move 'string' on to next argument */
optind_s++;
string = argv[optind_s];
while (optind_s + 1 < argc) {
char *string;
/* move 'string' on to next argument */
optind_s++;
string = argv[optind_s];
if (string == NULL)
return '?'; /* NULL argument string */
if (string == NULL)
return '?'; /* NULL argument string */
if (string[0] != '-')
return -1; /* found an unexpected character */
if (string[0] != '-')
return -1; /* found an unexpected character */
switch(getopt_check_character(string[1], optstring)) {
case GETOPT_FOUND_WITH_ARGUMENT:
if (optind_s + 1 < argc) {
optind_s++;
optarg_s = argv[optind_s];
return string[1];
} else {
return '?'; /* argument missing */
}
case GETOPT_FOUND_WITHOUT_ARGUMENT:
return string[1];
case GETOPT_NOT_FOUND:
default:
return '?'; /* didn't find expected character */
break;
switch (getopt_check_character(string[1], optstring)) {
case GETOPT_FOUND_WITH_ARGUMENT:
if (optind_s + 1 < argc) {
optind_s++;
optarg_s = argv[optind_s];
return string[1];
} else {
return '?'; /* argument missing */
}
case GETOPT_FOUND_WITHOUT_ARGUMENT:
return string[1];
case GETOPT_NOT_FOUND:
default:
return '?'; /* didn't find expected character */
break;
}
}
}
return -1;
return -1;
}

View File

@ -6,28 +6,27 @@
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
*
* 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
@ -44,7 +43,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h> /* for printf() */
@ -58,90 +57,85 @@
#include "ut_sim.h"
srtp_err_status_t
test_replay_dbx(int num_trials, unsigned long ws);
srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws);
double
rdbx_check_adds_per_second(int num_trials, unsigned long ws);
double rdbx_check_adds_per_second(int num_trials, unsigned long ws);
void
usage(char *prog_name) {
printf("usage: %s [ -t | -v ]\n", prog_name);
exit(255);
void usage(char *prog_name)
{
printf("usage: %s [ -t | -v ]\n", prog_name);
exit(255);
}
int
main (int argc, char *argv[]) {
double rate;
srtp_err_status_t status;
int q;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
int main(int argc, char *argv[])
{
double rate;
srtp_err_status_t status;
int q;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "tv");
if (q == -1)
break;
switch (q) {
case 't':
do_timing_test = 1;
break;
case 'v':
do_validation = 1;
break;
default:
usage(argv[0]);
}
}
printf("rdbx (replay database w/ extended range) test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
if (!do_validation && !do_timing_test)
usage(argv[0]);
if (do_validation) {
printf("testing srtp_rdbx_t (ws=128)...\n");
status = test_replay_dbx(1 << 12, 128);
if (status) {
printf("failed\n");
exit(1);
/* process input arguments */
while (1) {
q = getopt_s(argc, argv, "tv");
if (q == -1)
break;
switch (q) {
case 't':
do_timing_test = 1;
break;
case 'v':
do_validation = 1;
break;
default:
usage(argv[0]);
}
}
printf("passed\n");
printf("testing srtp_rdbx_t (ws=1024)...\n");
printf("rdbx (replay database w/ extended range) test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
status = test_replay_dbx(1 << 12, 1024);
if (status) {
printf("failed\n");
exit(1);
if (!do_validation && !do_timing_test)
usage(argv[0]);
if (do_validation) {
printf("testing srtp_rdbx_t (ws=128)...\n");
status = test_replay_dbx(1 << 12, 128);
if (status) {
printf("failed\n");
exit(1);
}
printf("passed\n");
printf("testing srtp_rdbx_t (ws=1024)...\n");
status = test_replay_dbx(1 << 12, 1024);
if (status) {
printf("failed\n");
exit(1);
}
printf("passed\n");
}
printf("passed\n");
}
if (do_timing_test) {
rate = rdbx_check_adds_per_second(1 << 18, 128);
printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
rate = rdbx_check_adds_per_second(1 << 18, 1024);
printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
}
return 0;
if (do_timing_test) {
rate = rdbx_check_adds_per_second(1 << 18, 128);
printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
rate = rdbx_check_adds_per_second(1 << 18, 1024);
printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
}
return 0;
}
void
print_rdbx(srtp_rdbx_t *rdbx) {
char buf[2048];
printf("rdbx: {%llu, %s}\n",
(unsigned long long)(rdbx->index),
bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf))
);
void print_rdbx(srtp_rdbx_t *rdbx)
{
char buf[2048];
printf("rdbx: {%llu, %s}\n", (unsigned long long)(rdbx->index),
bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf)));
}
/*
* rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against
* rdbx, then adds it. if a failure is detected (i.e., the check
@ -150,217 +144,214 @@ print_rdbx(srtp_rdbx_t *rdbx) {
*
*/
srtp_err_status_t
rdbx_check_add(srtp_rdbx_t *rdbx, uint32_t idx) {
int delta;
srtp_xtd_seq_num_t est;
delta = srtp_index_guess(&rdbx->index, &est, idx);
if (srtp_rdbx_check(rdbx, delta) != srtp_err_status_ok) {
printf("replay_check failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
srtp_err_status_t rdbx_check_add(srtp_rdbx_t *rdbx, uint32_t idx)
{
int delta;
srtp_xtd_seq_num_t est;
/*
* in practice, we'd authenticate the packet containing idx, using
* the estimated value est, at this point
*/
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
printf("rdbx_add_index failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
delta = srtp_index_guess(&rdbx->index, &est, idx);
return srtp_err_status_ok;
if (srtp_rdbx_check(rdbx, delta) != srtp_err_status_ok) {
printf("replay_check failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
/*
* in practice, we'd authenticate the packet containing idx, using
* the estimated value est, at this point
*/
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
printf("rdbx_add_index failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
return srtp_err_status_ok;
}
/*
* rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
*
*
* checks that a sequence number idx is in the replay database
* and thus will be rejected
*/
srtp_err_status_t
rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx) {
int delta;
srtp_xtd_seq_num_t est;
srtp_err_status_t status;
srtp_err_status_t rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
{
int delta;
srtp_xtd_seq_num_t est;
srtp_err_status_t status;
delta = srtp_index_guess(&rdbx->index, &est, idx);
delta = srtp_index_guess(&rdbx->index, &est, idx);
status = srtp_rdbx_check(rdbx, delta);
if (status == srtp_err_status_ok) {
printf("delta: %d ", delta);
printf("replay_check failed at index %u (false positive)\n", idx);
return srtp_err_status_algo_fail;
}
status = srtp_rdbx_check(rdbx, delta);
if (status == srtp_err_status_ok) {
printf("delta: %d ", delta);
printf("replay_check failed at index %u (false positive)\n", idx);
return srtp_err_status_algo_fail;
}
return srtp_err_status_ok;
return srtp_err_status_ok;
}
srtp_err_status_t
rdbx_check_add_unordered(srtp_rdbx_t *rdbx, uint32_t idx) {
int delta;
srtp_xtd_seq_num_t est;
srtp_err_status_t rstat;
srtp_err_status_t rdbx_check_add_unordered(srtp_rdbx_t *rdbx, uint32_t idx)
{
int delta;
srtp_xtd_seq_num_t est;
srtp_err_status_t rstat;
delta = srtp_index_guess(&rdbx->index, &est, idx);
delta = srtp_index_guess(&rdbx->index, &est, idx);
rstat = srtp_rdbx_check(rdbx, delta);
if ((rstat != srtp_err_status_ok) && (rstat != srtp_err_status_replay_old)) {
printf("replay_check_add_unordered failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
if (rstat == srtp_err_status_replay_old) {
return srtp_err_status_ok;
}
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
printf("rdbx_add_index failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
rstat = srtp_rdbx_check(rdbx, delta);
if ((rstat != srtp_err_status_ok) &&
(rstat != srtp_err_status_replay_old)) {
printf("replay_check_add_unordered failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
if (rstat == srtp_err_status_replay_old) {
return srtp_err_status_ok;
}
if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
printf("rdbx_add_index failed at index %u\n", idx);
return srtp_err_status_algo_fail;
}
return srtp_err_status_ok;
return srtp_err_status_ok;
}
srtp_err_status_t
test_replay_dbx(int num_trials, unsigned long ws) {
srtp_rdbx_t rdbx;
uint32_t idx, ircvd;
ut_connection utc;
srtp_err_status_t status;
int num_fp_trials;
srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
{
srtp_rdbx_t rdbx;
uint32_t idx, ircvd;
ut_connection utc;
srtp_err_status_t status;
int num_fp_trials;
status = srtp_rdbx_init(&rdbx, ws);
if (status) {
printf("replay_init failed with error code %d\n", status);
exit(1);
}
status = srtp_rdbx_init(&rdbx, ws);
if (status) {
printf("replay_init failed with error code %d\n", status);
exit(1);
}
/*
* test sequential insertion
*/
printf("\ttesting sequential insertion...");
for (idx=0; (int) idx < num_trials; idx++) {
status = rdbx_check_add(&rdbx, idx);
if (status)
return status;
}
printf("passed\n");
/*
* test sequential insertion
*/
printf("\ttesting sequential insertion...");
for (idx = 0; (int)idx < num_trials; idx++) {
status = rdbx_check_add(&rdbx, idx);
if (status)
return status;
}
printf("passed\n");
/*
* test for false positives by checking all of the index
* values which we've just added
*
* note that we limit the number of trials here, since allowing the
* rollover counter to roll over would defeat this test
*/
num_fp_trials = num_trials % 0x10000;
if (num_fp_trials == 0) {
printf("warning: no false positive tests performed\n");
}
printf("\ttesting for false positives...");
for (idx=0; (int) idx < num_fp_trials; idx++) {
status = rdbx_check_expect_failure(&rdbx, idx);
if (status)
return status;
}
printf("passed\n");
/*
* test for false positives by checking all of the index
* values which we've just added
*
* note that we limit the number of trials here, since allowing the
* rollover counter to roll over would defeat this test
*/
num_fp_trials = num_trials % 0x10000;
if (num_fp_trials == 0) {
printf("warning: no false positive tests performed\n");
}
printf("\ttesting for false positives...");
for (idx = 0; (int)idx < num_fp_trials; idx++) {
status = rdbx_check_expect_failure(&rdbx, idx);
if (status)
return status;
}
printf("passed\n");
/* re-initialize */
srtp_rdbx_dealloc(&rdbx);
/* re-initialize */
srtp_rdbx_dealloc(&rdbx);
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
return srtp_err_status_init_fail;
}
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
return srtp_err_status_init_fail;
}
/*
* test non-sequential insertion
*
* this test covers only fase negatives, since the values returned
* by ut_next_index(...) are distinct
*/
ut_init(&utc);
/*
* test non-sequential insertion
*
* this test covers only fase negatives, since the values returned
* by ut_next_index(...) are distinct
*/
ut_init(&utc);
printf("\ttesting non-sequential insertion...");
for (idx=0; (int) idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
status = rdbx_check_add_unordered(&rdbx, ircvd);
if (status)
return status;
status = rdbx_check_expect_failure(&rdbx, ircvd);
if (status)
return status;
}
printf("passed\n");
printf("\ttesting non-sequential insertion...");
for (idx = 0; (int)idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
status = rdbx_check_add_unordered(&rdbx, ircvd);
if (status)
return status;
status = rdbx_check_expect_failure(&rdbx, ircvd);
if (status)
return status;
}
printf("passed\n");
/* re-initialize */
srtp_rdbx_dealloc(&rdbx);
/* re-initialize */
srtp_rdbx_dealloc(&rdbx);
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
return srtp_err_status_init_fail;
}
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
return srtp_err_status_init_fail;
}
/*
* test insertion with large gaps.
* check for false positives for each insertion.
*/
printf("\ttesting insertion with large gaps...");
for (idx=0, ircvd=0; (int) idx < num_trials; idx++, ircvd += (1 << (rand() % 12))) {
status = rdbx_check_add(&rdbx, ircvd);
if (status)
return status;
status = rdbx_check_expect_failure(&rdbx, ircvd);
if (status)
return status;
}
printf("passed\n");
/*
* test insertion with large gaps.
* check for false positives for each insertion.
*/
printf("\ttesting insertion with large gaps...");
for (idx = 0, ircvd = 0; (int)idx < num_trials;
idx++, ircvd += (1 << (rand() % 12))) {
status = rdbx_check_add(&rdbx, ircvd);
if (status)
return status;
status = rdbx_check_expect_failure(&rdbx, ircvd);
if (status)
return status;
}
printf("passed\n");
srtp_rdbx_dealloc(&rdbx);
srtp_rdbx_dealloc(&rdbx);
return srtp_err_status_ok;
return srtp_err_status_ok;
}
#include <time.h> /* for clock() */
#include <stdlib.h> /* for random() */
double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
{
uint32_t i;
int delta;
srtp_rdbx_t rdbx;
srtp_xtd_seq_num_t est;
clock_t timer;
int failures; /* count number of failures */
#include <time.h> /* for clock() */
#include <stdlib.h> /* for random() */
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
exit(1);
}
double
rdbx_check_adds_per_second(int num_trials, unsigned long ws) {
uint32_t i;
int delta;
srtp_rdbx_t rdbx;
srtp_xtd_seq_num_t est;
clock_t timer;
int failures; /* count number of failures */
if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
printf("replay_init failed\n");
exit(1);
}
failures = 0;
timer = clock();
for (i = 0; (int)i < num_trials; i++) {
delta = srtp_index_guess(&rdbx.index, &est, i);
failures = 0;
timer = clock();
for(i=0; (int) i < num_trials; i++) {
delta = srtp_index_guess(&rdbx.index, &est, i);
if (srtp_rdbx_check(&rdbx, delta) != srtp_err_status_ok)
++failures;
else
if (srtp_rdbx_add_index(&rdbx, delta) != srtp_err_status_ok)
++failures;
}
timer = clock() - timer;
if (srtp_rdbx_check(&rdbx, delta) != srtp_err_status_ok)
++failures;
else if (srtp_rdbx_add_index(&rdbx, delta) != srtp_err_status_ok)
++failures;
}
timer = clock() - timer;
printf("number of failures: %d \n", failures);
printf("number of failures: %d \n", failures);
srtp_rdbx_dealloc(&rdbx);
srtp_rdbx_dealloc(&rdbx);
return (double) CLOCKS_PER_SEC * num_trials / timer;
return (double)CLOCKS_PER_SEC * num_trials / timer;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -44,7 +44,7 @@
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h>
@ -59,226 +59,225 @@
unsigned num_trials = 1 << 16;
srtp_err_status_t
test_rdb_db(void);
srtp_err_status_t test_rdb_db(void);
double
rdb_check_adds_per_second(void);
double rdb_check_adds_per_second(void);
int
main (void) {
srtp_err_status_t err;
printf("testing anti-replay database (srtp_rdb_t)...\n");
err = test_rdb_db();
if (err) {
printf("failed\n");
exit(1);
}
printf("done\n");
int main(void)
{
srtp_err_status_t err;
printf("rdb_check/rdb_adds per second: %e\n",
rdb_check_adds_per_second());
return 0;
printf("testing anti-replay database (srtp_rdb_t)...\n");
err = test_rdb_db();
if (err) {
printf("failed\n");
exit(1);
}
printf("done\n");
printf("rdb_check/rdb_adds per second: %e\n", rdb_check_adds_per_second());
return 0;
}
void
print_rdb(srtp_rdb_t *rdb) {
printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask));
void print_rdb(srtp_rdb_t *rdb)
{
printf("rdb: {%u, %s}\n", rdb->window_start,
v128_bit_string(&rdb->bitmask));
}
srtp_err_status_t
rdb_check_add(srtp_rdb_t *rdb, uint32_t idx) {
srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx)
{
if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
printf("rdb_check failed at index %u\n", idx);
return srtp_err_status_fail;
}
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
printf("rdb_add_index failed at index %u\n", idx);
return srtp_err_status_fail;
}
if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
printf("rdb_check failed at index %u\n", idx);
return srtp_err_status_fail;
}
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
printf("rdb_add_index failed at index %u\n", idx);
return srtp_err_status_fail;
}
return srtp_err_status_ok;
return srtp_err_status_ok;
}
srtp_err_status_t
rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx) {
srtp_err_status_t err;
err = srtp_rdb_check(rdb, idx);
if ((err != srtp_err_status_replay_old) && (err != srtp_err_status_replay_fail)) {
printf("rdb_check failed at index %u (false positive)\n", idx);
return srtp_err_status_fail;
}
srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx)
{
srtp_err_status_t err;
return srtp_err_status_ok;
err = srtp_rdb_check(rdb, idx);
if ((err != srtp_err_status_replay_old) &&
(err != srtp_err_status_replay_fail)) {
printf("rdb_check failed at index %u (false positive)\n", idx);
return srtp_err_status_fail;
}
return srtp_err_status_ok;
}
srtp_err_status_t
rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx) {
srtp_err_status_t rstat;
srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx)
{
srtp_err_status_t rstat;
/* printf("index: %u\n", idx); */
rstat = srtp_rdb_check(rdb, idx);
if ((rstat != srtp_err_status_ok) && (rstat != srtp_err_status_replay_old)) {
printf("rdb_check_add_unordered failed at index %u\n", idx);
return rstat;
}
if (rstat == srtp_err_status_replay_old) {
return srtp_err_status_ok;
}
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
printf("rdb_add_index failed at index %u\n", idx);
return srtp_err_status_fail;
}
/* printf("index: %u\n", idx); */
rstat = srtp_rdb_check(rdb, idx);
if ((rstat != srtp_err_status_ok) &&
(rstat != srtp_err_status_replay_old)) {
printf("rdb_check_add_unordered failed at index %u\n", idx);
return rstat;
}
if (rstat == srtp_err_status_replay_old) {
return srtp_err_status_ok;
}
if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
printf("rdb_add_index failed at index %u\n", idx);
return srtp_err_status_fail;
}
return srtp_err_status_ok;
return srtp_err_status_ok;
}
srtp_err_status_t
test_rdb_db() {
srtp_rdb_t rdb;
uint32_t idx, ircvd;
ut_connection utc;
srtp_err_status_t err;
srtp_err_status_t test_rdb_db()
{
srtp_rdb_t rdb;
uint32_t idx, ircvd;
ut_connection utc;
srtp_err_status_t err;
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_init_fail;
}
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_init_fail;
}
/* test sequential insertion */
for (idx=0; idx < num_trials; idx++) {
err = rdb_check_add(&rdb, idx);
if (err)
return err;
}
/* test sequential insertion */
for (idx = 0; idx < num_trials; idx++) {
err = rdb_check_add(&rdb, idx);
if (err)
return err;
}
/* test for false positives */
for (idx=0; idx < num_trials; idx++) {
err = rdb_check_expect_failure(&rdb, idx);
if (err)
return err;
}
/* test for false positives */
for (idx = 0; idx < num_trials; idx++) {
err = rdb_check_expect_failure(&rdb, idx);
if (err)
return err;
}
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
/* test non-sequential insertion */
ut_init(&utc);
for (idx=0; idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
err = rdb_check_add_unordered(&rdb, ircvd);
if (err)
return err;
err = rdb_check_expect_failure(&rdb, ircvd);
if (err)
return err;
}
/* test non-sequential insertion */
ut_init(&utc);
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
for (idx = 0; idx < num_trials; idx++) {
ircvd = ut_next_index(&utc);
err = rdb_check_add_unordered(&rdb, ircvd);
if (err)
return err;
err = rdb_check_expect_failure(&rdb, ircvd);
if (err)
return err;
}
/* test insertion with large gaps */
for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) {
err = rdb_check_add(&rdb, ircvd);
if (err)
return err;
err = rdb_check_expect_failure(&rdb, ircvd);
if (err)
return err;
}
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
/* test insertion with large gaps */
for (idx = 0, ircvd = 0; idx < num_trials;
idx++, ircvd += (1 << (rand() % 10))) {
err = rdb_check_add(&rdb, ircvd);
if (err)
return err;
err = rdb_check_expect_failure(&rdb, ircvd);
if (err)
return err;
}
/* test loss of first 513 packets */
for (idx=0; idx < num_trials; idx++) {
err = rdb_check_add(&rdb, idx + 513);
if (err)
return err;
}
/* re-initialize */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
/* test for false positives */
for (idx=0; idx < num_trials + 513; idx++) {
err = rdb_check_expect_failure(&rdb, idx);
if (err)
return err;
}
/* test loss of first 513 packets */
for (idx = 0; idx < num_trials; idx++) {
err = rdb_check_add(&rdb, idx + 513);
if (err)
return err;
}
/* test for key expired */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
rdb.window_start = 0x7ffffffe;
if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) {
printf("srtp_rdb_increment of 0x7ffffffe failed\n");
return srtp_err_status_fail;
}
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
printf("rdb valiue was not 0x7fffffff\n");
return srtp_err_status_fail;
}
if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) {
printf("srtp_rdb_increment of 0x7fffffff did not return srtp_err_status_key_expired\n");
return srtp_err_status_fail;
}
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
printf("rdb valiue was not 0x7fffffff\n");
return srtp_err_status_fail;
}
/* test for false positives */
for (idx = 0; idx < num_trials + 513; idx++) {
err = rdb_check_expect_failure(&rdb, idx);
if (err)
return err;
}
/* test for key expired */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
return srtp_err_status_fail;
}
rdb.window_start = 0x7ffffffe;
if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) {
printf("srtp_rdb_increment of 0x7ffffffe failed\n");
return srtp_err_status_fail;
}
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
printf("rdb valiue was not 0x7fffffff\n");
return srtp_err_status_fail;
}
if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) {
printf("srtp_rdb_increment of 0x7fffffff did not return "
"srtp_err_status_key_expired\n");
return srtp_err_status_fail;
}
if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
printf("rdb valiue was not 0x7fffffff\n");
return srtp_err_status_fail;
}
return srtp_err_status_ok;
return srtp_err_status_ok;
}
#include <time.h> /* for clock() */
#include <stdlib.h> /* for random() */
#include <time.h> /* for clock() */
#include <stdlib.h> /* for random() */
#define REPLAY_NUM_TRIALS 10000000
double
rdb_check_adds_per_second(void) {
uint32_t i;
srtp_rdb_t rdb;
clock_t timer;
int failures = 0; /* count number of failures */
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
exit(1);
}
double rdb_check_adds_per_second(void)
{
uint32_t i;
srtp_rdb_t rdb;
clock_t timer;
int failures = 0; /* count number of failures */
timer = clock();
for(i=0; i < REPLAY_NUM_TRIALS; i+=3) {
if (srtp_rdb_check(&rdb, i+2) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i+2) != srtp_err_status_ok)
++failures;
if (srtp_rdb_check(&rdb, i+1) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i+1) != srtp_err_status_ok)
++failures;
if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
++failures;
}
timer = clock() - timer;
if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
printf("rdb_init failed\n");
exit(1);
}
return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
timer = clock();
for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) {
if (srtp_rdb_check(&rdb, i + 2) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i + 2) != srtp_err_status_ok)
++failures;
if (srtp_rdb_check(&rdb, i + 1) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i + 1) != srtp_err_status_ok)
++failures;
if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
++failures;
if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
++failures;
}
timer = clock() - timer;
return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -43,9 +43,8 @@
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#include <config.h>
#endif
#include <stdio.h>
@ -55,121 +54,117 @@
* srtp_xtd_seq_num_t - this allows the functions to be exhaustively tested.
*/
#if ROC_NEEDS_TO_BE_TESTED
#define ROC_TEST
#define ROC_TEST
#endif
#include "rdbx.h"
#include "ut_sim.h"
srtp_err_status_t
roc_test(int num_trials);
srtp_err_status_t roc_test(int num_trials);
int
main (void) {
srtp_err_status_t status;
int main(void)
{
srtp_err_status_t status;
printf("rollover counter test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
printf("testing index functions...");
status = roc_test(1 << 18);
if (status) {
printf("failed\n");
exit(status);
}
printf("passed\n");
return 0;
printf("rollover counter test driver\n"
"David A. McGrew\n"
"Cisco Systems, Inc.\n");
printf("testing index functions...");
status = roc_test(1 << 18);
if (status) {
printf("failed\n");
exit(status);
}
printf("passed\n");
return 0;
}
#define ROC_VERBOSE 0
srtp_err_status_t
roc_test(int num_trials) {
srtp_xtd_seq_num_t local, est, ref;
ut_connection utc;
int i, num_bad_est = 0;
int delta;
uint32_t ircvd;
double failure_rate;
srtp_err_status_t roc_test(int num_trials)
{
srtp_xtd_seq_num_t local, est, ref;
ut_connection utc;
int i, num_bad_est = 0;
int delta;
uint32_t ircvd;
double failure_rate;
srtp_index_init(&local);
srtp_index_init(&ref);
srtp_index_init(&est);
srtp_index_init(&local);
srtp_index_init(&ref);
srtp_index_init(&est);
printf("\n\ttesting sequential insertion...");
for (i=0; i < 2048; i++) {
delta = srtp_index_guess(&local, &est, (uint16_t) ref);
printf("\n\ttesting sequential insertion...");
for (i = 0; i < 2048; i++) {
delta = srtp_index_guess(&local, &est, (uint16_t)ref);
#if ROC_VERBOSE
printf("%lld, %lld, %d\n", ref, est, i);
printf("%lld, %lld, %d\n", ref, est, i);
#endif
if (ref != est) {
if (ref != est) {
#if ROC_VERBOSE
printf(" *bad estimate*\n");
printf(" *bad estimate*\n");
#endif
++num_bad_est;
++num_bad_est;
}
srtp_index_advance(&ref, 1);
}
srtp_index_advance(&ref, 1);
}
failure_rate = (double) num_bad_est / num_trials;
if (failure_rate > 0.01) {
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
num_bad_est, num_trials);
return srtp_err_status_algo_fail;
}
printf("done\n");
printf("\ttesting non-sequential insertion...");
srtp_index_init(&local);
srtp_index_init(&ref);
srtp_index_init(&est);
ut_init(&utc);
for (i=0; i < num_trials; i++) {
/* get next seq num from unreliable transport simulator */
ircvd = ut_next_index(&utc);
/* set ref to value of ircvd */
ref = ircvd;
/* estimate index based on low bits of ircvd */
delta = srtp_index_guess(&local, &est, (uint16_t) ref);
#if ROC_VERBOSE
printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n",
ref, local, est, ircvd, delta);
#endif
if (local + delta != est) {
printf(" *bad delta*: local %llu + delta %d != est %llu\n",
(unsigned long long)local, delta, (unsigned long long)est);
return srtp_err_status_algo_fail;
failure_rate = (double)num_bad_est / num_trials;
if (failure_rate > 0.01) {
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
num_bad_est, num_trials);
return srtp_err_status_algo_fail;
}
printf("done\n");
/* now update local srtp_xtd_seq_num_t as necessary */
if (delta > 0)
srtp_index_advance(&local, delta);
printf("\ttesting non-sequential insertion...");
srtp_index_init(&local);
srtp_index_init(&ref);
srtp_index_init(&est);
ut_init(&utc);
if (ref != est) {
for (i = 0; i < num_trials; i++) {
/* get next seq num from unreliable transport simulator */
ircvd = ut_next_index(&utc);
/* set ref to value of ircvd */
ref = ircvd;
/* estimate index based on low bits of ircvd */
delta = srtp_index_guess(&local, &est, (uint16_t)ref);
#if ROC_VERBOSE
printf(" *bad estimate*\n");
printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n", ref,
local, est, ircvd, delta);
#endif
/* record failure event */
++num_bad_est;
/* reset local value to correct value */
local = ref;
}
}
failure_rate = (double) num_bad_est / num_trials;
if (failure_rate > 0.01) {
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
num_bad_est, num_trials);
return srtp_err_status_algo_fail;
}
printf("done\n");
return srtp_err_status_ok;
if (local + delta != est) {
printf(" *bad delta*: local %llu + delta %d != est %llu\n",
(unsigned long long)local, delta, (unsigned long long)est);
return srtp_err_status_algo_fail;
}
/* now update local srtp_xtd_seq_num_t as necessary */
if (delta > 0)
srtp_index_advance(&local, delta);
if (ref != est) {
#if ROC_VERBOSE
printf(" *bad estimate*\n");
#endif
/* record failure event */
++num_bad_est;
/* reset local value to correct value */
local = ref;
}
}
failure_rate = (double)num_bad_est / num_trials;
if (failure_rate > 0.01) {
printf("error: failure rate too high (%d bad estimates in %d trials)\n",
num_bad_est, num_trials);
return srtp_err_status_algo_fail;
}
printf("done\n");
return srtp_err_status_ok;
}

View File

@ -8,26 +8,26 @@
*/
/*
*
*
* 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
@ -50,178 +50,178 @@
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#include <sys/socket.h>
#endif
#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */
#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */
#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */
#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */
int
rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
int octets_sent;
srtp_err_status_t stat;
int pkt_len = len + RTP_HEADER_LEN;
int rtp_sendto(rtp_sender_t sender, const void *msg, int len)
{
int octets_sent;
srtp_err_status_t stat;
int pkt_len = len + RTP_HEADER_LEN;
/* marshal data */
strncpy(sender->message.body, msg, len);
/* update header */
sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
sender->message.header.seq = htons(sender->message.header.seq);
sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
sender->message.header.ts = htonl(sender->message.header.ts);
/* apply srtp */
stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
if (stat) {
/* marshal data */
strncpy(sender->message.body, msg, len);
/* update header */
sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
sender->message.header.seq = htons(sender->message.header.seq);
sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
sender->message.header.ts = htonl(sender->message.header.ts);
/* apply srtp */
stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
if (stat) {
#if PRINT_DEBUG
fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
#endif
return -1;
}
return -1;
}
#if VERBOSE_DEBUG
srtp_print_packet(&sender->message.header, pkt_len);
srtp_print_packet(&sender->message.header, pkt_len);
#endif
octets_sent = sendto(sender->socket, (void*)&sender->message,
pkt_len, 0, (struct sockaddr *)&sender->addr,
sizeof (struct sockaddr_in));
octets_sent =
sendto(sender->socket, (void *)&sender->message, pkt_len, 0,
(struct sockaddr *)&sender->addr, sizeof(struct sockaddr_in));
if (octets_sent != pkt_len) {
if (octets_sent != pkt_len) {
#if PRINT_DEBUG
fprintf(stderr, "error: couldn't send message %s", (char *)msg);
perror("");
fprintf(stderr, "error: couldn't send message %s", (char *)msg);
perror("");
#endif
}
}
return octets_sent;
return octets_sent;
}
int
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
int octets_recvd;
srtp_err_status_t stat;
octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
*len, 0, (struct sockaddr *) NULL, 0);
int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len)
{
int octets_recvd;
srtp_err_status_t stat;
if (octets_recvd == -1) {
*len = 0;
return -1;
}
octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, *len,
0, (struct sockaddr *)NULL, 0);
/* verify rtp header */
if (receiver->message.header.version != 2) {
*len = 0;
return -1;
}
if (octets_recvd == -1) {
*len = 0;
return -1;
}
/* verify rtp header */
if (receiver->message.header.version != 2) {
*len = 0;
return -1;
}
#if PRINT_DEBUG
fprintf(stderr, "%d octets received from SSRC %u\n",
octets_recvd, receiver->message.header.ssrc);
fprintf(stderr, "%d octets received from SSRC %u\n", octets_recvd,
receiver->message.header.ssrc);
#endif
#if VERBOSE_DEBUG
srtp_print_packet(&receiver->message.header, octets_recvd);
srtp_print_packet(&receiver->message.header, octets_recvd);
#endif
/* apply srtp */
stat = srtp_unprotect(receiver->srtp_ctx,
&receiver->message.header, &octets_recvd);
if (stat) {
fprintf(stderr,
"error: srtp unprotection failed with code %d%s\n", stat,
stat == srtp_err_status_replay_fail ? " (replay check failed)" :
stat == srtp_err_status_auth_fail ? " (auth check failed)" : "");
return -1;
}
strncpy(msg, receiver->message.body, octets_recvd);
return octets_recvd;
/* apply srtp */
stat = srtp_unprotect(receiver->srtp_ctx, &receiver->message.header,
&octets_recvd);
if (stat) {
fprintf(stderr, "error: srtp unprotection failed with code %d%s\n",
stat,
stat == srtp_err_status_replay_fail
? " (replay check failed)"
: stat == srtp_err_status_auth_fail ? " (auth check failed)"
: "");
return -1;
}
strncpy(msg, receiver->message.body, octets_recvd);
return octets_recvd;
}
int
rtp_sender_init(rtp_sender_t sender,
int sock,
struct sockaddr_in addr,
unsigned int ssrc) {
int rtp_sender_init(rtp_sender_t sender,
int sock,
struct sockaddr_in addr,
unsigned int ssrc)
{
/* set header values */
sender->message.header.ssrc = htonl(ssrc);
sender->message.header.ts = 0;
sender->message.header.seq = (uint16_t)rand();
sender->message.header.m = 0;
sender->message.header.pt = 0x1;
sender->message.header.version = 2;
sender->message.header.p = 0;
sender->message.header.x = 0;
sender->message.header.cc = 0;
/* set header values */
sender->message.header.ssrc = htonl(ssrc);
sender->message.header.ts = 0;
sender->message.header.seq = (uint16_t) rand();
sender->message.header.m = 0;
sender->message.header.pt = 0x1;
sender->message.header.version = 2;
sender->message.header.p = 0;
sender->message.header.x = 0;
sender->message.header.cc = 0;
/* set other stuff */
sender->socket = sock;
sender->addr = addr;
/* set other stuff */
sender->socket = sock;
sender->addr = addr;
return 0;
return 0;
}
int
rtp_receiver_init(rtp_receiver_t rcvr,
int sock,
struct sockaddr_in addr,
unsigned int ssrc) {
/* set header values */
rcvr->message.header.ssrc = htonl(ssrc);
rcvr->message.header.ts = 0;
rcvr->message.header.seq = 0;
rcvr->message.header.m = 0;
rcvr->message.header.pt = 0x1;
rcvr->message.header.version = 2;
rcvr->message.header.p = 0;
rcvr->message.header.x = 0;
rcvr->message.header.cc = 0;
int rtp_receiver_init(rtp_receiver_t rcvr,
int sock,
struct sockaddr_in addr,
unsigned int ssrc)
{
/* set header values */
rcvr->message.header.ssrc = htonl(ssrc);
rcvr->message.header.ts = 0;
rcvr->message.header.seq = 0;
rcvr->message.header.m = 0;
rcvr->message.header.pt = 0x1;
rcvr->message.header.version = 2;
rcvr->message.header.p = 0;
rcvr->message.header.x = 0;
rcvr->message.header.cc = 0;
/* set other stuff */
rcvr->socket = sock;
rcvr->addr = addr;
/* set other stuff */
rcvr->socket = sock;
rcvr->addr = addr;
return 0;
return 0;
}
int
rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) {
return srtp_create(&sender->srtp_ctx, policy);
int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy)
{
return srtp_create(&sender->srtp_ctx, policy);
}
int
rtp_sender_deinit_srtp(rtp_sender_t sender) {
return srtp_dealloc(sender->srtp_ctx);
int rtp_sender_deinit_srtp(rtp_sender_t sender)
{
return srtp_dealloc(sender->srtp_ctx);
}
int
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) {
return srtp_create(&sender->srtp_ctx, policy);
int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy)
{
return srtp_create(&sender->srtp_ctx, policy);
}
int
rtp_receiver_deinit_srtp(rtp_receiver_t sender) {
return srtp_dealloc(sender->srtp_ctx);
int rtp_receiver_deinit_srtp(rtp_receiver_t sender)
{
return srtp_dealloc(sender->srtp_ctx);
}
rtp_sender_t
rtp_sender_alloc(void) {
return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
rtp_sender_t rtp_sender_alloc(void)
{
return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
}
void
rtp_sender_dealloc(rtp_sender_t rtp_ctx) {
free(rtp_ctx);
void rtp_sender_dealloc(rtp_sender_t rtp_ctx)
{
free(rtp_ctx);
}
rtp_receiver_t
rtp_receiver_alloc(void) {
return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
rtp_receiver_t rtp_receiver_alloc(void)
{
return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
}
void
rtp_receiver_dealloc(rtp_receiver_t rtp_ctx) {
free(rtp_ctx);
void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx)
{
free(rtp_ctx);
}

View File

@ -1,6 +1,6 @@
/*
* rtp.h
*
*
* rtp interface for srtp reference implementation
*
* David A. McGrew
@ -15,26 +15,26 @@
*/
/*
*
*
* 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
@ -50,14 +50,13 @@
*
*/
#ifndef SRTP_RTP_H
#define SRTP_RTP_H
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#include <netinet/in.h>
#elif defined HAVE_WINSOCK2_H
# include <winsock2.h>
#include <winsock2.h>
#endif
#include "srtp_priv.h"
@ -69,98 +68,85 @@ extern "C" {
/*
* RTP_HEADER_LEN indicates the size of an RTP header
*/
#define RTP_HEADER_LEN 12
#define RTP_HEADER_LEN 12
/*
/*
* RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
*/
#define RTP_MAX_BUF_LEN 16384
#define RTP_MAX_BUF_LEN 16384
typedef srtp_hdr_t rtp_hdr_t;
typedef struct {
srtp_hdr_t header;
char body[RTP_MAX_BUF_LEN];
srtp_hdr_t header;
char body[RTP_MAX_BUF_LEN];
} rtp_msg_t;
typedef struct rtp_sender_ctx_t {
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* reciever's address */
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* reciever's address */
} rtp_sender_ctx_t;
typedef struct rtp_receiver_ctx_t {
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* receiver's address */
rtp_msg_t message;
int socket;
srtp_ctx_t *srtp_ctx;
struct sockaddr_in addr; /* receiver's address */
} rtp_receiver_ctx_t;
typedef struct rtp_sender_ctx_t *rtp_sender_t;
typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
int
rtp_sendto(rtp_sender_t sender, const void* msg, int len);
int rtp_sendto(rtp_sender_t sender, const void *msg, int len);
int
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
int
rtp_receiver_init(rtp_receiver_t rcvr, int sock,
struct sockaddr_in addr, unsigned int ssrc);
int rtp_receiver_init(rtp_receiver_t rcvr,
int sock,
struct sockaddr_in addr,
unsigned int ssrc);
int
rtp_sender_init(rtp_sender_t sender, int sock,
struct sockaddr_in addr, unsigned int ssrc);
int rtp_sender_init(rtp_sender_t sender,
int sock,
struct sockaddr_in addr,
unsigned int ssrc);
/*
* srtp_sender_init(...) initializes an rtp_sender_t
*/
int
srtp_sender_init(rtp_sender_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
srtp_sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int srtp_sender_init(
rtp_sender_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
srtp_sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int
srtp_receiver_init(rtp_receiver_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
srtp_sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int srtp_receiver_init(
rtp_receiver_t rtp_ctx, /* structure to be init'ed */
struct sockaddr_in name, /* socket name */
srtp_sec_serv_t security_services, /* sec. servs. to be used */
unsigned char *input_key /* master key/salt in hex */
);
int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
int
rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
int rtp_sender_deinit_srtp(rtp_sender_t sender);
int
rtp_sender_deinit_srtp(rtp_sender_t sender);
int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
int
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
int rtp_receiver_deinit_srtp(rtp_receiver_t sender);
int
rtp_receiver_deinit_srtp(rtp_receiver_t sender);
rtp_sender_t rtp_sender_alloc(void);
void rtp_sender_dealloc(rtp_sender_t rtp_ctx);
rtp_sender_t
rtp_sender_alloc(void);
void
rtp_sender_dealloc(rtp_sender_t rtp_ctx);
rtp_receiver_t
rtp_receiver_alloc(void);
void
rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
rtp_receiver_t rtp_receiver_alloc(void);
void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
#ifdef __cplusplus
}

View File

@ -4,14 +4,19 @@
* decoder structures and functions for SRTP pcap decoder
*
* Example:
* $ wget --no-check-certificate https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
* $ ./test/rtp_decoder -a -t 10 -e 128 -b aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
* < ~/marseillaise-srtp.pcap | text2pcap -t "%M:%S." -u 10000,10000 - - > ./marseillaise-rtp.pcap
* $ wget --no-check-certificate \
* https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
* $ ./test/rtp_decoder -a -t 10 -e 128 -b \
* aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
* < ~/marseillaise-srtp.pcap \
* | text2pcap -t "%M:%S." -u 10000,10000 - - \
* > ./marseillaise-rtp.pcap
*
* There is also a different way of setting up key size and tag size
* based upon RFC 4568 crypto suite specification, i.e.:
*
* $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
* $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b \
* aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
*
* Audio can be extracted using extractaudio utility from the RTPproxy
* package:
@ -23,26 +28,26 @@
* Some structure and code from https://github.com/gteissier/srtp-decrypt
*/
/*
*
*
* 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
@ -57,471 +62,506 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "getopt_s.h" /* for local getopt() */
#include <assert.h> /* for assert() */
#include "getopt_s.h" /* for local getopt() */
#include <assert.h> /* for assert() */
#include <pcap.h>
#include "rtp_decoder.h"
#include "util.h"
#define MAX_KEY_LEN 96
#ifndef timersub
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
#define MAX_KEY_LEN 96
#define MAX_FILTER 256
struct srtp_crypto_suite {
const char *can_name;
int key_size;
int tag_size;
const char *can_name;
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},
{.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},
#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 = NULL}
{.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 = NULL }
};
int
main (int argc, char *argv[]) {
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 pcap_net = 0;
pcap_t *pcap_handle;
int main(int argc, char *argv[])
{
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 pcap_net = 0;
pcap_t *pcap_handle;
#if BEW
struct sockaddr_in local;
struct sockaddr_in local;
#endif
srtp_sec_serv_t sec_servs = sec_serv_none;
int c;
struct srtp_crypto_suite scs, *i_scsp;
scs.key_size = 128;
scs.tag_size = 8;
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] = "";
rtp_decoder_t dec;
srtp_policy_t policy;
srtp_err_status_t status;
int len;
int expected_len;
int do_list_mods = 0;
srtp_sec_serv_t sec_servs = sec_serv_none;
int c;
struct srtp_crypto_suite scs, *i_scsp;
scs.key_size = 128;
scs.tag_size = 8;
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] = "";
rtp_decoder_t dec;
srtp_policy_t policy;
srtp_err_status_t status;
int len;
int expected_len;
int do_list_mods = 0;
fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(),
srtp_get_version());
/* initialize srtp library */
status = srtp_init();
if (status) {
fprintf(stderr, "error: srtp initialization failed with error code %d\n", status);
exit(1);
}
/* check args */
while (1) {
c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:");
if (c == -1) {
break;
/* initialize srtp library */
status = srtp_init();
if (status) {
fprintf(stderr,
"error: srtp initialization failed with error code %d\n",
status);
exit(1);
}
switch (c) {
case 'b':
b64_input = 1;
/* fall thru */
case 'k':
input_key = optarg_s;
break;
case 'e':
scs.key_size = atoi(optarg_s);
if (scs.key_size != 128 && scs.key_size != 256) {
fprintf(stderr, "error: encryption key size must be 128 or 256 (%d)\n", scs.key_size);
exit(1);
}
input_key = malloc(scs.key_size);
sec_servs |= sec_serv_conf;
break;
case 't':
scs.tag_size = atoi(optarg_s);
break;
case 'a':
sec_servs |= sec_serv_auth;
break;
case 'g':
gcm_on = 1;
sec_servs |= sec_serv_auth;
break;
case 'd':
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
fprintf(stderr, "error: set debug module (%s) failed\n", optarg_s);
exit(1);
}
break;
case 'f':
if(strlen(optarg_s) > MAX_FILTER){
fprintf(stderr, "error: filter bigger than %d characters\n", MAX_FILTER);
exit(1);
}
fprintf(stderr, "Setting filter as %s\n", optarg_s);
strcpy(filter_exp, optarg_s);
break;
case 'l':
do_list_mods = 1;
break;
case 's':
for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL; i_scsp++) {
if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
/* check args */
while (1) {
c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:");
if (c == -1) {
break;
}
}
if (i_scsp->can_name == NULL) {
fprintf(stderr, "Unknown/unsupported crypto suite name %s\n", optarg_s);
exit(1);
}
scs = *i_scsp;
input_key = malloc(scs.key_size);
sec_servs |= sec_serv_conf | sec_serv_auth;
break;
default:
usage(argv[0]);
switch (c) {
case 'b':
b64_input = 1;
/* fall thru */
case 'k':
input_key = optarg_s;
break;
case 'e':
scs.key_size = atoi(optarg_s);
if (scs.key_size != 128 && scs.key_size != 256) {
fprintf(stderr,
"error: encryption key size must be 128 or 256 (%d)\n",
scs.key_size);
exit(1);
}
input_key = malloc(scs.key_size);
sec_servs |= sec_serv_conf;
break;
case 't':
scs.tag_size = atoi(optarg_s);
break;
case 'a':
sec_servs |= sec_serv_auth;
break;
case 'g':
gcm_on = 1;
sec_servs |= sec_serv_auth;
break;
case 'd':
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (status) {
fprintf(stderr, "error: set debug module (%s) failed\n",
optarg_s);
exit(1);
}
break;
case 'f':
if (strlen(optarg_s) > MAX_FILTER) {
fprintf(stderr, "error: filter bigger than %d characters\n",
MAX_FILTER);
exit(1);
}
fprintf(stderr, "Setting filter as %s\n", optarg_s);
strcpy(filter_exp, optarg_s);
break;
case 'l':
do_list_mods = 1;
break;
case 's':
for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL;
i_scsp++) {
if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
break;
}
}
if (i_scsp->can_name == NULL) {
fprintf(stderr, "Unknown/unsupported crypto suite name %s\n",
optarg_s);
exit(1);
}
scs = *i_scsp;
input_key = malloc(scs.key_size);
sec_servs |= sec_serv_conf | sec_serv_auth;
break;
default:
usage(argv[0]);
}
}
}
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);
}
if (do_list_mods) {
status = srtp_crypto_kernel_list_debug_modules();
if (status) {
fprintf(stderr, "error: list of debug modules failed\n");
exit(1);
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);
}
return 0;
}
if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
/*
* a key must be provided if and only if security services have
* been requested
*/
if(input_key == NULL){
fprintf(stderr, "key not provided\n");
}
if(!sec_servs){
fprintf(stderr, "no secservs\n");
}
fprintf(stderr, "provided\n");
usage(argv[0]);
}
if (do_list_mods) {
status = srtp_crypto_kernel_list_debug_modules();
if (status) {
fprintf(stderr, "error: list of debug modules failed\n");
exit(1);
}
return 0;
}
if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
/*
* a key must be provided if and only if security services have
* been requested
*/
if (input_key == NULL) {
fprintf(stderr, "key not provided\n");
}
if (!sec_servs) {
fprintf(stderr, "no secservs\n");
}
fprintf(stderr, "provided\n");
usage(argv[0]);
}
/* report security services selected on the command line */
fprintf(stderr, "security services: ");
if (sec_servs & sec_serv_conf)
fprintf(stderr, "confidentiality ");
if (sec_servs & sec_serv_auth)
fprintf(stderr, "message authentication");
if (sec_servs == sec_serv_none)
fprintf(stderr, "none");
fprintf(stderr, "\n");
/* report security services selected on the command line */
fprintf(stderr, "security services: ");
if (sec_servs & sec_serv_conf)
fprintf(stderr, "confidentiality ");
if (sec_servs & sec_serv_auth)
fprintf(stderr, "message authentication");
if (sec_servs == sec_serv_none)
fprintf(stderr, "none");
fprintf(stderr, "\n");
/* set up the srtp policy and master key */
if (sec_servs) {
/*
* create policy structure, using the default mechanisms but
* with only the security services requested on the command line,
* using the right SSRC value
*/
switch (sec_servs) {
case sec_serv_conf_and_auth:
if (gcm_on) {
/* set up the srtp policy and master key */
if (sec_servs) {
/*
* create policy structure, using the default mechanisms but
* with only the security services requested on the command line,
* using the right SSRC value
*/
switch (sec_servs) {
case sec_serv_conf_and_auth:
if (gcm_on) {
#ifdef OPENSSL
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
break;
}
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
break;
}
#else
fprintf(stderr, "error: GCM mode only supported when using the OpenSSL crypto engine.\n");
return 0;
fprintf(stderr, "error: GCM mode only supported when using the "
"OpenSSL crypto engine.\n");
return 0;
#endif
} else {
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_rtp_default(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
}
}
break;
case sec_serv_conf:
if (gcm_on) {
fprintf(stderr, "error: GCM mode must always be used with auth enabled\n");
return -1;
} else {
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);
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
}
}
break;
case sec_serv_auth:
if (gcm_on) {
} else {
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_rtp_default(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
}
}
break;
case sec_serv_conf:
if (gcm_on) {
fprintf(
stderr,
"error: GCM mode must always be used with auth enabled\n");
return -1;
} else {
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);
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
break;
}
}
break;
case sec_serv_auth:
if (gcm_on) {
#ifdef OPENSSL
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtcp);
break;
}
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
&policy.rtcp);
break;
case 256:
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
&policy.rtcp);
break;
}
#else
printf("error: GCM mode only supported when using the OpenSSL crypto engine.\n");
return 0;
printf("error: GCM mode only supported when using the OpenSSL "
"crypto engine.\n");
return 0;
#endif
} else {
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
}
break;
default:
fprintf(stderr, "error: unknown security service requested\n");
return -1;
}
} else {
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
}
break;
default:
fprintf(stderr, "error: unknown security service requested\n");
return -1;
}
policy.key = (uint8_t *) key;
policy.ekt = NULL;
policy.next = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.rtp.sec_serv = sec_servs;
policy.rtcp.sec_serv = sec_servs; //sec_serv_none; /* we don't do RTCP anyway */
fprintf(stderr, "setting tag len %d\n", scs.tag_size);
policy.rtp.auth_tag_len = scs.tag_size;
policy.key = (uint8_t *)key;
policy.ekt = NULL;
policy.next = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.rtp.sec_serv = sec_servs;
policy.rtcp.sec_serv =
sec_servs; // sec_serv_none; /* we don't do RTCP anyway */
fprintf(stderr, "setting tag len %d\n", scs.tag_size);
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);
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);
policy.rtp.auth_tag_len = scs.tag_size;
}
/*
* read key from hexadecimal or base64 on command line into an octet
* string
*/
if (b64_input) {
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);
}
} else {
expected_len = policy.rtp.cipher_key_len * 2;
len = hex_string_to_octet_string(key, input_key, expected_len);
}
/* check that hex string is the right length */
if (len < expected_len) {
fprintf(stderr, "error: too few digits in key/salt "
"(should be %d digits, found %d)\n",
expected_len, len);
exit(1);
}
if (strlen(input_key) > policy.rtp.cipher_key_len * 2) {
fprintf(stderr, "error: too many digits in key/salt "
"(should be %d hexadecimal digits, found %u)\n",
policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
exit(1);
}
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));
/*
* read key from hexadecimal or base64 on command line into an octet string
*/
if (b64_input) {
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);
}
} else {
expected_len = policy.rtp.cipher_key_len*2;
len = hex_string_to_octet_string(key, input_key, expected_len);
}
/* check that hex string is the right length */
if (len < expected_len) {
fprintf(stderr,
"error: too few digits in key/salt "
"(should be %d digits, found %d)\n",
expected_len, len);
exit(1);
}
if (strlen(input_key) > policy.rtp.cipher_key_len*2) {
fprintf(stderr,
"error: too many digits in key/salt "
"(should be %d hexadecimal digits, found %u)\n",
policy.rtp.cipher_key_len*2, (unsigned)strlen(input_key));
exit(1);
fprintf(stderr,
"error: neither encryption or authentication were selected");
exit(1);
}
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));
pcap_handle = pcap_open_offline("-", errbuf);
} else {
fprintf(stderr, "error: neither encryption or authentication were selected");
exit(1);
}
if (!pcap_handle) {
fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
exit(1);
}
assert(pcap_handle != NULL);
if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
pcap_geterr(pcap_handle));
return (2);
}
if (pcap_setfilter(pcap_handle, &fp) == -1) {
fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
pcap_geterr(pcap_handle));
return (2);
}
dec = rtp_decoder_alloc();
if (dec == NULL) {
fprintf(stderr, "error: malloc() failed\n");
exit(1);
}
fprintf(stderr, "Starting decoder\n");
rtp_decoder_init(dec, policy);
pcap_handle = pcap_open_offline("-", errbuf);
pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
if (!pcap_handle) {
fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
exit(1);
}
assert(pcap_handle != NULL);
if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
pcap_geterr(pcap_handle));
return (2);
}
if (pcap_setfilter(pcap_handle, &fp) == -1) {
fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
pcap_geterr(pcap_handle));
return (2);
}
dec = rtp_decoder_alloc();
if (dec == NULL) {
fprintf(stderr, "error: malloc() failed\n");
exit(1);
}
fprintf(stderr, "Starting decoder\n");
rtp_decoder_init(dec, policy);
rtp_decoder_deinit_srtp(dec);
rtp_decoder_dealloc(dec);
pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
status = srtp_shutdown();
if (status) {
fprintf(stderr, "error: srtp shutdown failed with error code %d\n",
status);
exit(1);
}
rtp_decoder_deinit_srtp(dec);
rtp_decoder_dealloc(dec);
return 0;
}
status = srtp_shutdown();
if (status) {
fprintf(stderr, "error: srtp shutdown failed with error code %d\n", status);
void usage(char *string)
{
fprintf(
stderr,
"usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
"or %s -l\n"
"where -a use message authentication\n"
" -e <key size> use encryption (use 128 or 256 for key size)\n"
" -g Use AES-GCM mode (must be used with -e)\n"
" -t <tag size> Tag size to use (in GCM mode use 8 or 16)\n"
" -k <key> sets the srtp master key given in hexadecimal\n"
" -b <key> sets the srtp master key given in base64\n"
" -l list debug modules\n"
" -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",
string, string);
exit(1);
}
return 0;
}
void
usage(char *string) {
fprintf(stderr, "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
"or %s -l\n"
"where -a use message authentication\n"
" -e <key size> use encryption (use 128 or 256 for key size)\n"
" -g Use AES-GCM mode (must be used with -e)\n"
" -t <tag size> Tag size to use (in GCM mode use 8 or 16)\n"
" -k <key> sets the srtp master key given in hexadecimal\n"
" -b <key> sets the srtp master key given in base64\n"
" -l list debug modules\n"
" -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",
string, string);
exit(1);
rtp_decoder_t rtp_decoder_alloc(void)
{
return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
}
rtp_decoder_t
rtp_decoder_alloc(void) {
return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
{
free(rtp_ctx);
}
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);
}
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)
{
return srtp_dealloc(decoder->srtp_ctx);
}
int
rtp_decoder_deinit_srtp(rtp_decoder_t decoder) {
return srtp_dealloc(decoder->srtp_ctx);
}
int
rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy) {
dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
dcdr->srtp_ctx = NULL;
dcdr->start_tv.tv_usec = 0;
dcdr->start_tv.tv_sec = 0;
dcdr->frame_nr = -1;
dcdr->policy = policy;
dcdr->policy.ssrc.type = ssrc_specific;
return 0;
int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy)
{
dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
dcdr->srtp_ctx = NULL;
dcdr->start_tv.tv_usec = 0;
dcdr->start_tv.tv_sec = 0;
dcdr->frame_nr = -1;
dcdr->policy = policy;
dcdr->policy.ssrc.type = ssrc_specific;
return 0;
}
/*
* decodes key as base64
*/
void hexdump(const void *ptr, size_t size) {
int i, j;
const unsigned char *cptr = ptr;
void hexdump(const void *ptr, size_t size)
{
int i, j;
const unsigned char *cptr = ptr;
for (i = 0; i < size; i += 16) {
fprintf(stdout, "%04x ", i);
for (j = 0; j < 16 && i+j < size; j++) {
fprintf(stdout, "%02x ", cptr[i+j]);
for (i = 0; i < size; i += 16) {
fprintf(stdout, "%04x ", i);
for (j = 0; j < 16 && i + j < size; j++) {
fprintf(stdout, "%02x ", cptr[i + j]);
}
fprintf(stdout, "\n");
}
fprintf(stdout, "\n");
}
}
void
rtp_decoder_handle_pkt(u_char *arg, const struct pcap_pkthdr *hdr,
const u_char *bytes) {
rtp_decoder_t dcdr = (rtp_decoder_t)arg;
int pktsize;
struct timeval delta;
int octets_recvd;
srtp_err_status_t status;
dcdr->frame_nr++;
void rtp_decoder_handle_pkt(u_char *arg,
const struct pcap_pkthdr *hdr,
const u_char *bytes)
{
rtp_decoder_t dcdr = (rtp_decoder_t)arg;
int pktsize;
struct timeval delta;
int octets_recvd;
srtp_err_status_t status;
dcdr->frame_nr++;
if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
dcdr->start_tv = hdr->ts;
}
if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
dcdr->start_tv = hdr->ts;
}
if (hdr->caplen < dcdr->rtp_offset) {
return;
}
const void *rtp_packet = bytes + dcdr->rtp_offset;
if (hdr->caplen < dcdr->rtp_offset) {
return;
}
const void *rtp_packet = bytes + dcdr->rtp_offset;
memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
pktsize = hdr->caplen - dcdr->rtp_offset;
octets_recvd = pktsize;
memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
pktsize = hdr->caplen - dcdr->rtp_offset;
octets_recvd = pktsize;
if (octets_recvd == -1) {
return;
}
if (octets_recvd == -1) {
return;
}
/* verify rtp header */
if (dcdr->message.header.version != 2) {
return;
}
if(dcdr->srtp_ctx == NULL) {
status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
/* verify rtp header */
if (dcdr->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);
if (status) {
exit(1);
return;
}
}
status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
if (status) {
return;
}
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);
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);
}
void rtp_print_error(srtp_err_status_t status, char *message) {
void rtp_print_error(srtp_err_status_t status, char *message)
{
// clang-format off
fprintf(stderr,
"error: %s %d%s\n", message, status,
status == srtp_err_status_replay_fail ? " (replay check failed)" :
@ -530,4 +570,5 @@ void rtp_print_error(srtp_err_status_t status, char *message) {
status == srtp_err_status_cipher_fail ? " (cipher failed)" :
status == srtp_err_status_key_expired ? " (key expired)" :
status == srtp_err_status_auth_fail ? " (auth check failed)" : "");
// clang-format on
}

View File

@ -9,26 +9,26 @@
*
*/
/*
*
*
* 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
@ -44,7 +44,6 @@
*
*/
#ifndef RTP_DECODER_H
#define RTP_DECODER_H
@ -54,12 +53,12 @@
#define DEFAULT_RTP_OFFSET 42
typedef struct rtp_decoder_ctx_t {
srtp_policy_t policy;
srtp_ctx_t *srtp_ctx;
int rtp_offset;
struct timeval start_tv;
int frame_nr;
rtp_msg_t message;
srtp_policy_t policy;
srtp_ctx_t *srtp_ctx;
int rtp_offset;
struct timeval start_tv;
int frame_nr;
rtp_msg_t message;
} rtp_decoder_ctx_t;
typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
@ -69,7 +68,7 @@ typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
*/
void rtp_print_error(srtp_err_status_t status, char *message);
/*
/*
* prints the output of a random buffer in hexadecimal
*/
void hexdump(const void *ptr, size_t size);
@ -85,10 +84,12 @@ void usage(char *prog_name);
*/
char *decode_sdes(char *in, char *out);
/*
/*
* pcap handling
*/
void rtp_decoder_handle_pkt(u_char *arg, const struct pcap_pkthdr *hdr, const u_char *bytes);
void rtp_decoder_handle_pkt(u_char *arg,
const struct pcap_pkthdr *hdr,
const u_char *bytes);
rtp_decoder_t rtp_decoder_alloc(void);
@ -96,9 +97,9 @@ void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx);
int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy);
srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder, unsigned int ssrc);
srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
unsigned int ssrc);
int
rtp_decoder_deinit_srtp(rtp_decoder_t decoder);
int rtp_decoder_deinit_srtp(rtp_decoder_t decoder);
#endif /* RTP_DECODER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -72,13 +72,13 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number(void);
* item is the test function.
*/
TEST_LIST = {{"srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()",
srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output},
{"srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()",
srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param},
{"srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()",
srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number},
{NULL} /* End of tests */};
TEST_LIST = { { "srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()",
srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output },
{ "srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()",
srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param },
{ "srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()",
srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number },
{ NULL } /* End of tests */ };
/*
* Implementation.
@ -146,9 +146,9 @@ void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()
*/
void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
{
#define SAMPLE_COUNT (3)
// Preconditions
// Test each significant bit high in each full byte.
#define SAMPLE_COUNT (3)
srtp_session_keys_t session_keys;
srtcp_hdr_t header;
v128_t output_iv[SAMPLE_COUNT];
@ -173,13 +173,13 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
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], &header)
== srtp_err_status_ok);
sequence_num[i],
&header) == srtp_err_status_ok);
}
// Then all IVs are as expected
for (i = 0; i < SAMPLE_COUNT; i++) {
TEST_CHECK(memcmp(&final_iv[i], &output_iv[i], sizeof(v128_t)) == 0);
}
#undef SAMPLE_COUNT
#undef SAMPLE_COUNT
}

View File

@ -49,38 +49,61 @@
char bit_string[MAX_PRINT_STRING_LEN];
static inline int hex_char_to_nibble (uint8_t c)
static inline int hex_char_to_nibble(uint8_t c)
{
switch (c) {
case ('0'): return 0x0;
case ('1'): return 0x1;
case ('2'): return 0x2;
case ('3'): return 0x3;
case ('4'): return 0x4;
case ('5'): return 0x5;
case ('6'): return 0x6;
case ('7'): return 0x7;
case ('8'): return 0x8;
case ('9'): return 0x9;
case ('a'): return 0xa;
case ('A'): return 0xa;
case ('b'): return 0xb;
case ('B'): return 0xb;
case ('c'): return 0xc;
case ('C'): return 0xc;
case ('d'): return 0xd;
case ('D'): return 0xd;
case ('e'): return 0xe;
case ('E'): return 0xe;
case ('f'): return 0xf;
case ('F'): return 0xf;
default: return -1; /* this flags an error */
case ('0'):
return 0x0;
case ('1'):
return 0x1;
case ('2'):
return 0x2;
case ('3'):
return 0x3;
case ('4'):
return 0x4;
case ('5'):
return 0x5;
case ('6'):
return 0x6;
case ('7'):
return 0x7;
case ('8'):
return 0x8;
case ('9'):
return 0x9;
case ('a'):
return 0xa;
case ('A'):
return 0xa;
case ('b'):
return 0xb;
case ('B'):
return 0xb;
case ('c'):
return 0xc;
case ('C'):
return 0xc;
case ('d'):
return 0xd;
case ('D'):
return 0xd;
case ('e'):
return 0xe;
case ('E'):
return 0xe;
case ('f'):
return 0xf;
case ('F'):
return 0xf;
default:
return -1; /* this flags an error */
}
/* NOTREACHED */
return -1; /* this keeps compilers from complaining */
}
uint8_t nibble_to_hex_char (uint8_t nibble)
uint8_t nibble_to_hex_char(uint8_t nibble)
{
char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
@ -92,7 +115,7 @@ uint8_t nibble_to_hex_char (uint8_t nibble)
* hex_string_to_octet_string converts a hexadecimal string
* of length 2 * len to a raw octet string of length len
*/
int hex_string_to_octet_string (char *raw, char *hex, int len)
int hex_string_to_octet_string(char *raw, char *hex, int len)
{
uint8_t x;
int tmp;
@ -118,9 +141,9 @@ int hex_string_to_octet_string (char *raw, char *hex, int len)
return hex_len;
}
char * octet_string_hex_string (const void *s, int length)
char *octet_string_hex_string(const void *s, int length)
{
const uint8_t *str = (const uint8_t*)s;
const uint8_t *str = (const uint8_t *)s;
int i;
/* double length, since one octet takes two hex characters */
@ -132,7 +155,7 @@ char * octet_string_hex_string (const void *s, int length)
}
for (i = 0; i < length; i += 2) {
bit_string[i] = nibble_to_hex_char(*str >> 4);
bit_string[i] = nibble_to_hex_char(*str >> 4);
bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF);
}
bit_string[i] = 0; /* null terminate string */
@ -142,9 +165,9 @@ char * octet_string_hex_string (const void *s, int length)
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
static int base64_block_to_octet_triple (char *out, char *in)
static int base64_block_to_octet_triple(char *out, char *in)
{
unsigned char sextets[4] = {0};
unsigned char sextets[4] = { 0 };
int j = 0;
int i;
@ -152,7 +175,9 @@ static int base64_block_to_octet_triple (char *out, char *in)
char *p = strchr(b64chars, in[i]);
if (p != NULL) {
sextets[i] = p - b64chars;
} else{ j++; }
} else {
j++;
}
}
out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
@ -165,7 +190,7 @@ static int base64_block_to_octet_triple (char *out, char *in)
return j;
}
int base64_string_to_octet_string (char *out, int *pad, char *in, int len)
int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
{
int k = 0;
int i = 0;

View File

@ -47,7 +47,7 @@
#define MAX_PRINT_STRING_LEN 1024
int hex_string_to_octet_string(char *raw, char *hex, int len);
char * octet_string_hex_string(const void *s, int length);
char *octet_string_hex_string(const void *s, int length);
int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len);
#endif

View File

@ -112,6 +112,7 @@
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\libs\apr\include\arch\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_WINSOCK2_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<PostBuildEvent>
<Command>if not exist "$(OutDir)conf" xcopy "$(SolutionDir)conf\vanilla\*.*" "$(OutDir)conf\" /C /D /Y /S

View File

@ -68,7 +68,7 @@
<AdditionalIncludeDirectories>$(OpenSSLLibDir)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Platform)'=='Win32'">$(OpenSSLLibDir)\include_x86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Platform)'=='x64'">$(OpenSSLLibDir)\include_x64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>OPENSSL;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OpenSSLLibDir)\binaries\$(Platform)\$(LibraryConfiguration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>