FS-9785: upgrade libsrtp to 2.1

This commit is contained in:
Mike Jerris 2017-06-26 12:11:02 -05:00
parent 19e8621682
commit 3bcf5b7ff8
129 changed files with 21084 additions and 21652 deletions

View File

@ -584,14 +584,11 @@ libs/apr-util/libaprutil-1.la: libs/apr/libapr-1.la libs/apr-util libs/apr-util/
SRTP_SRC = libs/srtp/srtp/srtp.c libs/srtp/srtp/ekt.c libs/srtp/crypto/cipher/cipher.c libs/srtp/crypto/cipher/null_cipher.c \ SRTP_SRC = libs/srtp/srtp/srtp.c libs/srtp/srtp/ekt.c libs/srtp/crypto/cipher/cipher.c libs/srtp/crypto/cipher/null_cipher.c \
libs/srtp/crypto/cipher/aes.c libs/srtp/crypto/cipher/aes_icm.c \ libs/srtp/crypto/cipher/aes.c libs/srtp/crypto/cipher/aes_icm.c \
libs/srtp/crypto/cipher/aes_cbc.c \
libs/srtp/crypto/hash/null_auth.c libs/srtp/crypto/hash/sha1.c \ libs/srtp/crypto/hash/null_auth.c libs/srtp/crypto/hash/sha1.c \
libs/srtp/crypto/hash/hmac.c libs/srtp/crypto/hash/auth.c \ libs/srtp/crypto/hash/hmac.c libs/srtp/crypto/hash/auth.c \
libs/srtp/crypto/math/datatypes.c libs/srtp/crypto/math/stat.c \ libs/srtp/crypto/math/datatypes.c libs/srtp/crypto/math/stat.c \
libs/srtp/crypto/kernel/crypto_kernel.c libs/srtp/crypto/kernel/alloc.c \ libs/srtp/crypto/kernel/crypto_kernel.c libs/srtp/crypto/kernel/alloc.c \
libs/srtp/crypto/kernel/key.c \ libs/srtp/crypto/kernel/key.c libs/srtp/crypto/kernel/err.c \
libs/srtp/crypto/rng/prng.c libs/srtp/crypto/rng/ctr_prng.c \
libs/srtp/crypto/kernel/err.c libs/srtp/crypto/rng/rand_source.c \
libs/srtp/crypto/replay/rdb.c libs/srtp/crypto/replay/rdbx.c libs/srtp/crypto/replay/ut_sim.c libs/srtp/crypto/replay/rdb.c libs/srtp/crypto/replay/rdbx.c libs/srtp/crypto/replay/ut_sim.c
libs/srtp/libsrtp.la: libs/srtp libs/srtp/.update $(SRTP_SRC) libs/srtp/libsrtp.la: libs/srtp libs/srtp/.update $(SRTP_SRC)

View File

@ -1,223 +1,167 @@
Changelog Changelog
1.3.20 2.1.0
Lots of changes. Thanks to Jeff Chan for catching a memory leak and Compatibility changes
helping track down the endian issues with the SSRCs.
1.3.8 PR #253 - Cipher type cleanup for AES
When libSRTP is compiled with OpenSSL and the AES 256 ICM cipher is used
with RTCP an incorrect initialization vector is formed.
This change will break backwards compatibility with older versions (1.5,
2.0) of libSRTP when using the AES 256 ICM cipher with OpenSSL for RTCP.
This is an interim release. Several little-endian bugs were identified PR #259 - Sequence number incorrectly masked for AES GCM IV
and fixed; this means that we can use intel/linux for development again. The initialization vector for AES GCM encryption was incorrectly formed on
little endian machines.
This change will break backwards compatibility with older versions (1.5,
2.0) of libSRTP when using the AES GCM cipher for RTCP.
Cleaned up sha1 and hmac code significantly, got rid of some excess PR #287 - Fix OOB read in key generation for encrypted headers with GCM ciphers
functions and properly documented the fuctions in the .h files. Adds padding of GCM salt to the corresponding ICM length used for header
encryption.
This change will break backwards compatibility with version 2.0 of libSRTP
when using the header encryption extension with the AES GCM cipher.
Eliminated some vestigial files. Major changes
There is a SIGBUS error in the AES encrypt function on sparc PR #204 - OpenSSL performance improvements
(observed on both solaris and openbsd) with gcc 2.95. Was unable to Changed key expansion to occur once per key instead of once per packet.
find bad pointer anywhere, so I'm wondering if it isn't a compiler
problem (there's a known problem whose profile it fits). It doesn't
appear on any other platform, even in the cipher_driver stress
tests.
Planned changes PR #209 - Restore AES-192 under BoringSSL
BoringSSL supports AES-192 and is now enabled in libSRTP.
Change interface to nonces (xtd_seq_num_t) so that it uses PR #224 - Master Key Identifiers (MKI) Support patch
network byte ordering, and is consistent with other arguments. Adds MKI support with up to 4 keys.
PR #234 - Report SSRC instead of srtp_stream_t in srtp_event_data_t
srtp_stream_t is an opaque type making the event framework almost useless.
Now the SSRC is returned instead for use as a key in the public API.
1.3.6 PR #238 - Configure changes and improvements
CFLAGS check more shell neutral, quotation fixes, always generate and
install pkg-config file, improved OpenSSL discovery and linking, remove
-fPIC flag on Windows, fix shared library generation under Cygwin, replace
hardcoded CFLAGS with compiler checks, and regenerate configure after
configure.in changes.
Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to PR #241 & PR #261 - Improved logging API to receive log messages from libSRTP
/dev/urandom; the latter is non-blocking on all known platforms (which Provides a logging API and the ability to enable logging to stdout and a
corrects some programs that seem to hang) and is actually present on file, as well as a switch to enable all internal debug modules.
Open BSD (unlike /dev/random, which only works in the presence of
hardware supported random number generation).
Added machine/types.h case in include/integers.h. PR #289 - Added support for set and get the roll-over-counter
Adds an API to set and get the ROC in an (S)RTP session.
1.3.5 PR #304 - Fix (S)RTP and (S)RTCP for big endian machines
The structures srtp_hdr_t, srtcp_hdr_t and srtcp_trailer_t were defined
incorrectly on big endian systems.
Removing srtp_t::template and stream_clone(). Other changes
Adding a new policy structure, which will reflect a complete SRTP PR #149 - Don't create a symlink if there is no $(SHAREDLIBVERSION)
policy (including SRTCP).
This version is *incomplete* and will undergo more changes. It is PR #151 - Make srtp_driver compile for MIPS
provided only as a basis for discussion.
1.3.4 PR #160 - Use PKG_PROG_PKG_CONFIG to find correct pkg-config
Removed tmmh.c and tmmh.h, which implemented version one of TMMH. PR #167 - Additional RTCP and SRTCP tests
Changed srtp_get_trailer_length() to act on streams rather than PR #169 - Identified merge conflict created by commit 6b71fb9
sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should
usually be used rather than that function.
Removed 'salt' from cipher input. PR #173 - Avoid error 'possibly undefined macro: AM_PROG_AR'
Changed rdbx to use err.h error codes. PR #174 - Avoid warning 'The macro AC_TRY_LINK is obsolete.'
Changed malloc() and free() to xalloc() and xfree; these functions PR #175 - Remove 2nd -fPIC
are defined in crypto/kernel/alloc.c and declared in
include/alloc.h.
Added 'output' functions to cipher, in addition to 'encrypt' PR #182 - Add a length check before reading packet data
functions. It is no longer necessary to zeroize a buffer before
encrypting in order to get keystream.
Changed octet_string_hex_string() so that "times two" isn't needed PR #191 - On debug, output correct endianness of SSRC
in its input.
Added crypto_kernel_init() prior to command-line parsing, so that PR #192 - Replace octet_string_is_eq with a constant-time implementation
kernel can be passed command-line arguments, such as "-d
debug_module". This was done to for the applications
test/srtp-driver, test/kernel-driver, and test/ust-driver.
Improved srtp_init_aes_128_prf - wrote key derivation function PR #195 - Add missing __cplusplus header guards
(srtp_kdf_t).
Add the tag_len as an argument to the auth_compute() function, but PR #198 - Update sha1_driver.c to avoid memory leaks
not the corresponding macro. This change allows the tag length for
a given auth func to be set to different values at initialization
time. Previously, the structure auth_t contained the
output_length, but that value was inaccessible from hmac_compute()
and other functions.
Re-named files from a-b.c to a_b.c. in order to help portability. PR #202 - Add an explicit cast to avoid a printf format warning on macOS
Re-named rijndael to aes (or aes_128 as appropriate). PR #205 - Update Windows build files to Visual Studio 2015
PR #207 - Fix to install-win.bat syntax, and add installation of x64 libraries
1.2.1 PR #208 - Make replace_cipher and replace_auth public again
Changes so that 1.2.0 compiles on cygwin-win2k. PR #211 - Changes for OpenSSL 1.1.0 compatibility
Added better error reporting system. If syslog is present on the PR #213 - Add cast to `unsigned int` in call to printf in test
OS, then it is used.
PR #214 - Avoid empty initializer braces
1.2.0 Many improvements and additions, and a fex fixes PR #222 - Fix issue: No consistency when use some srtp_* functions
Fixed endian issues in RTP header construction in the function PR #231 - Advance version on master in preparation for 2.1 release
rtp_sendto() in srtp/rtp.c.
Implemented RIJNDAEL decryption operation, adding the functions PR #232 - Update Travis, do not build with OpenSSL on OSX
rijndael_decrypt() and rijndael_expand_decryption_key(). Also
re-named rijndael_expand_key() to rijndael_expand_encryption_key()
for consistency.
Implemented random number source using /dev/random, in the files PR #233 - crypto/replay/rdbx.c: Return type of srtp_index_guess from int to
crypto/rng/rand_source.c and include/rand_source.h. int32_t
Added index check to SEAL cipher (only values less than 2^32 are PR #236 - test/rtp_decoder.c: Removed superfluous conditional
allowed)
Added test case for null_auth authentication function. PR #237 - test/rtp_decoder.c: spring cleaning
Added a timing test which tests the effect of CPU cache thrash on PR #239 - octet_string_set_to_zero() delegates to OPENSSL_cleanse() if
cipher throughput. The test is done by the function available, if not it will use srtp_cleanse() to zero memory
cipher_test_throughput_array(); the function
cipher_array_alloc_init() creates an array of ciphers for use in
this test. This test can be accessed by using the -a flag to
the application cipher-driver in the test subdirectory.
Added argument processing to ust-driver.c, and added that app to
the 'runtest' target in Makefile.in.
A minor auth_t API change: last argument of auth_init() eliminated. PR #243 - EKT is not really supported yet, remove from install
PR #244 - Add simple error checking in timing test to avoid false results
1.0.6 A small but important fix PR #245 - Add missing srtp_cipher_dealloc calls when test fails
Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero() PR #246 - test/rtp_decoder: Add missing conditional
after buffer allocation.
Eliminated references to no-longer-existing variables in debugging PR #248 - New README.md that integrates intro, credits and references from
code in srtp/srtp.c. This fixes the compilation failure that /doc/ and is used to generate documentation
occured when using PRINT_DEBUG in that file.
Corrected spelling of Richard Priestley's name in credits. Sorry PR #249 - Remove support for generic aesicm from configure.in
Richard!
PR #250 - Update README.md, incorrect tag for link
1.0.5 Many little fixes PR #255 - Cleanup outdated comment related to MKI
Fixed octet_string_set_to_zero(), which was writing one PR #258 - Add AES-GCM to DTLS-SRTP Protection Profiles
more zero octet than it should. This bug caused srtp_protect()
and srtp_unprotect() to overwrite the byte that followed the
srtp packet.
Changed sizeof(uint32_t) to srtp_get_trailer_length() in PR #263 - Cleaning up and removing duplicated and outdated code
srtp-driver.c. This is just defensive coding.
Added NULL check to malloc in srtp_alloc(). PR #265 - Introduction of unit test framework: CUTest
PR #267 - crypto/kernel/err.c: Include datatypes.h
1.0.4 Many minor fixes and two big ones (thanks for the bug reports!) PR #272 - Reduce literal constants
Removed 'ssrc' from the srtp_init_aes_128_prf() function argument PR #273 - SRTP AEAD SRTCP initialization vector regression tests
list. This is so that applications which do not a priori know the
ssrc which they will be receiving can still use libsrtp. Now the
SSRC value is gleaned from the rtp header and exored into the
counter mode offset in the srtp_protect() and srtp_unprotect()
functions, if that cipher is used. This change cascaed through
many other functions, including srtp_init_from_hex(),
srtp_sender_init() and srtp_receiver_init() in rtp.c, and also
changing the CLI to test/rtpw. In the future, another function
call will be added to the library that enables multiple ssrc/key
pairs to be installed into the same srtp session, so that libsrtp
works with multiple srtp senders. For now, this functionality is
lacking.
Removed the GDOI interface to the rtpw demo program. This will be PR #274 - Update Travis build - add ccache
added again at a later date, after the SRTP and GDOI distributions
stabilize. For now, I've left in the GDOI #defines and autoconf
definitions so that they'll be in place when needed.
Updated tmmhv2_compute() so that it didn't assume any particular PR #276 - Reference and docs updates
alginment of the output tag.
Changed bit field variables in srtp.h to unsigned char from PR #278 - Removed crypto/test/auth_driver.c and test/lfsr.c
unsigned int in order to avoid a potential endianness issue.
Fixed rdbx_estimate_index() to handle all input cases. This solves PR #279 - Bump copyright year
the now notorious "abaft" bug in the rtpw demo app on linux/intel,
in which spurious replay protection failures happen after that word
is received.
Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed PR #283 - Add missing docs in srtp.h
from rijndael_icm_set_segment().
Added error checking and handling to srtp_sender_init() and PR #284 - Add strict-prototypes warning if supported
srtp_receiver_init().
Changed srtp_alloc() so that it does what you'd expect: allocate an PR #291 - Use const char * for srtp_set_debug_module()
srtp_ctx_t structure. This hides the library internals.
PR #294 - Fix incorrect result of rdb_increment on overflow
1.0.1 Many minor fixes PR #300 - Standalone tests
Added cipher_driver_buffer_test(...) to test/cipher-driver.c. This PR #301 - Configure fixes
function checks that the byte-buffering functions used by a cipher
are correct.
Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and PR #302 - Fix warning regarding unused variable
changed index_t to xtd_seq_num_t (see include/rdbx.h).
Fixed SEAL3.0 output byte buffering, added byte-buffering test to
cipher/cipher-driver.c.
Fixed roc-driver so that the non-sequential insertion test
automatically recovers from bad estimates. This was required to
prevent spurious failures.
Made rdbx_estimate_index(...) function smarter, so that initial RTP
sequence numbers greater than 32,768 don't cause it to estimate the
rollover counter of 0xffffffff.
1.0.0 Initial release
PR #303 - Makefile.in: Add gnu as match for shared lib suffix

View File

@ -1,6 +1,6 @@
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,4 +1,4 @@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu subdir-objects
NAME=srtp NAME=srtp
AM_CFLAGS = $(new_AM_CFLAGS) -I./src -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include AM_CFLAGS = $(new_AM_CFLAGS) -I./src -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include
@ -6,10 +6,9 @@ AM_CPPFLAGS = $(AM_CFLAGS)
AM_LDFLAGS = $(new_AM_LDFLAGS) -L. AM_LDFLAGS = $(new_AM_LDFLAGS) -L.
HMAC_OBJS = @HMAC_OBJS@ HMAC_OBJS = @HMAC_OBJS@
RNG_EXTRA_OBJS = @RNG_EXTRA_OBJS@
AES_ICM_OBJS = @AES_ICM_OBJS@ AES_ICM_OBJS = @AES_ICM_OBJS@
lib_LTLIBRARIES = libsrtp.la libcryptomath.la lib_LTLIBRARIES = libsrtp.la
libsrtp_la_SOURCES = srtp/srtp.c srtp/ekt.c crypto/cipher/cipher.c crypto/cipher/null_cipher.c \ libsrtp_la_SOURCES = srtp/srtp.c srtp/ekt.c crypto/cipher/cipher.c crypto/cipher/null_cipher.c \
crypto/hash/null_auth.c crypto/hash/auth.c \ crypto/hash/null_auth.c crypto/hash/auth.c \
crypto/math/datatypes.c crypto/math/stat.c \ crypto/math/datatypes.c crypto/math/stat.c \
@ -24,39 +23,24 @@ EXTRA_DIST=
if ENABLE_OPENSSL if ENABLE_OPENSSL
libsrtp_la_SOURCES += crypto/cipher/aes_icm_ossl.c crypto/cipher/aes_gcm_ossl.c libsrtp_la_SOURCES += crypto/cipher/aes_icm_ossl.c crypto/cipher/aes_gcm_ossl.c
libsrtp_la_SOURCES += crypto/rng/rand_source_ossl.c
libsrtp_la_SOURCES += crypto/hash/hmac_ossl.c libsrtp_la_SOURCES += crypto/hash/hmac_ossl.c
else else
libsrtp_la_SOURCES += crypto/hash/sha1.c crypto/hash/hmac.c libsrtp_la_SOURCES += crypto/hash/sha1.c crypto/hash/hmac.c
libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c crypto/cipher/aes_cbc.c libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c
libsrtp_la_SOURCES += crypto/rng/prng.c crypto/rng/ctr_prng.c
if RNG_OBJS_LINUX
libsrtp_la_SOURCES += crypto/rng/rand_linux_kernel.c
EXTRA_DIST += crypto/rng/rand_source.c
else
libsrtp_la_SOURCES += crypto/rng/rand_source.c
endif
endif endif
if GDOI if GDOI
libsrtp_la_SOURCES += gdoi/srtp+gdoi.c libsrtp_la_SOURCES += gdoi/srtp+gdoi.c
endif endif
libcryptomath_la_SOURCES = crypto/math/math.c crypto/math/gf2_8.c
libcryptomath_la_LDFLAGS = -version-info 1:42:1
library_includedir = $(prefix)/include/srtp library_includedir = $(prefix)/include/srtp
library_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/include/aes_cbc.h crypto/include/auth.h \ library_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/include/auth.h \
crypto/include/crypto_math.h crypto/include/datatypes.h crypto/include/integers.h crypto/include/null_cipher.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/rdbx.h crypto/include/aes_icm.h crypto/include/cipher.h crypto/include/crypto_types.h \
crypto/include/err.h crypto/include/kernel_compat.h crypto/include/prng.h crypto/include/sha1.h \ crypto/include/err.h crypto/include/sha1.h \
crypto/include/aes.h crypto/include/config.h crypto/include/crypto.h crypto/include/gf2_8.h crypto/include/key.h \ crypto/include/aes.h crypto/include/config.h crypto/include/key.h \
crypto/include/rand_source.h crypto/include/stat.h crypto/include/alloc.h crypto/include/crypto_kernel.h \ crypto/include/stat.h crypto/include/alloc.h crypto/include/crypto_kernel.h \
crypto/include/cryptoalg.h crypto/include/hmac.h crypto/include/null_auth.h crypto/include/rdb.h crypto/include/xfm.h crypto/include/hmac.h crypto/include/null_auth.h crypto/include/rdb.h
noinst_PROGRAMS = aes_tables
aes_tables_SOURCES = tables/aes_tables.c
aes_tables_LDADD = libcryptomath.la
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = srtp-1.42.pc pkgconfig_DATA = srtp-1.42.pc

460
libs/srtp/README.md Normal file
View File

@ -0,0 +1,460 @@
<a name="introduction-to-libsrtp"></a>
# Introduction to libSRTP
This package provides an implementation of the Secure Real-time
Transport Protocol (SRTP), the Universal Security Transform (UST), and
a supporting cryptographic kernel. The SRTP API is documented in include/srtp.h,
and the library is in libsrtp2.a (after compilation).
This document describes libSRTP, the Open Source Secure RTP library
from Cisco Systems, Inc. RTP is the Real-time Transport Protocol, an
IETF standard for the transport of real-time data such as telephony,
audio, and video, defined by [RFC 3550](https://www.ietf.org/rfc/rfc3550.txt).
Secure RTP (SRTP) is an RTP profile for providing confidentiality to RTP data
and authentication to the RTP header and payload. SRTP is an IETF Standard,
defined in [RFC 3711](https://www.ietf.org/rfc/rfc3711.txt), and was developed
in the IETF Audio/Video Transport (AVT) Working Group. This library supports
all of the mandatory features of SRTP, but not all of the optional features. See
the [Supported Features](#supported-features) section for more detailed information.
This document is also used to generate the documentation files in the /doc/
folder where a more detailed reference to the libSRTP API and related functions
can be created (requires installing doxygen.). The reference material is created
automatically from comments embedded in some of the C header files. The
documentation is organized into modules in order to improve its clarity. These
modules do not directly correspond to files. An underlying cryptographic kernel
provides much of the basic functionality of libSRTP but is mostly undocumented
because it does its work behind the scenes.
--------------------------------------------------------------------------------
<a name="contact"></a>
# Contact Us
- [libsrtp@lists.packetizer.com](mailto:libsrtp@lists.packetizer.com) general mailing list for news / announcements / discussions. This is an open list, see
[https://lists.packetizer.com/mailman/listinfo/libsrtp](https://lists.packetizer.com/mailman/listinfo/libsrtp) for singing up.
- [libsrtp-security@lists.packetizer.com](mailto:libsrtp-security@lists.packetizer.com) for disclosing security issues to the libsrtp maintenance team. This is a closed list but anyone can send to it.
--------------------------------------------------------------------------------
<a name="contents"></a>
## Contents
- [Introduction to libSRTP](#introduction-to-libsrtp)
- [Contact Us](#contact)
- [Contents](#contents)
- [License and Disclaimer](#license-and-disclaimer)
- [libSRTP Overview](#libsrtp-overview)
- [Secure RTP Background](#secure-rtp-background)
- [Supported Features](#supported-features)
- [Implementation Notes](#implementation-notes)
- [Installing and Building libSRTP](#installing-and-building-libsrtp)
- [Applications](#applications)
- [Example Code](#example-code)
- [Credits](#credits)
- [References](#references)
--------------------------------------------------------------------------------
<a name="license-and-disclaimer"></a>
# License and Disclaimer
libSRTP is distributed under the following license, which is included
in the source code distribution. It is reproduced in the manual in
case you got the library from another source.
> Copyright (c) 2001-2017 Cisco Systems, Inc. All rights reserved.
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions
> are met:
>
> - Redistributions of source code must retain the above copyright
> notice, this list of conditions and the following disclaimer.
> - Redistributions in binary form must reproduce the above copyright
> notice, this list of conditions and the following disclaimer in
> the documentation and/or other materials provided with the distribution.
> - Neither the name of the Cisco Systems, Inc. nor the names of its
> contributors may be used to endorse or promote products derived
> from this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
> INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
> OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
<a name="libsrtp-overview"></a>
# libSRTP Overview
libSRTP provides functions for protecting RTP and RTCP. RTP packets
can be encrypted and authenticated (using the `srtp_protect()`
function), turning them into SRTP packets. Similarly, SRTP packets
can be decrypted and have their authentication verified (using the
`srtp_unprotect()` function), turning them into RTP packets. Similar
functions apply security to RTCP packets.
The typedef `srtp_stream_t` points to a structure holding all of the
state associated with an SRTP stream, including the keys and
parameters for cipher and message authentication functions and the
anti-replay data. A particular `srtp_stream_t` holds the information
needed to protect a particular RTP and RTCP stream. This datatype
is intentionally opaque in order to better seperate the libSRTP
API from its implementation.
Within an SRTP session, there can be multiple streams, each
originating from a particular sender. Each source uses a distinct
stream context to protect the RTP and RTCP stream that it is
originating. The typedef `srtp_t` points to a structure holding all of
the state associated with an SRTP session. There can be multiple
stream contexts associated with a single `srtp_t`. A stream context
cannot exist indepent from an `srtp_t`, though of course an `srtp_t` can
be created that contains only a single stream context. A device
participating in an SRTP session must have a stream context for each
source in that session, so that it can process the data that it
receives from each sender.
In libSRTP, a session is created using the function `srtp_create()`.
The policy to be implemented in the session is passed into this
function as an `srtp_policy_t` structure. A single one of these
structures describes the policy of a single stream. These structures
can also be linked together to form an entire session policy. A linked
list of `srtp_policy_t` structures is equivalent to a session policy.
In such a policy, we refer to a single `srtp_policy_t` as an *element*.
An `srtp_policy_t` strucutre contains two `crypto_policy_t` structures
that describe the cryptograhic policies for RTP and RTCP, as well as
the SRTP master key and the SSRC value. The SSRC describes what to
protect (e.g. which stream), and the `crypto_policy_t` structures
describe how to protect it. The key is contained in a policy element
because it simplifies the interface to the library. In many cases, it
is desirable to use the same cryptographic policies across all of the
streams in a session, but to use a distinct key for each stream. A
`crypto_policy_t` structure can be initialized by using either the
`crypto_policy_set_rtp_default()` or `crypto_policy_set_rtcp_default()`
functions, which set a crypto policy structure to the default policies
for RTP and RTCP protection, respectively.
--------------------------------------------------------------------------------
<a name="secure-rtp-background"></a>
## Secure RTP Background
In this section we review SRTP and introduce some terms that are used
in libSRTP. An RTP session is defined by a pair of destination
transport addresses, that is, a network address plus a pair of UDP
ports for RTP and RTCP. RTCP, the RTP control protocol, is used to
coordinate between the participants in an RTP session, e.g. to provide
feedback from receivers to senders. An *SRTP session* is
similarly defined; it is just an RTP session for which the SRTP
profile is being used. An SRTP session consists of the traffic sent
to the SRTP or SRTCP destination transport addresses. Each
participant in a session is identified by a synchronization source
(SSRC) identifier. Some participants may not send any SRTP traffic;
they are called receivers, even though they send out SRTCP traffic,
such as receiver reports.
RTP allows multiple sources to send RTP and RTCP traffic during the
same session. The synchronization source identifier (SSRC) is used to
distinguish these sources. In libSRTP, we call the SRTP and SRTCP
traffic from a particular source a *stream*. Each stream has its own
SSRC, sequence number, rollover counter, and other data. A particular
choice of options, cryptographic mechanisms, and keys is called a
*policy*. Each stream within a session can have a distinct policy
applied to it. A session policy is a collection of stream policies.
A single policy can be used for all of the streams in a given session,
though the case in which a single *key* is shared across multiple
streams requires care. When key sharing is used, the SSRC values that
identify the streams **must** be distinct. This requirement can be
enforced by using the convention that each SRTP and SRTCP key is used
for encryption by only a single sender. In other words, the key is
shared only across streams that originate from a particular device (of
course, other SRTP participants will need to use the key for
decryption). libSRTP supports this enforcement by detecting the case
in which a key is used for both inbound and outbound data.
--------------------------------------------------------------------------------
<a name="supported-features"></a>
## Supported Features
This library supports all of the mandatory-to-implement features of
SRTP (as defined in [RFC 3711](https://www.ietf.org/rfc/rfc3711.txt)). Some of these
features can be selected (or de-selected) at run time by setting an
appropriate policy; this is done using the structure `srtp_policy_t`.
Some other behaviors of the protocol can be adapted by defining an
approriate event handler for the exceptional events; see the SRTPevents
section in the generated documentation.
Some options that are described in the SRTP specification are not
supported. This includes
- key derivation rates other than zero,
- the cipher F8,
- the use of the packet index to select between master keys.
The user should be aware that it is possible to misuse this libary,
and that the result may be that the security level it provides is
inadequate. If you are implementing a feature using this library, you
will want to read the Security Considerations section of [RFC 3711](https://www.ietf.org/rfc/rfc3711.txt).
In addition, it is important that you read and understand the
terms outlined in the [License and Disclaimer](#license-and-disclaimer) section.
--------------------------------------------------------------------------------
<a name="implementation-notes"></a>
## Implementation Notes
* The `srtp_protect()` function assumes that the buffer holding the
rtp packet has enough storage allocated that the authentication
tag can be written to the end of that packet. If this assumption
is not valid, memory corruption will ensue.
* Automated tests for the crypto functions are provided through
the `cipher_type_self_test()` and `auth_type_self_test()` functions.
These functions should be used to test each port of this code
to a new platform.
* Replay protection is contained in the crypto engine, and
tests for it are provided.
* This implementation provides calls to initialize, protect, and
unprotect RTP packets, and makes as few as possible assumptions
about how these functions will be called. For example, the
caller is not expected to provide packets in order (though if
they're called more than 65k out of sequence, synchronization
will be lost).
* The sequence number in the rtp packet is used as the low 16 bits
of the sender's local packet index. Note that RTP will start its
sequence number in a random place, and the SRTP layer just jumps
forward to that number at its first invocation. An earlier
version of this library used initial sequence numbers that are
less than 32,768; this trick is no longer required as the
`rdbx_estimate_index(...)` function has been made smarter.
* The replay window for (S)RTCP is hardcoded to 128 bits in length.
--------------------------------------------------------------------------------
<a name="installing-and-building-libsrtp"></a>
# Installing and Building libSRTP
To install libSRTP, download the latest release of the distribution
from [https://github.com/cisco/libsrtp/releases](https://github.com/cisco/libsrtp/releases).
You probably want to get the most recent release. Unpack the distribution and
extract the source files; the directory into which the source files
will go is named `libsrtp-A-B-C` where `A` is the version number, `B` is the
major release number and `C` is the minor release number.
libSRTP uses the GNU `autoconf` and `make` utilities (BSD make will not work; if
both versions of make are on your platform, you can invoke GNU make as
`gmake`.). In the `libsrtp` directory, run the configure script and then
make:
~~~.txt
./configure [ options ]
make
~~~
The configure script accepts the following options:
Option | Description
-------------------------------|--------------------
\-\-help \-h | Display help
\-\-enable-debug-logging | Enable debug logging in all modules
\-\-enable-log-stdout | Enable logging to stdout
\-\-enable-openssl | Enable OpenSSL crypto engine
\-\-enable-openssl-kdf | Enable OpenSSL KDF algorithm
\-\-with-log-file | Use file for logging
\-\-with-openssl-dir | Location of OpenSSL installation
By default there is no log output, logging can be enabled to be output to stdout
or a given file using the configure options.
This package has been tested on the following platforms: Mac OS X
(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and
OpenBSD (sparc-unknown-openbsd2.7).
--------------------------------------------------------------------------------
<a name="applications"></a>
# Applications
Several test drivers and a simple and portable srtp application are
included in the `test/` subdirectory.
Test driver | Function tested
--------- | -------
kernel_driver | crypto kernel (ciphers, auth funcs, rng)
srtp_driver | srtp in-memory tests (does not use the network)
rdbx_driver | rdbx (extended replay database)
roc_driver | extended sequence number functions
replay_driver | replay database
cipher_driver | ciphers
auth_driver | hash functions
The app `rtpw` is a simple rtp application which reads words from
`/usr/dict/words` and then sends them out one at a time using [s]rtp.
Manual srtp keying uses the -k option; automated key management
using gdoi will be added later.
usage:
~~~.txt
rtpw [[-d <debug>]* [-k|b <key> [-a][-e <key size>][-g]] [-s | -r] dest_ip dest_port] | [-l]
~~~
Either the -s (sender) or -r (receiver) option must be chosen. The
values `dest_ip`, `dest_port` are the IP address and UDP port to which
the dictionary will be sent, respectively.
The options are:
Option | Description
--------- | -------
-s | (S)RTP sender - causes app to send words
-r | (S)RTP receive - causes app to receive words
-k <key> | use SRTP master key <key>, where the key is a hexadecimal (without the leading "0x")
-b <key> | same as -k but with base64 encoded key
-e <keysize> | encrypt/decrypt (for data confidentiality) (requires use of -k option as well) (use 128, 192, or 256 for keysize)
-g | use AES-GCM mode (must be used with -e)
-a | message authentication (requires use of -k option as well)
-l | list the available debug modules
-d <debug> | turn on debugging for module <debug>
In order to get random 30-byte values for use as key/salt pairs , you
can use the following bash function to format the output of
`/dev/random` (where that device is available).
~~~.txt
function randhex() {
cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
}
~~~
An example of an SRTP session using two rtpw programs follows:
~~~.txt
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -e 128 -a 0.0.0.0 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
...
[sh2]$ test/rtpw -r -k $k -e 128 -a 0.0.0.0 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
~~~
--------------------------------------------------------------------------------
<a name="example-code"></a>
## Example Code
This section provides a simple example of how to use libSRTP. The
example code lacks error checking, but is functional. Here we assume
that the value ssrc is already set to describe the SSRC of the stream
that we are sending, and that the functions `get_rtp_packet()` and
`send_srtp_packet()` are available to us. The former puts an RTP packet
into the buffer and returns the number of octets written to that
buffer. The latter sends the RTP packet in the buffer, given the
length as its second argument.
~~~.c
srtp_t session;
srtp_policy_t policy;
// Set key to predetermined value
uint8_t key[30] = {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};
// initialize libSRTP
srtp_init();
// set policy to describe a policy for an SRTP stream
crypto_policy_set_rtp_default(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
policy.ssrc = ssrc;
policy.key = key;
policy.next = NULL;
// allocate and initialize the SRTP session
srtp_create(&session, &policy);
// main loop: get rtp packets, send srtp packets
while (1) {
char rtp_buffer[2048];
unsigned len;
len = get_rtp_packet(rtp_buffer);
srtp_protect(session, rtp_buffer, &len);
send_srtp_packet(rtp_buffer, len);
}
~~~
--------------------------------------------------------------------------------
<a name="credits"></a>
# Credits
The original implementation and documentation of libSRTP was written
by David McGrew of Cisco Systems, Inc. in order to promote the use,
understanding, and interoperability of Secure RTP. Michael Jerris
contributed support for building under MSVC. Andris Pavenis
contributed many important fixes. Brian West contributed changes to
enable dynamic linking. Yves Shumann reported documentation bugs.
Randell Jesup contributed a working SRTCP implementation and other
fixes. Steve Underwood contributed x86_64 portability changes. We also give
thanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill
Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and
others for contributions, comments, and corrections.
This reference material, when applicable, in this documenation was generated
using the doxygen utility for automatic documentation of source code.
Copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc.
--------------------------------------------------------------------------------
<a name="references"></a>
# References
SRTP and ICM References
September, 2005
Secure RTP is defined in [RFC 3711](https://www.ietf.org/rfc/rfc3711.txt).
The counter mode definition is in Section 4.1.1.
SHA-1 is defined in [FIPS PUB 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
HMAC is defined in [RFC 2104](https://www.ietf.org/rfc/rfc2104.txt)
and HMAC-SHA1 test vectors are available
in [RFC 2202](https://www.ietf.org/rfc/rfc2202.txt).
AES-GCM usage in SRTP is defined in [RFC 7714](https://www.ietf.org/html/rfc7714)

View File

@ -1 +1 @@
1.4.5 2.1.0-pre

162
libs/srtp/config.h_win32vc7 Normal file
View File

@ -0,0 +1,162 @@
/* Hacked config.h for Windows XP 32-bit & VC7 */
#ifdef (_MSC_VER >= 1400)
# define HAVE_RAND_S 1
#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
/* Path to random device */
#undef DEV_URANDOM
/* 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. */
#define HAVE_INET_ATON 1
/* Define to 1 if the system has the type `int16_t'. */
#undef HAVE_INT16_T
/* Define to 1 if the system has the type `int32_t'. */
#undef HAVE_INT32_T
/* Define to 1 if the system has the type `int8_t'. */
#undef HAVE_INT8_T
/* 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. */
#define HAVE_SOCKET 1
/* 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. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* 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'. */
#undef HAVE_UINT16_T
/* Define to 1 if the system has the type `uint32_t'. */
#undef HAVE_UINT32_T
/* Define to 1 if the system has the type `uint64_t'. */
#undef HAVE_UINT64_T
/* Define to 1 if the system has the type `uint8_t'. */
#undef HAVE_UINT8_T
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* 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. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef 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. */
#undef STDC_HEADERS
/* 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 to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
//#ifndef __cplusplus
//#undef inline
//#endif
#define inline __inline
/* Define to `unsigned' if <sys/types.h> does not define. */
//#undef size_t

View File

@ -3,6 +3,7 @@
#if (_MSC_VER >= 1400) #if (_MSC_VER >= 1400)
# define HAVE_RAND_S 1 # define HAVE_RAND_S 1
# define _CRT_RAND_S
#endif #endif
/* Define if building for a CISC machine (e.g. Intel). */ /* Define if building for a CISC machine (e.g. Intel). */
@ -11,20 +12,14 @@
/* Define if building for a RISC machine (assume slow byte access). */ /* Define if building for a RISC machine (assume slow byte access). */
/* #undef CPU_RISC */ /* #undef CPU_RISC */
/* Path to random device */ /* Define to enabled debug logging for all mudules. */
/* #define DEV_URANDOM "/dev/urandom" */ #undef ENABLE_DEBUG_LOGGING
/* Define to compile in dynamic debugging system. */ /* Logging statments will be writen to this file. */
#define ENABLE_DEBUGGING 1
/* Report errors to this file. */
/* #undef ERR_REPORTING_FILE */ /* #undef ERR_REPORTING_FILE */
/* Define to use logging to stdout. */ /* Define to redirect logging to stdout. */
#define ERR_REPORTING_STDOUT 1 #undef ERR_REPORTING_STDOUT
/* Define this to use ISMAcryp code. */
/* #undef GENERIC_AESICM */
/* Define to 1 if you have the <arpa/inet.h> header file. */ /* Define to 1 if you have the <arpa/inet.h> header file. */
/* #undef HAVE_ARPA_INET_H */ /* #undef HAVE_ARPA_INET_H */
@ -74,9 +69,6 @@
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
/* Define to 1 if you have the <syslog.h> header file. */
/* #undef HAVE_SYSLOG_H */
/* Define to 1 if you have the <sys/int_types.h> header file. */ /* Define to 1 if you have the <sys/int_types.h> header file. */
/* #undef HAVE_SYS_INT_TYPES_H */ /* #undef HAVE_SYS_INT_TYPES_H */
@ -152,12 +144,6 @@
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Write errors to this file */
/* #undef USE_ERR_REPORTING_FILE */
/* Define to use syslog logging. */
/* #undef USE_SYSLOG */
/* Define to 1 if your processor stores words with the most significant byte /* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */ first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */ /* #undef WORDS_BIGENDIAN */

182
libs/srtp/config.hw.orig Normal file
View File

@ -0,0 +1,182 @@
/* 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

@ -266,7 +266,6 @@ if test "$enable_openssl" = "yes"; then
[AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])]) [AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])])
AC_DEFINE(OPENSSL, 1, [Define this to use OpenSSL crypto.]) AC_DEFINE(OPENSSL, 1, [Define this to use OpenSSL crypto.])
AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o" AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o"
RNG_OBJS=rand_source_ossl.o
HMAC_OBJS=crypto/hash/hmac_ossl.o HMAC_OBJS=crypto/hash/hmac_ossl.o
USE_OPENSSL=1 USE_OPENSSL=1
AC_SUBST(USE_OPENSSL) AC_SUBST(USE_OPENSSL)
@ -275,10 +274,8 @@ else
AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o crypto/cipher/aes_cbc.o" AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o crypto/cipher/aes_cbc.o"
AC_MSG_CHECKING(which random device to use) AC_MSG_CHECKING(which random device to use)
if test "$enable_kernel_linux" = "yes"; then if test "$enable_kernel_linux" = "yes"; then
RNG_OBJS=rand_linux_kernel.o
AC_MSG_RESULT([Linux kernel builtin]) AC_MSG_RESULT([Linux kernel builtin])
else else
RNG_OBJS=rand_source.o
if test -n "$DEV_URANDOM"; then if test -n "$DEV_URANDOM"; then
AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device]) AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device])
AC_MSG_RESULT([$DEV_URANDOM]) AC_MSG_RESULT([$DEV_URANDOM])
@ -286,15 +283,11 @@ else
AC_MSG_RESULT([standard rand() function...]) AC_MSG_RESULT([standard rand() function...])
fi fi
fi fi
RNG_EXTRA_OBJS="crypto/rng/prng.o crypto/rng/ctr_prng.o"
HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o" HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
fi fi
AM_CONDITIONAL([ENABLE_OPENSSL],[test "${enable_openssl}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENSSL],[test "${enable_openssl}" = "yes"])
AM_CONDITIONAL([RNG_OBJS_LINUX], test x$enable_kernel_linux = xyes)
AC_SUBST(AES_ICM_OBJS) AC_SUBST(AES_ICM_OBJS)
AC_SUBST(RNG_OBJS)
AC_SUBST(RNG_EXTRA_OBJS)
AC_SUBST(HMAC_OBJS) AC_SUBST(HMAC_OBJS)
AC_MSG_RESULT($enable_openssl) AC_MSG_RESULT($enable_openssl)
@ -343,13 +336,11 @@ 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 srtp-1.42.pc)
# This is needed when building outside the source dir. # This is needed when building outside the source dir.
AS_MKDIR_P(crypto/ae_xfm)
AS_MKDIR_P(crypto/cipher) AS_MKDIR_P(crypto/cipher)
AS_MKDIR_P(crypto/hash) AS_MKDIR_P(crypto/hash)
AS_MKDIR_P(crypto/kernel) AS_MKDIR_P(crypto/kernel)
AS_MKDIR_P(crypto/math) AS_MKDIR_P(crypto/math)
AS_MKDIR_P(crypto/replay) AS_MKDIR_P(crypto/replay)
AS_MKDIR_P(crypto/rng)
AS_MKDIR_P(crypto/test) AS_MKDIR_P(crypto/test)
AS_MKDIR_P(doc) AS_MKDIR_P(doc)
AS_MKDIR_P(srtp) AS_MKDIR_P(srtp)

View File

@ -1 +0,0 @@
Makefile

View File

@ -1 +0,0 @@
1.0.0

View File

@ -1,570 +0,0 @@
/*
* xfm.c
*
* Crypto transform implementation
*
* David A. McGrew
* Cisco Systems, Inc.
*/
#include "cryptoalg.h"
#include "aes_cbc.h"
#include "hmac.h"
#include "crypto_kernel.h" /* for crypto_get_random() */
#define KEY_LEN 16
#define ENC_KEY_LEN 16
#define MAC_KEY_LEN 16
#define IV_LEN 16
#define TAG_LEN 12
#define MAX_EXPAND 27
err_status_t
aes_128_cbc_hmac_sha1_96_func(void *key,
void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len,
void *auth_tag) {
aes_cbc_ctx_t aes_ctx;
hmac_ctx_t hmac_ctx;
unsigned char enc_key[ENC_KEY_LEN];
unsigned char mac_key[MAC_KEY_LEN];
err_status_t status;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
/* derive encryption and authentication keys from the input key */
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
if (status) return status;
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
if (status) return status;
/* perform encryption and authentication */
/* set aes key */
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
if (status) return status;
/* set iv */
status = crypto_get_random(iv, IV_LEN);
if (status) return status;
status = aes_cbc_set_iv(&aes_ctx, iv);
/* encrypt the opaque data */
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
if (status) return status;
/* authenticate clear and opaque data */
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
if (status) return status;
status = hmac_start(&hmac_ctx);
if (status) return status;
status = hmac_update(&hmac_ctx, clear, clear_len);
if (status) return status;
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
if (status) return status;
}
return err_status_ok;
}
err_status_t
aes_128_cbc_hmac_sha1_96_inv(void *key,
void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len,
void *auth_tag) {
aes_cbc_ctx_t aes_ctx;
hmac_ctx_t hmac_ctx;
unsigned char enc_key[ENC_KEY_LEN];
unsigned char mac_key[MAC_KEY_LEN];
unsigned char tmp_tag[TAG_LEN];
unsigned char *tag = auth_tag;
err_status_t status;
int i;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
/* derive encryption and authentication keys from the input key */
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
if (status) return status;
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
if (status) return status;
/* perform encryption and authentication */
/* set aes key */
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt);
if (status) return status;
/* set iv */
status = rand_source_get_octet_string(iv, IV_LEN);
if (status) return status;
status = aes_cbc_set_iv(&aes_ctx, iv);
/* encrypt the opaque data */
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
if (status) return status;
/* authenticate clear and opaque data */
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
if (status) return status;
status = hmac_start(&hmac_ctx);
if (status) return status;
status = hmac_update(&hmac_ctx, clear, clear_len);
if (status) return status;
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
if (status) return status;
/* compare the computed tag with the one provided as input */
for (i=0; i < TAG_LEN; i++)
if (tmp_tag[i] != tag[i])
return err_status_auth_fail;
}
return err_status_ok;
}
#define ENC 1
#define DEBUG_PRINT 0
err_status_t
aes_128_cbc_hmac_sha1_96_enc(void *key,
const void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len) {
aes_cbc_ctx_t aes_ctx;
hmac_ctx_t hmac_ctx;
unsigned char enc_key[ENC_KEY_LEN];
unsigned char mac_key[MAC_KEY_LEN];
unsigned char *auth_tag;
err_status_t status;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
#if DEBUG_PRINT
printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
#endif
/* derive encryption and authentication keys from the input key */
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
if (status) return status;
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
if (status) return status;
/* perform encryption and authentication */
/* set aes key */
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
if (status) return status;
/* set iv */
status = rand_source_get_octet_string(iv, IV_LEN);
if (status) return status;
status = aes_cbc_set_iv(&aes_ctx, iv);
if (status) return status;
#if DEBUG_PRINT
printf("plaintext len: %d\n", *opaque_len);
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len));
#endif
#if ENC
/* encrypt the opaque data */
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
if (status) return status;
#endif
#if DEBUG_PRINT
printf("ciphertext len: %d\n", *opaque_len);
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
#endif
/*
* authenticate clear and opaque data, then write the
* authentication tag to the location immediately following the
* ciphertext
*/
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
if (status) return status;
status = hmac_start(&hmac_ctx);
if (status) return status;
status = hmac_update(&hmac_ctx, clear, clear_len);
if (status) return status;
#if DEBUG_PRINT
printf("hmac input: %s\n",
octet_string_hex_string(clear, clear_len));
#endif
auth_tag = (unsigned char *)opaque;
auth_tag += *opaque_len;
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
if (status) return status;
#if DEBUG_PRINT
printf("hmac input: %s\n",
octet_string_hex_string(opaque, *opaque_len));
#endif
/* bump up the opaque_len to reflect the authentication tag */
*opaque_len += TAG_LEN;
#if DEBUG_PRINT
printf("prot data len: %d\n", *opaque_len);
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
#endif
}
return err_status_ok;
}
err_status_t
aes_128_cbc_hmac_sha1_96_dec(void *key,
const void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len) {
aes_cbc_ctx_t aes_ctx;
hmac_ctx_t hmac_ctx;
unsigned char enc_key[ENC_KEY_LEN];
unsigned char mac_key[MAC_KEY_LEN];
unsigned char tmp_tag[TAG_LEN];
unsigned char *auth_tag;
unsigned ciphertext_len;
err_status_t status;
int i;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
#if DEBUG_PRINT
printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
#endif
/* derive encryption and authentication keys from the input key */
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
if (status) return status;
status = hmac_init(&hmac_ctx, key, KEY_LEN);
if (status) return status;
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
if (status) return status;
#if DEBUG_PRINT
printf("prot data len: %d\n", *opaque_len);
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
#endif
/*
* set the protected data length to that of the ciphertext, by
* subtracting out the length of the authentication tag
*/
ciphertext_len = *opaque_len - TAG_LEN;
#if DEBUG_PRINT
printf("ciphertext len: %d\n", ciphertext_len);
#endif
/* verify the authentication tag */
/*
* compute the authentication tag for the clear and opaque data,
* and write it to a temporary location
*/
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
if (status) return status;
status = hmac_start(&hmac_ctx);
if (status) return status;
status = hmac_update(&hmac_ctx, clear, clear_len);
if (status) return status;
#if DEBUG_PRINT
printf("hmac input: %s\n",
octet_string_hex_string(clear, clear_len));
#endif
status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
if (status) return status;
#if DEBUG_PRINT
printf("hmac input: %s\n",
octet_string_hex_string(opaque, ciphertext_len));
#endif
/*
* compare the computed tag with the one provided as input (which
* immediately follows the ciphertext)
*/
auth_tag = (unsigned char *)opaque;
auth_tag += ciphertext_len;
#if DEBUG_PRINT
printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));
printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));
#endif
for (i=0; i < TAG_LEN; i++) {
if (tmp_tag[i] != auth_tag[i])
return err_status_auth_fail;
}
/* bump down the opaque_len to reflect the authentication tag */
*opaque_len -= TAG_LEN;
/* decrypt the confidential data */
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt);
if (status) return status;
status = aes_cbc_set_iv(&aes_ctx, iv);
if (status) return status;
#if DEBUG_PRINT
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
#endif
#if ENC
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
if (status) return status;
#endif
#if DEBUG_PRINT
printf("plaintext len: %d\n", ciphertext_len);
printf("plaintext: %s\n",
octet_string_hex_string(opaque, ciphertext_len));
#endif
/* indicate the length of the plaintext */
*opaque_len = ciphertext_len;
}
return err_status_ok;
}
cryptoalg_ctx_t cryptoalg_ctx = {
aes_128_cbc_hmac_sha1_96_enc,
aes_128_cbc_hmac_sha1_96_dec,
KEY_LEN,
IV_LEN,
TAG_LEN,
MAX_EXPAND,
};
cryptoalg_t cryptoalg = &cryptoalg_ctx;
#define NULL_TAG_LEN 12
err_status_t
null_enc(void *key,
const void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len) {
int i;
unsigned char *auth_tag;
unsigned char *init_vec = iv;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
#if DEBUG_PRINT
printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN);
printf("plaintext len: %d\n", *opaque_len);
#endif
for (i=0; i < IV_LEN; i++)
init_vec[i] = i + (i * 16);
#if DEBUG_PRINT
printf("iv: %s\n",
octet_string_hex_string(iv, IV_LEN));
printf("plaintext: %s\n",
octet_string_hex_string(opaque, *opaque_len));
#endif
auth_tag = opaque;
auth_tag += *opaque_len;
for (i=0; i < NULL_TAG_LEN; i++)
auth_tag[i] = i + (i * 16);
*opaque_len += NULL_TAG_LEN;
#if DEBUG_PRINT
printf("protected data len: %d\n", *opaque_len);
printf("protected data: %s\n",
octet_string_hex_string(opaque, *opaque_len));
#endif
}
return err_status_ok;
}
err_status_t
null_dec(void *key,
const void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len) {
unsigned char *auth_tag;
/* check if we're doing authentication only */
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
/* perform authentication only */
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
/*
* bad parameter - we expect either all three pointers to be NULL,
* or none of those pointers to be NULL
*/
return err_status_fail;
} else {
#if DEBUG_PRINT
printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
printf("protected data len: %d\n", *opaque_len);
printf("protected data: %s\n",
octet_string_hex_string(opaque, *opaque_len));
#endif
auth_tag = opaque;
auth_tag += (*opaque_len - NULL_TAG_LEN);
#if DEBUG_PRINT
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
#endif
*opaque_len -= NULL_TAG_LEN;
#if DEBUG_PRINT
printf("plaintext len: %d\n", *opaque_len);
printf("plaintext: %s\n",
octet_string_hex_string(opaque, *opaque_len));
#endif
}
return err_status_ok;
}
cryptoalg_ctx_t null_cryptoalg_ctx = {
null_enc,
null_dec,
KEY_LEN,
IV_LEN,
NULL_TAG_LEN,
MAX_EXPAND,
};
cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
int
cryptoalg_get_id(cryptoalg_t c) {
if (c == cryptoalg)
return 1;
return 0;
}
cryptoalg_t
cryptoalg_find_by_id(int id) {
switch(id) {
case 1:
return cryptoalg;
default:
break;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,561 +0,0 @@
/*
* aes_cbc.c
*
* AES Cipher Block Chaining Mode
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "aes_cbc.h"
#include "alloc.h"
debug_module_t mod_aes_cbc = {
0, /* debugging is off by default */
"aes cbc" /* printable module name */
};
err_status_t
aes_cbc_alloc(cipher_t **c, int key_len, int tlen) {
extern cipher_type_t aes_cbc;
uint8_t *pointer;
int tmp;
debug_print(mod_aes_cbc,
"allocating cipher with key length %d", key_len);
if (key_len != 16 && key_len != 24 && key_len != 32)
return err_status_bad_param;
/* allocate memory a cipher of type aes_cbc */
tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
pointer = (uint8_t*)crypto_alloc(tmp);
if (pointer == NULL)
return err_status_alloc_fail;
/* set pointers */
*c = (cipher_t *)pointer;
(*c)->type = &aes_cbc;
(*c)->state = pointer + sizeof(cipher_t);
/* increment ref_count */
aes_cbc.ref_count++;
/* set key size */
(*c)->key_len = key_len;
return err_status_ok;
}
err_status_t
aes_cbc_dealloc(cipher_t *c) {
extern cipher_type_t aes_cbc;
/* zeroize entire state*/
octet_string_set_to_zero((uint8_t *)c,
sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
/* free memory */
crypto_free(c);
/* decrement ref_count */
aes_cbc.ref_count--;
return err_status_ok;
}
err_status_t
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len) {
debug_print(mod_aes_cbc,
"key: %s", octet_string_hex_string(key, key_len));
/*
* Save the key until we have the IV later. We don't
* know the direction until the IV is set.
*/
c->key_len = (key_len <= 32 ? key_len : 32);
memcpy(c->key, key, c->key_len);
return err_status_ok;
}
err_status_t
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv, int direction) {
err_status_t status;
int i;
/* v128_t *input = iv; */
uint8_t *input = (uint8_t*) iv;
/* set state and 'previous' block to iv */
for (i=0; i < 16; i++)
c->previous.v8[i] = c->state.v8[i] = input[i];
debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));
/* expand key for the appropriate direction */
switch (direction) {
case (direction_encrypt):
status = aes_expand_encryption_key(c->key, c->key_len, &c->expanded_key);
memset(c->key, 0, 32);
if (status)
return status;
break;
case (direction_decrypt):
status = aes_expand_decryption_key(c->key, c->key_len, &c->expanded_key);
memset(c->key, 0, 32);
if (status)
return status;
break;
default:
return err_status_bad_param;
}
return err_status_ok;
}
err_status_t
aes_cbc_encrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data) {
int i;
unsigned char *input = data; /* pointer to data being read */
unsigned char *output = data; /* pointer to data being written */
int bytes_to_encr = *bytes_in_data;
/*
* verify that we're 16-octet aligned
*/
if (*bytes_in_data & 0xf)
return err_status_bad_param;
/*
* note that we assume that the initialization vector has already
* been set, e.g. by calling aes_cbc_set_iv()
*/
debug_print(mod_aes_cbc, "iv: %s",
v128_hex_string(&c->state));
/*
* loop over plaintext blocks, exoring state into plaintext then
* encrypting and writing to output
*/
while (bytes_to_encr > 0) {
/* exor plaintext into state */
for (i=0; i < 16; i++)
c->state.v8[i] ^= *input++;
debug_print(mod_aes_cbc, "inblock: %s",
v128_hex_string(&c->state));
aes_encrypt(&c->state, &c->expanded_key);
debug_print(mod_aes_cbc, "outblock: %s",
v128_hex_string(&c->state));
/* copy ciphertext to output */
for (i=0; i < 16; i++)
*output++ = c->state.v8[i];
bytes_to_encr -= 16;
}
return err_status_ok;
}
err_status_t
aes_cbc_decrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data) {
int i;
v128_t state, previous;
unsigned char *input = data; /* pointer to data being read */
unsigned char *output = data; /* pointer to data being written */
int bytes_to_encr = *bytes_in_data;
uint8_t tmp;
/*
* verify that we're 16-octet aligned
*/
if (*bytes_in_data & 0x0f)
return err_status_bad_param;
/* set 'previous' block to iv*/
for (i=0; i < 16; i++) {
previous.v8[i] = c->previous.v8[i];
}
debug_print(mod_aes_cbc, "iv: %s",
v128_hex_string(&previous));
/*
* loop over ciphertext blocks, decrypting then exoring with state
* then writing plaintext to output
*/
while (bytes_to_encr > 0) {
/* set state to ciphertext input block */
for (i=0; i < 16; i++) {
state.v8[i] = *input++;
}
debug_print(mod_aes_cbc, "inblock: %s",
v128_hex_string(&state));
/* decrypt state */
aes_decrypt(&state, &c->expanded_key);
debug_print(mod_aes_cbc, "outblock: %s",
v128_hex_string(&state));
/*
* exor previous ciphertext block out of plaintext, and write new
* plaintext block to output, while copying old ciphertext block
* to the 'previous' block
*/
for (i=0; i < 16; i++) {
tmp = *output;
*output++ = state.v8[i] ^ previous.v8[i];
previous.v8[i] = tmp;
}
bytes_to_encr -= 16;
}
return err_status_ok;
}
err_status_t
aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data) {
int i;
unsigned char *pad_start;
int num_pad_bytes;
err_status_t status;
/*
* determine the number of padding bytes that we need to add -
* this value is always between 1 and 16, inclusive.
*/
num_pad_bytes = 16 - (*bytes_in_data & 0xf);
pad_start = data;
pad_start += *bytes_in_data;
*pad_start++ = 0xa0;
for (i=0; i < num_pad_bytes; i++)
*pad_start++ = 0x00;
/*
* increment the data size
*/
*bytes_in_data += num_pad_bytes;
/*
* now cbc encrypt the padded data
*/
status = aes_cbc_encrypt(c, data, bytes_in_data);
if (status)
return status;
return err_status_ok;
}
err_status_t
aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data) {
unsigned char *pad_end;
int num_pad_bytes;
err_status_t status;
/*
* cbc decrypt the padded data
*/
status = aes_cbc_decrypt(c, data, bytes_in_data);
if (status)
return status;
/*
* determine the number of padding bytes in the decrypted plaintext
* - this value is always between 1 and 16, inclusive.
*/
num_pad_bytes = 1;
pad_end = data + (*bytes_in_data - 1);
while (*pad_end != 0xa0) { /* note: should check padding correctness */
pad_end--;
num_pad_bytes++;
}
/* decrement data size */
*bytes_in_data -= num_pad_bytes;
return err_status_ok;
}
char
aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
/*
* Test case 0 is derived from FIPS 197 Appendix C; it uses an
* all-zero IV, so that the first block encryption matches the test
* case in that appendix. This property provides a check of the base
* AES encryption and decryption algorithms; if CBC fails on some
* particular platform, then you should print out AES intermediate
* data and compare with the detailed info provided in that appendix.
*
*/
uint8_t aes_cbc_test_case_0_key[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
uint8_t aes_cbc_test_case_0_plaintext[64] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};
uint8_t aes_cbc_test_case_0_ciphertext[80] = {
0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1,
0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b
};
uint8_t aes_cbc_test_case_0_iv[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
cipher_test_case_t aes_cbc_test_case_0 = {
16, /* octets in key */
aes_cbc_test_case_0_key, /* key */
aes_cbc_test_case_0_iv, /* initialization vector */
16, /* octets in plaintext */
aes_cbc_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */
aes_cbc_test_case_0_ciphertext, /* ciphertext */
0,
NULL,
0,
NULL /* pointer to next testcase */
};
/*
* this test case is taken directly from Appendix F.2 of NIST Special
* Publication SP 800-38A
*/
uint8_t aes_cbc_test_case_1_key[16] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
};
uint8_t aes_cbc_test_case_1_plaintext[64] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
};
uint8_t aes_cbc_test_case_1_ciphertext[80] = {
0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99,
0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3
};
uint8_t aes_cbc_test_case_1_iv[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
cipher_test_case_t aes_cbc_test_case_1 = {
16, /* octets in key */
aes_cbc_test_case_1_key, /* key */
aes_cbc_test_case_1_iv, /* initialization vector */
64, /* octets in plaintext */
aes_cbc_test_case_1_plaintext, /* plaintext */
80, /* octets in ciphertext */
aes_cbc_test_case_1_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_0 /* pointer to next testcase */
};
/*
* Test case 2 is like test case 0, but for 256-bit keys. (FIPS 197
* appendix C.3).
*/
uint8_t aes_cbc_test_case_2_key[32] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
uint8_t aes_cbc_test_case_2_plaintext[64] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};
uint8_t aes_cbc_test_case_2_ciphertext[80] = {
0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
0x72, 0x72, 0x6e, 0xe7, 0x71, 0x39, 0xbf, 0x11,
0xe5, 0x40, 0xe2, 0x7c, 0x54, 0x65, 0x1d, 0xee
};
uint8_t aes_cbc_test_case_2_iv[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
cipher_test_case_t aes_cbc_test_case_2 = {
32, /* octets in key */
aes_cbc_test_case_2_key, /* key */
aes_cbc_test_case_2_iv, /* initialization vector */
16, /* octets in plaintext */
aes_cbc_test_case_2_plaintext, /* plaintext */
32, /* octets in ciphertext */
aes_cbc_test_case_2_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_1 /* pointer to next testcase */
};
/*
* this test case is taken directly from Appendix F.2 of NIST Special
* Publication SP 800-38A
*/
uint8_t aes_cbc_test_case_3_key[32] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
};
uint8_t aes_cbc_test_case_3_plaintext[64] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
};
uint8_t aes_cbc_test_case_3_ciphertext[80] = {
0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
0xfb, 0x98, 0x20, 0x2c, 0x45, 0xb2, 0xe4, 0xa0,
0x63, 0xc4, 0x68, 0xba, 0x84, 0x39, 0x16, 0x5a
};
uint8_t aes_cbc_test_case_3_iv[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
cipher_test_case_t aes_cbc_test_case_3 = {
32, /* octets in key */
aes_cbc_test_case_3_key, /* key */
aes_cbc_test_case_3_iv, /* initialization vector */
64, /* octets in plaintext */
aes_cbc_test_case_3_plaintext, /* plaintext */
80, /* octets in ciphertext */
aes_cbc_test_case_3_ciphertext, /* ciphertext */
0,
NULL,
0,
&aes_cbc_test_case_2 /* pointer to next testcase */
};
cipher_type_t aes_cbc = {
(cipher_alloc_func_t) aes_cbc_alloc,
(cipher_dealloc_func_t) aes_cbc_dealloc,
(cipher_init_func_t) aes_cbc_context_init,
(cipher_set_aad_func_t) 0,
(cipher_encrypt_func_t) aes_cbc_nist_encrypt,
(cipher_decrypt_func_t) aes_cbc_nist_decrypt,
(cipher_set_iv_func_t) aes_cbc_set_iv,
(cipher_get_tag_func_t) 0,
(char *) aes_cbc_description,
(int) 0, /* instance count */
(cipher_test_case_t *) &aes_cbc_test_case_3,
(debug_module_t *) &mod_aes_cbc,
(cipher_type_id_t) AES_CBC
};

View File

@ -10,7 +10,7 @@
/* /*
* *
* Copyright (c) 2013, Cisco Systems, Inc. * Copyright (c) 2013-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,14 +44,19 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <openssl/evp.h> #include <openssl/evp.h>
#include "aes_icm_ossl.h" #include "aes_icm_ossl.h"
#include "aes_gcm_ossl.h" #include "aes_gcm_ossl.h"
#include "alloc.h" #include "alloc.h"
#include "err.h" /* for srtp_debug */
#include "crypto_types.h" #include "crypto_types.h"
debug_module_t mod_aes_gcm = { srtp_debug_module_t srtp_mod_aes_gcm = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"aes gcm" /* printable module name */ "aes gcm" /* printable module name */
}; };
@ -60,12 +65,12 @@ debug_module_t mod_aes_gcm = {
* The following are the global singleton instances for the * The following are the global singleton instances for the
* 128-bit and 256-bit GCM ciphers. * 128-bit and 256-bit GCM ciphers.
*/ */
extern cipher_type_t aes_gcm_128_openssl; extern const srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern cipher_type_t aes_gcm_256_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 * 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. * optional 12 byte tag, which may be supported in the future.
*/ */
#define GCM_AUTH_TAG_LEN 16 #define GCM_AUTH_TAG_LEN 16
#define GCM_AUTH_TAG_LEN_8 8 #define GCM_AUTH_TAG_LEN_8 8
@ -74,101 +79,98 @@ extern cipher_type_t aes_gcm_256_openssl;
/* /*
* This function allocates a new instance of this crypto engine. * This function allocates a new instance of this crypto engine.
* The key_len parameter should be one of 28 or 44 for * The key_len parameter should be one of 28 or 44 for
* AES-128-GCM or AES-256-GCM respectively. Note that the * AES-128-GCM or AES-256-GCM respectively. Note that the
* key length includes the 14 byte salt value that is used when * key length includes the 14 byte salt value that is used when
* initializing the KDF. * initializing the KDF.
*/ */
err_status_t aes_gcm_openssl_alloc (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)
{ {
aes_gcm_ctx_t *gcm; srtp_aes_gcm_ctx_t *gcm;
int tmp;
uint8_t *allptr;
debug_print(mod_aes_gcm, "allocating cipher with key length %d", key_len); debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d", key_len);
debug_print(mod_aes_gcm, "allocating cipher with tag length %d", tlen); debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
/* /*
* Verify the key_len is valid for one of: AES-128/256 * Verify the key_len is valid for one of: AES-128/256
*/ */
if (key_len != AES_128_GCM_KEYSIZE_WSALT && if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
key_len != AES_256_GCM_KEYSIZE_WSALT) { key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
return (err_status_bad_param); return (srtp_err_status_bad_param);
} }
if (tlen != GCM_AUTH_TAG_LEN && if (tlen != GCM_AUTH_TAG_LEN &&
tlen != GCM_AUTH_TAG_LEN_8) { tlen != GCM_AUTH_TAG_LEN_8) {
return (err_status_bad_param); return (srtp_err_status_bad_param);
} }
/* allocate memory a cipher of type aes_gcm */ /* allocate memory a cipher of type aes_gcm */
tmp = sizeof(cipher_t) + sizeof(aes_gcm_ctx_t); *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
allptr = crypto_alloc(tmp); if (*c == NULL) {
if (allptr == NULL) { return (srtp_err_status_alloc_fail);
return (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;
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) {
srtp_crypto_free(gcm);
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
} }
/* set pointers */ /* set pointers */
*c = (cipher_t*)allptr; (*c)->state = gcm;
(*c)->state = allptr + sizeof(cipher_t);
gcm = (aes_gcm_ctx_t *)(*c)->state;
/* increment ref_count */ /* setup cipher attributes */
switch (key_len) { switch (key_len) {
case AES_128_GCM_KEYSIZE_WSALT: case SRTP_AES_GCM_128_KEY_LEN_WSALT:
(*c)->type = &aes_gcm_128_openssl; (*c)->type = &srtp_aes_gcm_128_openssl;
(*c)->algorithm = AES_128_GCM; (*c)->algorithm = SRTP_AES_GCM_128;
aes_gcm_128_openssl.ref_count++; gcm->key_size = SRTP_AES_128_KEY_LEN;
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE; gcm->tag_len = tlen;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
break; break;
case AES_256_GCM_KEYSIZE_WSALT: case SRTP_AES_GCM_256_KEY_LEN_WSALT:
(*c)->type = &aes_gcm_256_openssl; (*c)->type = &srtp_aes_gcm_256_openssl;
(*c)->algorithm = AES_256_GCM; (*c)->algorithm = SRTP_AES_GCM_256;
aes_gcm_256_openssl.ref_count++; gcm->key_size = SRTP_AES_256_KEY_LEN;
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE; gcm->tag_len = tlen;
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
break; break;
} }
/* set key size */ /* set key size */
(*c)->key_len = key_len; (*c)->key_len = key_len;
EVP_CIPHER_CTX_init(&gcm->ctx);
return (err_status_ok); return (srtp_err_status_ok);
} }
/* /*
* This function deallocates a GCM session * This function deallocates a GCM session
*/ */
err_status_t aes_gcm_openssl_dealloc (cipher_t *c) static srtp_err_status_t srtp_aes_gcm_openssl_dealloc (srtp_cipher_t *c)
{ {
aes_gcm_ctx_t *ctx; srtp_aes_gcm_ctx_t *ctx;
ctx = (aes_gcm_ctx_t*)c->state; ctx = (srtp_aes_gcm_ctx_t*)c->state;
if (ctx) { if (ctx) {
EVP_CIPHER_CTX_cleanup(&ctx->ctx); EVP_CIPHER_CTX_free(ctx->ctx);
/* decrement ref_count for the appropriate engine */ /* zeroize the key material */
switch (ctx->key_size) { octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
case AES_256_KEYSIZE: srtp_crypto_free(ctx);
aes_gcm_256_openssl.ref_count--;
break;
case AES_128_KEYSIZE:
aes_gcm_128_openssl.ref_count--;
break;
default:
return (err_status_dealloc_fail);
break;
}
} }
/* zeroize entire state*/
octet_string_set_to_zero((uint8_t*)c, sizeof(cipher_t) + sizeof(aes_gcm_ctx_t));
/* free memory */ /* free memory */
crypto_free(c); srtp_crypto_free(c);
return (err_status_ok); return (srtp_err_status_ok);
} }
/* /*
@ -177,25 +179,32 @@ err_status_t aes_gcm_openssl_dealloc (cipher_t *c)
* *
* the key is the secret key * the key is the secret key
*/ */
err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key) static srtp_err_status_t srtp_aes_gcm_openssl_context_init (void* cv, const uint8_t *key)
{ {
c->dir = direction_any; srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
const EVP_CIPHER *evp;
/* copy key to be used later when CiscoSSL crypto context is created */ c->dir = srtp_direction_any;
v128_copy_octet_string((v128_t*)&c->key, key);
if (c->key_size == AES_256_KEYSIZE) { debug_print(srtp_mod_aes_gcm, "key: %s", srtp_octet_string_hex_string(key, c->key_size));
debug_print(mod_aes_gcm, "Copying last 16 bytes of key: %s",
v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); switch (c->key_size) {
v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, case SRTP_AES_256_KEY_LEN:
key + AES_128_KEYSIZE); evp = EVP_aes_256_gcm();
break;
case SRTP_AES_128_KEY_LEN:
evp = EVP_aes_128_gcm();
break;
default:
return (srtp_err_status_bad_param);
break;
} }
debug_print(mod_aes_gcm, "key: %s", v128_hex_string((v128_t*)&c->key)); if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) {
return (srtp_err_status_init_fail);
}
EVP_CIPHER_CTX_cleanup(&c->ctx); return (srtp_err_status_ok);
return (err_status_ok);
} }
@ -203,48 +212,34 @@ err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key)
* aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
* the offset * the offset
*/ */
err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv, static srtp_err_status_t srtp_aes_gcm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
int direction)
{ {
const EVP_CIPHER *evp; srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
v128_t *nonce = iv;
if (direction != direction_encrypt && direction != direction_decrypt) { if (direction != srtp_direction_encrypt && direction != srtp_direction_decrypt) {
return (err_status_bad_param); return (srtp_err_status_bad_param);
} }
c->dir = direction; c->dir = direction;
debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(nonce)); debug_print(srtp_mod_aes_gcm, "setting iv: %s", v128_hex_string((v128_t*)iv));
switch (c->key_size) { if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL,
case AES_256_KEYSIZE: NULL, (c->dir == srtp_direction_encrypt ? 1 : 0))) {
evp = EVP_aes_256_gcm(); return (srtp_err_status_init_fail);
break;
case AES_128_KEYSIZE:
evp = EVP_aes_128_gcm();
break;
default:
return (err_status_bad_param);
break;
}
if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8,
NULL, (c->dir == direction_encrypt ? 1 : 0))) {
return (err_status_init_fail);
} }
/* set IV len and the IV value, the followiong 3 calls are required */ /* 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)) { if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
return (err_status_init_fail); return (srtp_err_status_init_fail);
} }
if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void*)iv)) {
return (err_status_init_fail); return (srtp_err_status_init_fail);
} }
if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_IV_GEN, 0, (void*)iv)) {
return (err_status_init_fail); return (srtp_err_status_init_fail);
} }
return (err_status_ok); return (srtp_err_status_ok);
} }
/* /*
@ -255,22 +250,31 @@ err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv,
* aad Additional data to process for AEAD cipher suites * aad Additional data to process for AEAD cipher suites
* aad_len length of aad buffer * aad_len length of aad buffer
*/ */
err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad, static srtp_err_status_t srtp_aes_gcm_openssl_set_aad (void *cv, const uint8_t *aad, uint32_t aad_len)
unsigned int aad_len)
{ {
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
int rv; int rv;
/* /*
* Set dummy tag, OpenSSL requires the Tag to be set before * Set dummy tag, OpenSSL requires the Tag to be set before
* processing AAD * processing AAD
*/ */
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad);
rv = EVP_Cipher(&c->ctx, NULL, aad, aad_len); /*
* 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
* aad read-only in this function and all its wrappers.
*/
unsigned char dummy_tag[GCM_AUTH_TAG_LEN];
memset(dummy_tag, 0x0, GCM_AUTH_TAG_LEN);
EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, &dummy_tag);
rv = EVP_Cipher(c->ctx, NULL, aad, aad_len);
if (rv != aad_len) { if (rv != aad_len) {
return (err_status_algo_fail); return (srtp_err_status_algo_fail);
} else { } else {
return (err_status_ok); return (srtp_err_status_ok);
} }
} }
@ -282,24 +286,24 @@ err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad,
* buf data to encrypt * buf data to encrypt
* enc_len length of encrypt buffer * enc_len length of encrypt buffer
*/ */
err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf, static srtp_err_status_t srtp_aes_gcm_openssl_encrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
unsigned int *enc_len)
{ {
if (c->dir != direction_encrypt && c->dir != direction_decrypt) { srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
return (err_status_bad_param); if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
return (srtp_err_status_bad_param);
} }
/* /*
* Encrypt the data * Encrypt the data
*/ */
EVP_Cipher(&c->ctx, buf, buf, *enc_len); EVP_Cipher(c->ctx, buf, buf, *enc_len);
return (err_status_ok); return (srtp_err_status_ok);
} }
/* /*
* This function calculates and returns the GCM tag for a given context. * This function calculates and returns the GCM tag for a given context.
* This should be called after encrypting the data. The *len value * This should be called after encrypting the data. The *len value
* is increased by the tag size. The caller must ensure that *buf has * is increased by the tag size. The caller must ensure that *buf has
* enough room to accept the appended tag. * enough room to accept the appended tag.
* *
@ -308,25 +312,25 @@ err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf,
* buf data to encrypt * buf data to encrypt
* len length of encrypt buffer * len length of encrypt buffer
*/ */
err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf, static srtp_err_status_t srtp_aes_gcm_openssl_get_tag (void *cv, uint8_t *buf, uint32_t *len)
int *len)
{ {
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
/* /*
* Calculate the tag * Calculate the tag
*/ */
EVP_Cipher(&c->ctx, NULL, NULL, 0); EVP_Cipher(c->ctx, NULL, NULL, 0);
/* /*
* Retreive the tag * Retreive the tag
*/ */
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf); EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf);
/* /*
* Increase encryption length by desired tag size * Increase encryption length by desired tag size
*/ */
*len = c->tag_len; *len = c->tag_len;
return (err_status_ok); return (srtp_err_status_ok);
} }
@ -338,25 +342,25 @@ err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf,
* buf data to encrypt * buf data to encrypt
* enc_len length of encrypt buffer * enc_len length of encrypt buffer
*/ */
err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf, static srtp_err_status_t srtp_aes_gcm_openssl_decrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
unsigned int *enc_len)
{ {
if (c->dir != direction_encrypt && c->dir != direction_decrypt) { srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
return (err_status_bad_param); if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
return (srtp_err_status_bad_param);
} }
/* /*
* Set the tag before decrypting * Set the tag before decrypting
*/ */
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
buf + (*enc_len - c->tag_len)); buf + (*enc_len - c->tag_len));
EVP_Cipher(&c->ctx, buf, buf, *enc_len - c->tag_len); EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len);
/* /*
* Check the tag * Check the tag
*/ */
if (EVP_Cipher(&c->ctx, NULL, NULL, 0)) { if (EVP_Cipher(c->ctx, NULL, NULL, 0)) {
return (err_status_auth_fail); return (srtp_err_status_auth_fail);
} }
/* /*
@ -365,7 +369,7 @@ err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf,
*/ */
*enc_len -= c->tag_len; *enc_len -= c->tag_len;
return (err_status_ok); return (srtp_err_status_ok);
} }
@ -373,28 +377,28 @@ err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf,
/* /*
* Name of this crypto engine * Name of this crypto engine
*/ */
char aes_gcm_128_openssl_description[] = "AES-128 GCM using openssl"; static const char srtp_aes_gcm_128_openssl_description[] = "AES-128 GCM using openssl";
char aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl"; static const char srtp_aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl";
/* /*
* KAT values for AES self-test. These * KAT values for AES self-test. These
* values we're derived from independent test code * values we're derived from independent test code
* using OpenSSL. * using OpenSSL.
*/ */
uint8_t aes_gcm_test_case_0_key[AES_128_GCM_KEYSIZE_WSALT] = { 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, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x09, 0x0a, 0x0b, 0x0c,
}; };
uint8_t aes_gcm_test_case_0_iv[12] = { static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88 0xde, 0xca, 0xf8, 0x88
}; };
uint8_t aes_gcm_test_case_0_plaintext[60] = { static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
@ -405,13 +409,13 @@ uint8_t aes_gcm_test_case_0_plaintext[60] = {
0xba, 0x63, 0x7b, 0x39 0xba, 0x63, 0x7b, 0x39
}; };
uint8_t aes_gcm_test_case_0_aad[20] = { 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,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2 0xab, 0xad, 0xda, 0xd2
}; };
uint8_t aes_gcm_test_case_0_ciphertext[76] = { static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
@ -425,50 +429,50 @@ uint8_t aes_gcm_test_case_0_ciphertext[76] = {
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
}; };
cipher_test_case_t aes_gcm_test_case_0a = { static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
aes_gcm_test_case_0_key, /* key */ srtp_aes_gcm_test_case_0_key, /* key */
aes_gcm_test_case_0_iv, /* packet index */ srtp_aes_gcm_test_case_0_iv, /* packet index */
60, /* octets in plaintext */ 60, /* octets in plaintext */
aes_gcm_test_case_0_plaintext, /* plaintext */ srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
68, /* octets in ciphertext */ 68, /* octets in ciphertext */
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */ srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */ 20, /* octets in AAD */
aes_gcm_test_case_0_aad, /* AAD */ srtp_aes_gcm_test_case_0_aad, /* AAD */
GCM_AUTH_TAG_LEN_8, GCM_AUTH_TAG_LEN_8,
NULL /* pointer to next testcase */ NULL /* pointer to next testcase */
}; };
cipher_test_case_t aes_gcm_test_case_0 = { static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
aes_gcm_test_case_0_key, /* key */ srtp_aes_gcm_test_case_0_key, /* key */
aes_gcm_test_case_0_iv, /* packet index */ srtp_aes_gcm_test_case_0_iv, /* packet index */
60, /* octets in plaintext */ 60, /* octets in plaintext */
aes_gcm_test_case_0_plaintext, /* plaintext */ srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
76, /* octets in ciphertext */ 76, /* octets in ciphertext */
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */ srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */ 20, /* octets in AAD */
aes_gcm_test_case_0_aad, /* AAD */ srtp_aes_gcm_test_case_0_aad, /* AAD */
GCM_AUTH_TAG_LEN, GCM_AUTH_TAG_LEN,
&aes_gcm_test_case_0a /* pointer to next testcase */ &srtp_aes_gcm_test_case_0a /* pointer to next testcase */
}; };
uint8_t aes_gcm_test_case_1_key[AES_256_GCM_KEYSIZE_WSALT] = { 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, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c, 0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2, 0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x09, 0x0a, 0x0b, 0x0c,
}; };
uint8_t aes_gcm_test_case_1_iv[12] = { static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88 0xde, 0xca, 0xf8, 0x88
}; };
uint8_t aes_gcm_test_case_1_plaintext[60] = { static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] = {
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
@ -479,89 +483,85 @@ uint8_t aes_gcm_test_case_1_plaintext[60] = {
0xba, 0x63, 0x7b, 0x39 0xba, 0x63, 0x7b, 0x39
}; };
uint8_t aes_gcm_test_case_1_aad[20] = { 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,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2 0xab, 0xad, 0xda, 0xd2
}; };
uint8_t aes_gcm_test_case_1_ciphertext[76] = { static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46, 0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a, 0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86, 0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a, 0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9, 0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80, 0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10, 0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
0x09, 0xc9, 0x86, 0xc1, 0x09, 0xc9, 0x86, 0xc1,
/* the last 16 bytes are the tag */ /* the last 16 bytes are the tag */
0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f, 0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d, 0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
}; };
cipher_test_case_t aes_gcm_test_case_1a = { static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
aes_gcm_test_case_1_key, /* key */ srtp_aes_gcm_test_case_1_key, /* key */
aes_gcm_test_case_1_iv, /* packet index */ srtp_aes_gcm_test_case_1_iv, /* packet index */
60, /* octets in plaintext */ 60, /* octets in plaintext */
aes_gcm_test_case_1_plaintext, /* plaintext */ srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
68, /* octets in ciphertext */ 68, /* octets in ciphertext */
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */ srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */ 20, /* octets in AAD */
aes_gcm_test_case_1_aad, /* AAD */ srtp_aes_gcm_test_case_1_aad, /* AAD */
GCM_AUTH_TAG_LEN_8, GCM_AUTH_TAG_LEN_8,
NULL /* pointer to next testcase */ NULL /* pointer to next testcase */
}; };
cipher_test_case_t aes_gcm_test_case_1 = { static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
aes_gcm_test_case_1_key, /* key */ srtp_aes_gcm_test_case_1_key, /* key */
aes_gcm_test_case_1_iv, /* packet index */ srtp_aes_gcm_test_case_1_iv, /* packet index */
60, /* octets in plaintext */ 60, /* octets in plaintext */
aes_gcm_test_case_1_plaintext, /* plaintext */ srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
76, /* octets in ciphertext */ 76, /* octets in ciphertext */
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */ srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
20, /* octets in AAD */ 20, /* octets in AAD */
aes_gcm_test_case_1_aad, /* AAD */ srtp_aes_gcm_test_case_1_aad, /* AAD */
GCM_AUTH_TAG_LEN, GCM_AUTH_TAG_LEN,
&aes_gcm_test_case_1a /* pointer to next testcase */ &srtp_aes_gcm_test_case_1a /* pointer to next testcase */
}; };
/* /*
* This is the vector function table for this crypto engine. * This is the vector function table for this crypto engine.
*/ */
cipher_type_t aes_gcm_128_openssl = { const srtp_cipher_type_t srtp_aes_gcm_128_openssl = {
(cipher_alloc_func_t) aes_gcm_openssl_alloc, srtp_aes_gcm_openssl_alloc,
(cipher_dealloc_func_t) aes_gcm_openssl_dealloc, srtp_aes_gcm_openssl_dealloc,
(cipher_init_func_t) aes_gcm_openssl_context_init, srtp_aes_gcm_openssl_context_init,
(cipher_set_aad_func_t) aes_gcm_openssl_set_aad, srtp_aes_gcm_openssl_set_aad,
(cipher_encrypt_func_t) aes_gcm_openssl_encrypt, srtp_aes_gcm_openssl_encrypt,
(cipher_decrypt_func_t) aes_gcm_openssl_decrypt, srtp_aes_gcm_openssl_decrypt,
(cipher_set_iv_func_t) aes_gcm_openssl_set_iv, srtp_aes_gcm_openssl_set_iv,
(cipher_get_tag_func_t) aes_gcm_openssl_get_tag, srtp_aes_gcm_openssl_get_tag,
(char*) aes_gcm_128_openssl_description, srtp_aes_gcm_128_openssl_description,
(int) 0, /* instance count */ &srtp_aes_gcm_test_case_0,
(cipher_test_case_t*) &aes_gcm_test_case_0, SRTP_AES_GCM_128
(debug_module_t*) &mod_aes_gcm,
(cipher_type_id_t) AES_128_GCM
}; };
/* /*
* This is the vector function table for this crypto engine. * This is the vector function table for this crypto engine.
*/ */
cipher_type_t aes_gcm_256_openssl = { const srtp_cipher_type_t srtp_aes_gcm_256_openssl = {
(cipher_alloc_func_t) aes_gcm_openssl_alloc, srtp_aes_gcm_openssl_alloc,
(cipher_dealloc_func_t) aes_gcm_openssl_dealloc, srtp_aes_gcm_openssl_dealloc,
(cipher_init_func_t) aes_gcm_openssl_context_init, srtp_aes_gcm_openssl_context_init,
(cipher_set_aad_func_t) aes_gcm_openssl_set_aad, srtp_aes_gcm_openssl_set_aad,
(cipher_encrypt_func_t) aes_gcm_openssl_encrypt, srtp_aes_gcm_openssl_encrypt,
(cipher_decrypt_func_t) aes_gcm_openssl_decrypt, srtp_aes_gcm_openssl_decrypt,
(cipher_set_iv_func_t) aes_gcm_openssl_set_iv, srtp_aes_gcm_openssl_set_iv,
(cipher_get_tag_func_t) aes_gcm_openssl_get_tag, srtp_aes_gcm_openssl_get_tag,
(char*) aes_gcm_256_openssl_description, srtp_aes_gcm_256_openssl_description,
(int) 0, /* instance count */ &srtp_aes_gcm_test_case_1,
(cipher_test_case_t*) &aes_gcm_test_case_1, SRTP_AES_GCM_256
(debug_module_t*) &mod_aes_gcm,
(cipher_type_id_t) AES_256_GCM
}; };

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,6 +43,9 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define ALIGN_32 0 #define ALIGN_32 0
@ -50,17 +53,19 @@
#include "alloc.h" #include "alloc.h"
debug_module_t mod_aes_icm = { srtp_debug_module_t srtp_mod_aes_icm = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"aes icm" /* printable module name */ "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: * integer counter mode works as follows:
* *
* 16 bits * 16 bits
* <-----> * <----->
* +------+------+------+------+------+------+------+------+ * +------+------+------+------+------+------+------+------+
* | nonce | pakcet index | ctr |---+ * | nonce | pakcet index | ctr |---+
* +------+------+------+------+------+------+------+------+ | * +------+------+------+------+------+------+------+------+ |
* | * |
@ -71,16 +76,16 @@ debug_module_t mod_aes_icm = {
* +---------+ * +---------+
* | encrypt | * | encrypt |
* +---------+ * +---------+
* | * |
* +------+------+------+------+------+------+------+------+ | * +------+------+------+------+------+------+------+------+ |
* | keystream block |<--+ * | keystream block |<--+
* +------+------+------+------+------+------+------+------+ * +------+------+------+------+------+------+------+------+
* *
* All fields are big-endian * All fields are big-endian
* *
* ctr is the block counter, which increments from zero for * ctr is the block counter, which increments from zero for
* each packet (16 bits wide) * each packet (16 bits wide)
* *
* packet index is distinct for each packet (48 bits wide) * packet index is distinct for each packet (48 bits wide)
* *
* nonce can be distinct across many uses of the same key, or * nonce can be distinct across many uses of the same key, or
@ -89,77 +94,77 @@ debug_module_t mod_aes_icm = {
* *
*/ */
err_status_t static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int tlen)
aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) { {
extern cipher_type_t aes_icm; srtp_aes_icm_ctx_t *icm;
uint8_t *pointer;
int tmp;
debug_print(mod_aes_icm, debug_print(srtp_mod_aes_icm,
"allocating cipher with key length %d", key_len); "allocating cipher with key length %d", key_len);
/* /*
* Ismacryp, for example, uses 16 byte key + 8 byte * The check for key_len = 30/46 does not apply. Our usage
* salt so this function is called with key_len = 24. * of aes functions with key_len = values other than 30
* The check for key_len = 30/38/46 does not apply. Our usage * has not broken anything. Don't know what would be the
* of aes functions with key_len = values other than 30 * effect of skipping this check for srtp in general.
* 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) {
*/ return srtp_err_status_bad_param;
if (!(forIsmacryp && key_len > 16 && key_len < 30) && }
key_len != 30 && key_len != 38 && key_len != 46)
return err_status_bad_param;
/* allocate memory a cipher of type aes_icm */ /* allocate memory a cipher of type aes_icm */
tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
pointer = (uint8_t*)crypto_alloc(tmp); if (*c == NULL) {
if (pointer == NULL) return srtp_err_status_alloc_fail;
return err_status_alloc_fail; }
memset(*c, 0x0, sizeof(srtp_cipher_t));
/* set pointers */ icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
*c = (cipher_t *)pointer; if (icm == NULL) {
switch (key_len) { srtp_crypto_free(*c);
case 46: return srtp_err_status_alloc_fail;
(*c)->algorithm = AES_256_ICM; }
break; memset(icm, 0x0, sizeof(srtp_aes_icm_ctx_t));
case 38:
(*c)->algorithm = AES_192_ICM;
break;
default:
(*c)->algorithm = AES_128_ICM;
break;
}
(*c)->type = &aes_icm;
(*c)->state = pointer + sizeof(cipher_t);
/* increment ref_count */ /* set pointers */
aes_icm.ref_count++; (*c)->state = icm;
/* set key size */ switch (key_len) {
(*c)->key_len = key_len; case SRTP_AES_ICM_256_KEY_LEN_WSALT:
(*c)->algorithm = SRTP_AES_ICM_256;
(*c)->type = &srtp_aes_icm_256;
break;
default:
(*c)->algorithm = SRTP_AES_ICM_128;
(*c)->type = &srtp_aes_icm_128;
break;
}
return err_status_ok; /* set key size */
icm->key_size = key_len;
(*c)->key_len = key_len;
return srtp_err_status_ok;
} }
err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) { static srtp_err_status_t srtp_aes_icm_dealloc (srtp_cipher_t *c)
return aes_icm_alloc_ismacryp(c, key_len, 0); {
} srtp_aes_icm_ctx_t *ctx;
err_status_t if (c == NULL) {
aes_icm_dealloc(cipher_t *c) { return srtp_err_status_bad_param;
extern cipher_type_t aes_icm; }
/* zeroize entire state*/ ctx = (srtp_aes_icm_ctx_t *)c->state;
octet_string_set_to_zero((uint8_t *)c, if (ctx) {
sizeof(aes_icm_ctx_t) + sizeof(cipher_t)); /* zeroize the key material */
octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
srtp_crypto_free(ctx);
}
/* free memory */ /* free the cipher context */
crypto_free(c); srtp_crypto_free(c);
/* decrement ref_count */ return srtp_err_status_ok;
aes_icm.ref_count--;
return err_status_ok;
} }
@ -167,114 +172,57 @@ aes_icm_dealloc(cipher_t *c) {
* aes_icm_context_init(...) initializes the aes_icm_context * aes_icm_context_init(...) initializes the aes_icm_context
* using the value in key[]. * using the value in key[].
* *
* the key is the secret key * the key is the secret key
* *
* the salt is unpredictable (but not necessarily secret) data which * the salt is unpredictable (but not necessarily secret) data which
* randomizes the starting point in the keystream * randomizes the starting point in the keystream
*/ */
err_status_t static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key)
aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) { {
err_status_t status; srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
int base_key_len, copy_len; srtp_err_status_t status;
int base_key_len, copy_len;
if (key_len > 16 && key_len < 30) /* Ismacryp */ if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT || c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) {
base_key_len = 16; base_key_len = c->key_size - SRTP_SALT_LEN;
else if (key_len == 30 || key_len == 38 || key_len == 46) } else{
base_key_len = key_len - 14; return srtp_err_status_bad_param;
else }
return err_status_bad_param;
/* /*
* set counter and initial values to 'offset' value, being careful not to * set counter and initial values to 'offset' value, being careful not to
* go past the end of the key buffer * go past the end of the key buffer
*/ */
v128_set_to_zero(&c->counter);
v128_set_to_zero(&c->offset);
copy_len = key_len - base_key_len;
/* force last two octets of the offset to be left zero (for srtp compatibility) */
if (copy_len > 14)
copy_len = 14;
memcpy(&c->counter, key + base_key_len, copy_len);
memcpy(&c->offset, key + base_key_len, copy_len);
debug_print(mod_aes_icm,
"key: %s", octet_string_hex_string(key, base_key_len));
debug_print(mod_aes_icm,
"offset: %s", v128_hex_string(&c->offset));
/* expand key */
status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
if (status) {
v128_set_to_zero(&c->counter); v128_set_to_zero(&c->counter);
v128_set_to_zero(&c->offset); v128_set_to_zero(&c->offset);
return status;
}
/* indicate that the keystream_buffer is empty */ copy_len = c->key_size - base_key_len;
c->bytes_in_buffer = 0; /* 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;
}
return err_status_ok; memcpy(&c->counter, key + base_key_len, copy_len);
} memcpy(&c->offset, key + base_key_len, copy_len);
/* debug_print(srtp_mod_aes_icm,
* aes_icm_set_octet(c, i) sets the counter of the context which it is "key: %s", srtp_octet_string_hex_string(key, base_key_len));
* passed so that the next octet of keystream that will be generated debug_print(srtp_mod_aes_icm,
* is the ith octet "offset: %s", v128_hex_string(&c->offset));
*/
err_status_t /* expand key */
aes_icm_set_octet(aes_icm_ctx_t *c, status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
uint64_t octet_num) { if (status) {
v128_set_to_zero(&c->counter);
v128_set_to_zero(&c->offset);
return status;
}
#ifdef NO_64BIT_MATH /* indicate that the keystream_buffer is empty */
int tail_num = low32(octet_num) & 0x0f;
/* 64-bit right-shift 4 */
uint64_t block_num = make64(high32(octet_num) >> 4,
((high32(octet_num) & 0x0f)<<(32-4)) |
(low32(octet_num) >> 4));
#else
int tail_num = (int)(octet_num % 16);
uint64_t block_num = octet_num / 16;
#endif
/* set counter value */
/* FIX - There's no way this is correct */
c->counter.v64[0] = c->offset.v64[0];
#ifdef NO_64BIT_MATH
c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
low32(c->offset.v64[0]) ^ low32(block_num));
#else
c->counter.v64[0] = c->offset.v64[0] ^ block_num;
#endif
debug_print(mod_aes_icm,
"set_octet: %s", v128_hex_string(&c->counter));
/* fill keystream buffer, if needed */
if (tail_num) {
v128_copy(&c->keystream_buffer, &c->counter);
aes_encrypt(&c->keystream_buffer, &c->expanded_key);
c->bytes_in_buffer = sizeof(v128_t);
debug_print(mod_aes_icm, "counter: %s",
v128_hex_string(&c->counter));
debug_print(mod_aes_icm, "ciphertext: %s",
v128_hex_string(&c->keystream_buffer));
/* indicate number of bytes in keystream_buffer */
c->bytes_in_buffer = sizeof(v128_t) - tail_num;
} else {
/* indicate that keystream_buffer is empty */
c->bytes_in_buffer = 0; c->bytes_in_buffer = 0;
}
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
@ -282,25 +230,26 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
* the offset * the offset
*/ */
err_status_t static srtp_err_status_t srtp_aes_icm_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) { {
v128_t nonce; srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
v128_t nonce;
/* set nonce (for alignment) */ /* set nonce (for alignment) */
v128_copy_octet_string(&nonce, iv); v128_copy_octet_string(&nonce, iv);
debug_print(mod_aes_icm, debug_print(srtp_mod_aes_icm,
"setting iv: %s", v128_hex_string(&nonce)); "setting iv: %s", v128_hex_string(&nonce));
v128_xor(&c->counter, &c->offset, &nonce);
debug_print(mod_aes_icm,
"set_counter: %s", v128_hex_string(&c->counter));
/* indicate that the keystream_buffer is empty */ v128_xor(&c->counter, &c->offset, &nonce);
c->bytes_in_buffer = 0;
return err_status_ok; 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;
return srtp_err_status_ok;
} }
@ -311,37 +260,24 @@ aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) {
* *
* this is an internal, hopefully inlined function * this is an internal, hopefully inlined function
*/ */
static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
static inline void {
aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) { /* fill buffer with new keystream */
/* fill buffer with new keystream */ v128_copy(&c->keystream_buffer, &c->counter);
v128_copy(&c->keystream_buffer, &c->counter); srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
aes_encrypt(&c->keystream_buffer, &c->expanded_key); c->bytes_in_buffer = sizeof(v128_t);
c->bytes_in_buffer = sizeof(v128_t);
debug_print(mod_aes_icm, "counter: %s", debug_print(srtp_mod_aes_icm, "counter: %s",
v128_hex_string(&c->counter)); v128_hex_string(&c->counter));
debug_print(mod_aes_icm, "ciphertext: %s", debug_print(srtp_mod_aes_icm, "ciphertext: %s",
v128_hex_string(&c->keystream_buffer)); v128_hex_string(&c->keystream_buffer));
/* clock counter forward */
if (forIsmacryp) { /* clock counter forward */
uint32_t temp; if (!++(c->counter.v8[15])) {
//alex's clock counter forward ++(c->counter.v8[14]);
temp = ntohl(c->counter.v32[3]); }
c->counter.v32[3] = htonl(++temp);
} else {
if (!++(c->counter.v8[15]))
++(c->counter.v8[14]);
}
} }
static inline void aes_icm_advance(aes_icm_ctx_t *c) {
aes_icm_advance_ismacryp(c, 0);
}
/*e /*e
* icm_encrypt deals with the following cases: * icm_encrypt deals with the following cases:
* *
@ -352,221 +288,202 @@ static inline void aes_icm_advance(aes_icm_ctx_t *c) {
* - add keystream into data until keystream_buffer is depleted * - add keystream into data until keystream_buffer is depleted
* - loop over blocks, filling keystream_buffer and then * - loop over blocks, filling keystream_buffer and then
* adding keystream into data * adding keystream into data
* - fill buffer then add in remaining (< 16) bytes of keystream * - fill buffer then add in remaining (< 16) bytes of keystream
*/ */
err_status_t static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len)
unsigned char *buf, unsigned int *enc_len, {
int forIsmacryp) { srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t*)cv;
unsigned int bytes_to_encr = *enc_len; unsigned int bytes_to_encr = *enc_len;
unsigned int i; unsigned int i;
uint32_t *b; uint32_t *b;
/* check that there's enough segment left but not for ismacryp*/ /* check that there's enough segment left*/
if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
return err_status_terminus; return srtp_err_status_terminus;
}
debug_print(mod_aes_icm, "block index: %d", debug_print(srtp_mod_aes_icm, "block index: %d",
htons(c->counter.v16[7])); htons(c->counter.v16[7]));
if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) { 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++)
{
*buf++ ^= c->keystream_buffer.v8[i];
}
c->bytes_in_buffer -= bytes_to_encr; /* 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++) {
*buf++ ^= c->keystream_buffer.v8[i];
}
/* return now to avoid the main loop */ c->bytes_in_buffer -= bytes_to_encr;
return err_status_ok;
} else { /* return now to avoid the main loop */
return srtp_err_status_ok;
/* encrypt bytes until the remaining data is 16-byte aligned */
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; } else {
c->bytes_in_buffer = 0;
} /* encrypt bytes until the remaining data is 16-byte aligned */
for (i = (sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) {
/* now loop over entire 16-byte blocks of keystream */ *buf++ ^= c->keystream_buffer.v8[i];
for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) { }
/* fill buffer with new keystream */ bytes_to_encr -= c->bytes_in_buffer;
aes_icm_advance_ismacryp(c, forIsmacryp); c->bytes_in_buffer = 0;
/* }
* add keystream into the data buffer (this would be a lot faster
* if we could assume 32-bit alignment!) /* 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!)
*/
#if ALIGN_32 #if ALIGN_32
b = (uint32_t *)buf; b = (uint32_t*)buf;
*b++ ^= c->keystream_buffer.v32[0]; *b++ ^= c->keystream_buffer.v32[0];
*b++ ^= c->keystream_buffer.v32[1]; *b++ ^= c->keystream_buffer.v32[1];
*b++ ^= c->keystream_buffer.v32[2]; *b++ ^= c->keystream_buffer.v32[2];
*b++ ^= c->keystream_buffer.v32[3]; *b++ ^= c->keystream_buffer.v32[3];
buf = (uint8_t *)b; buf = (uint8_t*)b;
#else #else
if ((((unsigned long) buf) & 0x03) != 0) { if ((((unsigned long)buf) & 0x03) != 0) {
*buf++ ^= c->keystream_buffer.v8[0]; *buf++ ^= c->keystream_buffer.v8[0];
*buf++ ^= c->keystream_buffer.v8[1]; *buf++ ^= c->keystream_buffer.v8[1];
*buf++ ^= c->keystream_buffer.v8[2]; *buf++ ^= c->keystream_buffer.v8[2];
*buf++ ^= c->keystream_buffer.v8[3]; *buf++ ^= c->keystream_buffer.v8[3];
*buf++ ^= c->keystream_buffer.v8[4]; *buf++ ^= c->keystream_buffer.v8[4];
*buf++ ^= c->keystream_buffer.v8[5]; *buf++ ^= c->keystream_buffer.v8[5];
*buf++ ^= c->keystream_buffer.v8[6]; *buf++ ^= c->keystream_buffer.v8[6];
*buf++ ^= c->keystream_buffer.v8[7]; *buf++ ^= c->keystream_buffer.v8[7];
*buf++ ^= c->keystream_buffer.v8[8]; *buf++ ^= c->keystream_buffer.v8[8];
*buf++ ^= c->keystream_buffer.v8[9]; *buf++ ^= c->keystream_buffer.v8[9];
*buf++ ^= c->keystream_buffer.v8[10]; *buf++ ^= c->keystream_buffer.v8[10];
*buf++ ^= c->keystream_buffer.v8[11]; *buf++ ^= c->keystream_buffer.v8[11];
*buf++ ^= c->keystream_buffer.v8[12]; *buf++ ^= c->keystream_buffer.v8[12];
*buf++ ^= c->keystream_buffer.v8[13]; *buf++ ^= c->keystream_buffer.v8[13];
*buf++ ^= c->keystream_buffer.v8[14]; *buf++ ^= c->keystream_buffer.v8[14];
*buf++ ^= c->keystream_buffer.v8[15]; *buf++ ^= c->keystream_buffer.v8[15];
} else { } else {
b = (uint32_t *)buf; b = (uint32_t*)buf;
*b++ ^= c->keystream_buffer.v32[0]; *b++ ^= c->keystream_buffer.v32[0];
*b++ ^= c->keystream_buffer.v32[1]; *b++ ^= c->keystream_buffer.v32[1];
*b++ ^= c->keystream_buffer.v32[2]; *b++ ^= c->keystream_buffer.v32[2];
*b++ ^= c->keystream_buffer.v32[3]; *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) {
/* if there is a tail end of the data, process it */
if ((bytes_to_encr & 0xf) != 0) {
/* fill buffer with new keystream */
aes_icm_advance_ismacryp(c, forIsmacryp);
for (i=0; i < (bytes_to_encr & 0xf); i++)
*buf++ ^= c->keystream_buffer.v8[i];
/* 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 */ /* fill buffer with new keystream */
c->bytes_in_buffer = 0; srtp_aes_icm_advance(c);
} for (i = 0; i < (bytes_to_encr & 0xf); i++) {
*buf++ ^= c->keystream_buffer.v8[i];
}
return err_status_ok; /* 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;
} }
err_status_t static const char srtp_aes_icm_128_description[] = "AES-128 integer counter mode";
aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) { static const char srtp_aes_icm_256_description[] = "AES-256 integer counter mode";
return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
}
err_status_t static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
unsigned int len = num_octets_to_output; 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
/* zeroize the buffer */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
octet_string_set_to_zero(buffer, num_octets_to_output);
/* exor keystream into buffer */
return aes_icm_encrypt(c, buffer, &len);
}
uint16_t
aes_icm_bytes_encrypted(aes_icm_ctx_t *c) {
return htons(c->counter.v16[7]);
}
char
aes_icm_description[] = "aes integer counter mode";
uint8_t aes_icm_test_case_0_key[30] = {
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
}; };
uint8_t aes_icm_test_case_0_nonce[16] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
uint8_t aes_icm_test_case_0_plaintext[32] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
uint8_t aes_icm_test_case_0_ciphertext[32] = { static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
}; };
cipher_test_case_t aes_icm_test_case_0 = { static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
30, /* octets in key */ SRTP_AES_ICM_128_KEY_LEN_WSALT, /* octets in key */
aes_icm_test_case_0_key, /* key */ srtp_aes_icm_128_test_case_0_key, /* key */
aes_icm_test_case_0_nonce, /* packet index */ srtp_aes_icm_128_test_case_0_nonce, /* packet index */
32, /* octets in plaintext */ 32, /* octets in plaintext */
aes_icm_test_case_0_plaintext, /* plaintext */ srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */ 32, /* octets in ciphertext */
aes_icm_test_case_0_ciphertext, /* ciphertext */ srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
0, 0,
NULL, NULL,
0, 0,
NULL /* pointer to next testcase */ NULL /* pointer to next testcase */
}; };
uint8_t aes_icm_test_case_1_key[46] = { 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, 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92, 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82, 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98, 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
}; };
uint8_t aes_icm_test_case_1_nonce[16] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
uint8_t aes_icm_test_case_1_plaintext[32] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
uint8_t aes_icm_test_case_1_ciphertext[32] = { static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25, 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4, 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6, 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
}; };
cipher_test_case_t aes_icm_test_case_1 = { static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
46, /* octets in key */ SRTP_AES_ICM_256_KEY_LEN_WSALT, /* octets in key */
aes_icm_test_case_1_key, /* key */ srtp_aes_icm_256_test_case_0_key, /* key */
aes_icm_test_case_1_nonce, /* packet index */ srtp_aes_icm_256_test_case_0_nonce, /* packet index */
32, /* octets in plaintext */ 32, /* octets in plaintext */
aes_icm_test_case_1_plaintext, /* plaintext */ srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */ 32, /* octets in ciphertext */
aes_icm_test_case_1_ciphertext, /* ciphertext */ srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
0, 0,
NULL, NULL,
0, 0,
&aes_icm_test_case_0 /* pointer to next testcase */ NULL, /* pointer to next testcase */
}; };
@ -575,19 +492,30 @@ cipher_test_case_t aes_icm_test_case_1 = {
* note: the encrypt function is identical to the decrypt function * note: the encrypt function is identical to the decrypt function
*/ */
cipher_type_t aes_icm = { const srtp_cipher_type_t srtp_aes_icm_128 = {
(cipher_alloc_func_t) aes_icm_alloc, srtp_aes_icm_alloc,
(cipher_dealloc_func_t) aes_icm_dealloc, srtp_aes_icm_dealloc,
(cipher_init_func_t) aes_icm_context_init, srtp_aes_icm_context_init,
(cipher_set_aad_func_t) 0, 0, /* set_aad */
(cipher_encrypt_func_t) aes_icm_encrypt, srtp_aes_icm_encrypt,
(cipher_decrypt_func_t) aes_icm_encrypt, srtp_aes_icm_encrypt,
(cipher_set_iv_func_t) aes_icm_set_iv, srtp_aes_icm_set_iv,
(cipher_get_tag_func_t) 0, 0, /* get_tag */
(char *) aes_icm_description, srtp_aes_icm_128_description,
(int) 0, /* instance count */ &srtp_aes_icm_128_test_case_0,
(cipher_test_case_t *) &aes_icm_test_case_1, SRTP_AES_ICM_128
(debug_module_t *) &mod_aes_icm,
(cipher_type_id_t) AES_ICM
}; };
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
};

View File

@ -14,7 +14,7 @@
/* /*
* *
* Copyright (c) 2013, Cisco Systems, Inc. * Copyright (c) 2013-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,21 +48,24 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <openssl/evp.h> #include <openssl/evp.h>
#include "aes_icm_ossl.h" #include "aes_icm_ossl.h"
#include "crypto_types.h" #include "crypto_types.h"
#include "err.h" /* for srtp_debug */
#include "alloc.h" #include "alloc.h"
#include "crypto_types.h"
debug_module_t mod_aes_icm = { srtp_debug_module_t srtp_mod_aes_icm = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"aes icm ossl" /* printable module name */ "aes icm ossl" /* printable module name */
}; };
extern cipher_test_case_t aes_icm_test_case_0; extern const srtp_cipher_type_t srtp_aes_icm_128;
extern cipher_type_t aes_icm; extern const srtp_cipher_type_t srtp_aes_icm_192;
extern cipher_type_t aes_icm_192; extern const srtp_cipher_type_t srtp_aes_icm_256;
extern cipher_type_t aes_icm_256;
/* /*
* integer counter mode works as follows: * integer counter mode works as follows:
@ -70,7 +73,7 @@ extern cipher_type_t aes_icm_256;
* 16 bits * 16 bits
* <-----> * <----->
* +------+------+------+------+------+------+------+------+ * +------+------+------+------+------+------+------+------+
* | nonce | pakcet index | ctr |---+ * | nonce | packet index | ctr |---+
* +------+------+------+------+------+------+------+------+ | * +------+------+------+------+------+------+------+------+ |
* | * |
* +------+------+------+------+------+------+------+------+ v * +------+------+------+------+------+------+------+------+ v
@ -106,106 +109,98 @@ extern cipher_type_t aes_icm_256;
* value. The tlen argument is for the AEAD tag length, which * value. The tlen argument is for the AEAD tag length, which
* isn't used in counter mode. * isn't used in counter mode.
*/ */
err_status_t aes_icm_openssl_alloc (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)
{ {
aes_icm_ctx_t *icm; srtp_aes_icm_ctx_t *icm;
int tmp;
uint8_t *allptr;
debug_print(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 * Verify the key_len is valid for one of: AES-128/192/256
*/ */
if (key_len != AES_128_KEYSIZE_WSALT && key_len != AES_192_KEYSIZE_WSALT && if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT && key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
key_len != AES_256_KEYSIZE_WSALT) { key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
return err_status_bad_param; return srtp_err_status_bad_param;
} }
/* allocate memory a cipher of type aes_icm */ /* allocate memory a cipher of type aes_icm */
tmp = sizeof(cipher_t) + sizeof(aes_icm_ctx_t); *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
allptr = (uint8_t*)crypto_alloc(tmp); if (*c == NULL) {
if (allptr == NULL) { return srtp_err_status_alloc_fail;
return 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;
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) {
srtp_crypto_free(icm);
srtp_crypto_free(*c);
*c = NULL;
return srtp_err_status_alloc_fail;
} }
/* set pointers */ /* set pointers */
*c = (cipher_t*)allptr; (*c)->state = icm;
(*c)->state = allptr + sizeof(cipher_t);
icm = (aes_icm_ctx_t*)(*c)->state;
/* increment ref_count */ /* setup cipher parameters */
switch (key_len) { switch (key_len) {
case AES_128_KEYSIZE_WSALT: case SRTP_AES_ICM_128_KEY_LEN_WSALT:
(*c)->algorithm = AES_128_ICM; (*c)->algorithm = SRTP_AES_ICM_128;
(*c)->type = &aes_icm; (*c)->type = &srtp_aes_icm_128;
aes_icm.ref_count++; icm->key_size = SRTP_AES_128_KEY_LEN;
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
break; break;
case AES_192_KEYSIZE_WSALT: case SRTP_AES_ICM_192_KEY_LEN_WSALT:
(*c)->algorithm = AES_192_ICM; (*c)->algorithm = SRTP_AES_ICM_192;
(*c)->type = &aes_icm_192; (*c)->type = &srtp_aes_icm_192;
aes_icm_192.ref_count++; icm->key_size = SRTP_AES_192_KEY_LEN;
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_192_KEYSIZE;
break; break;
case AES_256_KEYSIZE_WSALT: case SRTP_AES_ICM_256_KEY_LEN_WSALT:
(*c)->algorithm = AES_256_ICM; (*c)->algorithm = SRTP_AES_ICM_256;
(*c)->type = &aes_icm_256; (*c)->type = &srtp_aes_icm_256;
aes_icm_256.ref_count++; icm->key_size = SRTP_AES_256_KEY_LEN;
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
break; break;
} }
/* set key size */ /* set key size */
(*c)->key_len = key_len; (*c)->key_len = key_len;
EVP_CIPHER_CTX_init(&icm->ctx);
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
* This function deallocates an instance of this engine * This function deallocates an instance of this engine
*/ */
err_status_t aes_icm_openssl_dealloc (cipher_t *c) static srtp_err_status_t srtp_aes_icm_openssl_dealloc (srtp_cipher_t *c)
{ {
aes_icm_ctx_t *ctx; srtp_aes_icm_ctx_t *ctx;
if (c == NULL) { if (c == NULL) {
return err_status_bad_param; return srtp_err_status_bad_param;
} }
/* /*
* Free the EVP context * Free the EVP context
*/ */
ctx = (aes_icm_ctx_t*)c->state; ctx = (srtp_aes_icm_ctx_t*)c->state;
if (ctx != NULL) { if (ctx != NULL) {
EVP_CIPHER_CTX_cleanup(&ctx->ctx); EVP_CIPHER_CTX_free(ctx->ctx);
/* decrement ref_count for the appropriate engine */ /* zeroize the key material */
switch (ctx->key_size) { octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
case AES_256_KEYSIZE: srtp_crypto_free(ctx);
aes_icm_256.ref_count--;
break;
case AES_192_KEYSIZE:
aes_icm_192.ref_count--;
break;
case AES_128_KEYSIZE:
aes_icm.ref_count--;
break;
default:
return err_status_dealloc_fail;
break;
}
} }
/* zeroize entire state*/
octet_string_set_to_zero((uint8_t*)c,
sizeof(cipher_t) + sizeof(aes_icm_ctx_t));
/* free memory */ /* free memory */
crypto_free(c); srtp_crypto_free(c);
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
@ -217,42 +212,50 @@ err_status_t aes_icm_openssl_dealloc (cipher_t *c)
* the salt is unpredictable (but not necessarily secret) data which * the salt is unpredictable (but not necessarily secret) data which
* randomizes the starting point in the keystream * randomizes the starting point in the keystream
*/ */
err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, 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;
/* /*
* set counter and initial values to 'offset' value, being careful not to * set counter and initial values to 'offset' value, being careful not to
* go past the end of the key buffer * go past the end of the key buffer
*/ */
v128_set_to_zero(&c->counter); v128_set_to_zero(&c->counter);
v128_set_to_zero(&c->offset); v128_set_to_zero(&c->offset);
memcpy(&c->counter, key + c->key_size, SALT_SIZE); memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
memcpy(&c->offset, key + c->key_size, SALT_SIZE); memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
/* force last two octets of the offset to zero (for srtp compatibility) */ /* force last two octets of the offset to zero (for srtp compatibility) */
c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0; c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0; c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
/* copy key to be used later when CiscoSSL crypto context is created */ debug_print(srtp_mod_aes_icm, "key: %s", srtp_octet_string_hex_string(key, c->key_size));
v128_copy_octet_string((v128_t*)&c->key, key); debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
/* if the key is greater than 16 bytes, copy the second switch (c->key_size) {
* half. Note, we treat AES-192 and AES-256 the same here case SRTP_AES_256_KEY_LEN:
* for simplicity. The storage location receiving the evp = EVP_aes_256_ctr();
* key is statically allocated to handle a full 32 byte key break;
* regardless of the cipher in use. case SRTP_AES_192_KEY_LEN:
*/ evp = EVP_aes_192_ctr();
if (c->key_size == AES_256_KEYSIZE || c->key_size == AES_192_KEYSIZE) { break;
debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s", case SRTP_AES_128_KEY_LEN:
v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); evp = EVP_aes_128_ctr();
v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE); break;
default:
return srtp_err_status_bad_param;
break;
} }
debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key)); if (!EVP_EncryptInit_ex(c->ctx, evp,
debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); NULL, key, NULL)) {
return srtp_err_status_fail;
} else {
return srtp_err_status_ok;
}
EVP_CIPHER_CTX_cleanup(&c->ctx); return srtp_err_status_ok;
return err_status_ok;
} }
@ -260,40 +263,25 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key)
* aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
* the offset * the offset
*/ */
err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir) static srtp_err_status_t srtp_aes_icm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
{ {
const EVP_CIPHER *evp; srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
v128_t nonce; v128_t nonce;
/* set nonce (for alignment) */ /* set nonce (for alignment) */
v128_copy_octet_string(&nonce, iv); v128_copy_octet_string(&nonce, iv);
debug_print(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); v128_xor(&c->counter, &c->offset, &nonce);
debug_print(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));
switch (c->key_size) { if (!EVP_EncryptInit_ex(c->ctx, NULL,
case AES_256_KEYSIZE: NULL, NULL, c->counter.v8)) {
evp = EVP_aes_256_ctr(); return srtp_err_status_fail;
break;
case AES_192_KEYSIZE:
evp = EVP_aes_192_ctr();
break;
case AES_128_KEYSIZE:
evp = EVP_aes_128_ctr();
break;
default:
return err_status_bad_param;
break;
}
if (!EVP_EncryptInit_ex(&c->ctx, evp,
NULL, c->key.v8, c->counter.v8)) {
return err_status_fail;
} else { } else {
return err_status_ok; return srtp_err_status_ok;
} }
} }
@ -305,85 +293,72 @@ err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir)
* buf data to encrypt * buf data to encrypt
* enc_len length of encrypt buffer * enc_len length of encrypt buffer
*/ */
err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) 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; int len = 0;
debug_print(mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
if (!EVP_EncryptUpdate(&c->ctx, buf, &len, buf, *enc_len)) { if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
return err_status_cipher_fail; return srtp_err_status_cipher_fail;
} }
*enc_len = len; *enc_len = len;
if (!EVP_EncryptFinal_ex(&c->ctx, buf, (int*)&len)) { if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
return err_status_cipher_fail; return srtp_err_status_cipher_fail;
} }
*enc_len += len; *enc_len += len;
return err_status_ok; return srtp_err_status_ok;
}
/*
* Abstraction layer for encrypt.
*/
err_status_t aes_icm_output (aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output)
{
unsigned int len = num_octets_to_output;
/* zeroize the buffer */
octet_string_set_to_zero(buffer, num_octets_to_output);
/* exor keystream into buffer */
return aes_icm_openssl_encrypt(c, buffer, &len);
} }
/* /*
* Name of this crypto engine * Name of this crypto engine
*/ */
char aes_icm_openssl_description[] = "AES-128 counter mode using openssl"; static const char srtp_aes_icm_128_openssl_description[] = "AES-128 counter mode using openssl";
char aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl"; static const char srtp_aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
char aes_icm_256_openssl_description[] = "AES-256 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 * KAT values for AES self-test. These
* values came from the legacy libsrtp code. * values came from the legacy libsrtp code.
*/ */
uint8_t aes_icm_test_case_0_key[AES_128_KEYSIZE_WSALT] = { 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, 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
}; };
uint8_t aes_icm_test_case_0_nonce[16] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
uint8_t aes_icm_test_case_0_plaintext[32] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
uint8_t aes_icm_test_case_0_ciphertext[32] = { static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
}; };
cipher_test_case_t aes_icm_test_case_0 = { static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
AES_128_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_ICM_128_KEY_LEN_WSALT, /* octets in key */
aes_icm_test_case_0_key, /* key */ srtp_aes_icm_128_test_case_0_key, /* key */
aes_icm_test_case_0_nonce, /* packet index */ srtp_aes_icm_128_test_case_0_nonce, /* packet index */
32, /* octets in plaintext */ 32, /* octets in plaintext */
aes_icm_test_case_0_plaintext, /* plaintext */ srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */ 32, /* octets in ciphertext */
aes_icm_test_case_0_ciphertext, /* ciphertext */ srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
0, 0,
NULL, NULL,
0, 0,
@ -394,7 +369,7 @@ cipher_test_case_t aes_icm_test_case_0 = {
* KAT values for AES-192-CTR self-test. These * KAT values for AES-192-CTR self-test. These
* values came from section 7 of RFC 6188. * values came from section 7 of RFC 6188.
*/ */
uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = { 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, 0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21, 0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7, 0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
@ -402,45 +377,44 @@ uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
}; };
uint8_t aes_icm_192_test_case_1_nonce[16] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
uint8_t aes_icm_192_test_case_1_plaintext[32] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
uint8_t aes_icm_192_test_case_1_ciphertext[32] = { static const uint8_t srtp_aes_icm_192_test_case_0_ciphertext[32] = {
0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d, 0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d,
0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c, 0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61, 0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a 0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
}; };
cipher_test_case_t aes_icm_192_test_case_1 = { static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
AES_192_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_ICM_192_KEY_LEN_WSALT, /* octets in key */
aes_icm_192_test_case_1_key, /* key */ srtp_aes_icm_192_test_case_0_key, /* key */
aes_icm_192_test_case_1_nonce, /* packet index */ srtp_aes_icm_192_test_case_0_nonce, /* packet index */
32, /* octets in plaintext */ 32, /* octets in plaintext */
aes_icm_192_test_case_1_plaintext, /* plaintext */ srtp_aes_icm_192_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */ 32, /* octets in ciphertext */
aes_icm_192_test_case_1_ciphertext, /* ciphertext */ srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext */
0, 0,
NULL, NULL,
0, 0,
NULL /* pointer to next testcase */ NULL /* pointer to next testcase */
}; };
/* /*
* KAT values for AES-256-CTR self-test. These * KAT values for AES-256-CTR self-test. These
* values came from section 7 of RFC 6188. * values came from section 7 of RFC 6188.
*/ */
uint8_t aes_icm_256_test_case_2_key[AES_256_KEYSIZE_WSALT] = { 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, 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92, 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82, 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
@ -449,33 +423,33 @@ uint8_t aes_icm_256_test_case_2_key[AES_256_KEYSIZE_WSALT] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
}; };
uint8_t aes_icm_256_test_case_2_nonce[16] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
uint8_t aes_icm_256_test_case_2_plaintext[32] = { 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
uint8_t aes_icm_256_test_case_2_ciphertext[32] = { static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25, 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4, 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6, 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
}; };
cipher_test_case_t aes_icm_256_test_case_2 = { static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
AES_256_KEYSIZE_WSALT, /* octets in key */ SRTP_AES_ICM_256_KEY_LEN_WSALT, /* octets in key */
aes_icm_256_test_case_2_key, /* key */ srtp_aes_icm_256_test_case_0_key, /* key */
aes_icm_256_test_case_2_nonce, /* packet index */ srtp_aes_icm_256_test_case_0_nonce, /* packet index */
32, /* octets in plaintext */ 32, /* octets in plaintext */
aes_icm_256_test_case_2_plaintext, /* plaintext */ srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
32, /* octets in ciphertext */ 32, /* octets in ciphertext */
aes_icm_256_test_case_2_ciphertext, /* ciphertext */ srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
0, 0,
NULL, NULL,
0, 0,
@ -486,59 +460,53 @@ cipher_test_case_t aes_icm_256_test_case_2 = {
* This is the function table for this crypto engine. * This is the function table for this crypto engine.
* note: the encrypt function is identical to the decrypt function * note: the encrypt function is identical to the decrypt function
*/ */
cipher_type_t aes_icm = { const srtp_cipher_type_t srtp_aes_icm_128 = {
(cipher_alloc_func_t) aes_icm_openssl_alloc, srtp_aes_icm_openssl_alloc,
(cipher_dealloc_func_t) aes_icm_openssl_dealloc, srtp_aes_icm_openssl_dealloc,
(cipher_init_func_t) aes_icm_openssl_context_init, srtp_aes_icm_openssl_context_init,
(cipher_set_aad_func_t) 0, 0, /* set_aad */
(cipher_encrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_decrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_set_iv_func_t) aes_icm_openssl_set_iv, srtp_aes_icm_openssl_set_iv,
(cipher_get_tag_func_t) 0, 0, /* get_tag */
(char*) aes_icm_openssl_description, srtp_aes_icm_128_openssl_description,
(int) 0, /* instance count */ &srtp_aes_icm_128_test_case_0,
(cipher_test_case_t*) &aes_icm_test_case_0, SRTP_AES_ICM_128
(debug_module_t*) &mod_aes_icm,
(cipher_type_id_t) AES_ICM
}; };
/* /*
* This is the function table for this crypto engine. * This is the function table for this crypto engine.
* note: the encrypt function is identical to the decrypt function * note: the encrypt function is identical to the decrypt function
*/ */
cipher_type_t aes_icm_192 = { const srtp_cipher_type_t srtp_aes_icm_192 = {
(cipher_alloc_func_t) aes_icm_openssl_alloc, srtp_aes_icm_openssl_alloc,
(cipher_dealloc_func_t) aes_icm_openssl_dealloc, srtp_aes_icm_openssl_dealloc,
(cipher_init_func_t) aes_icm_openssl_context_init, srtp_aes_icm_openssl_context_init,
(cipher_set_aad_func_t) 0, 0, /* set_aad */
(cipher_encrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_decrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_set_iv_func_t) aes_icm_openssl_set_iv, srtp_aes_icm_openssl_set_iv,
(cipher_get_tag_func_t) 0, 0, /* get_tag */
(char*) aes_icm_192_openssl_description, srtp_aes_icm_192_openssl_description,
(int) 0, /* instance count */ &srtp_aes_icm_192_test_case_0,
(cipher_test_case_t*) &aes_icm_192_test_case_1, SRTP_AES_ICM_192
(debug_module_t*) &mod_aes_icm,
(cipher_type_id_t) AES_192_ICM
}; };
/* /*
* This is the function table for this crypto engine. * This is the function table for this crypto engine.
* note: the encrypt function is identical to the decrypt function * note: the encrypt function is identical to the decrypt function
*/ */
cipher_type_t aes_icm_256 = { const srtp_cipher_type_t srtp_aes_icm_256 = {
(cipher_alloc_func_t) aes_icm_openssl_alloc, srtp_aes_icm_openssl_alloc,
(cipher_dealloc_func_t) aes_icm_openssl_dealloc, srtp_aes_icm_openssl_dealloc,
(cipher_init_func_t) aes_icm_openssl_context_init, srtp_aes_icm_openssl_context_init,
(cipher_set_aad_func_t) 0, 0, /* set_aad */
(cipher_encrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_decrypt_func_t) aes_icm_openssl_encrypt, srtp_aes_icm_openssl_encrypt,
(cipher_set_iv_func_t) aes_icm_openssl_set_iv, srtp_aes_icm_openssl_set_iv,
(cipher_get_tag_func_t) 0, 0, /* get_tag */
(char*) aes_icm_256_openssl_description, srtp_aes_icm_256_openssl_description,
(int) 0, /* instance count */ &srtp_aes_icm_256_test_case_0,
(cipher_test_case_t*) &aes_icm_256_test_case_2, SRTP_AES_ICM_256
(debug_module_t*) &mod_aes_icm,
(cipher_type_id_t) AES_256_ICM
}; };

File diff suppressed because it is too large Load Diff

View File

@ -9,26 +9,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -44,96 +44,95 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "datatypes.h" #include "datatypes.h"
#include "null_cipher.h" #include "null_cipher.h"
#include "err.h" /* for srtp_debug */
#include "alloc.h" #include "alloc.h"
/* the null_cipher uses the cipher debug module */ /* the null_cipher uses the cipher debug module */
extern debug_module_t mod_cipher; extern srtp_debug_module_t srtp_mod_cipher;
err_status_t static srtp_err_status_t srtp_null_cipher_alloc (srtp_cipher_t **c, int key_len, int tlen)
null_cipher_alloc(cipher_t **c, int key_len, int tlen) { {
extern cipher_type_t null_cipher; extern const srtp_cipher_type_t srtp_null_cipher;
uint8_t *pointer;
debug_print(mod_cipher,
"allocating cipher with key length %d", key_len);
/* allocate memory a cipher of type null_cipher */ debug_print(srtp_mod_cipher,
pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t)); "allocating cipher with key length %d", key_len);
if (pointer == NULL)
return err_status_alloc_fail;
/* set pointers */ /* allocate memory a cipher of type null_cipher */
*c = (cipher_t *)pointer; *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
(*c)->algorithm = NULL_CIPHER; if (*c == NULL) {
(*c)->type = &null_cipher; return srtp_err_status_alloc_fail;
(*c)->state = pointer + sizeof(cipher_t); }
memset(*c, 0x0, sizeof(srtp_cipher_t));
/* set key size */ /* set pointers */
(*c)->key_len = key_len; (*c)->algorithm = SRTP_NULL_CIPHER;
(*c)->type = &srtp_null_cipher;
(*c)->state = (void *) 0x1; /* The null cipher does not maintain state */
/* set key size */
(*c)->key_len = key_len;
return srtp_err_status_ok;
/* increment ref_count */
null_cipher.ref_count++;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_cipher_dealloc (srtp_cipher_t *c)
null_cipher_dealloc(cipher_t *c) { {
extern cipher_type_t null_cipher; extern const srtp_cipher_type_t srtp_null_cipher;
/* zeroize entire state*/ /* zeroize entire state*/
octet_string_set_to_zero((uint8_t *)c, octet_string_set_to_zero(c, sizeof(srtp_cipher_t));
sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
/* free memory of type null_cipher */ /* free memory of type null_cipher */
crypto_free(c); srtp_crypto_free(c);
return srtp_err_status_ok;
/* decrement reference count */
null_cipher.ref_count--;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_cipher_init (void *cv, const uint8_t *key)
null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) { {
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
debug_print(mod_cipher, "initializing null cipher", NULL); debug_print(srtp_mod_cipher, "initializing null cipher", NULL);
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_cipher_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
null_cipher_set_iv(null_cipher_ctx_t *c, void *iv) { {
return err_status_ok; /* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_cipher_encrypt (void *cv,
null_cipher_encrypt(null_cipher_ctx_t *c, unsigned char *buf, unsigned int *bytes_to_encr)
unsigned char *buf, unsigned int *bytes_to_encr) { {
return err_status_ok; /* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
return srtp_err_status_ok;
} }
char static const char srtp_null_cipher_description[] = "null cipher";
null_cipher_description[] = "null cipher";
cipher_test_case_t static const srtp_cipher_test_case_t srtp_null_cipher_test_0 = {
null_cipher_test_0 = { 0, /* octets in key */
0, /* octets in key */ NULL, /* key */
NULL, /* key */ 0, /* packet index */
0, /* packet index */ 0, /* octets in plaintext */
0, /* octets in plaintext */ NULL, /* plaintext */
NULL, /* plaintext */ 0, /* octets in plaintext */
0, /* octets in plaintext */ NULL, /* ciphertext */
NULL, /* ciphertext */ 0,
0, NULL,
NULL, 0,
0, NULL /* pointer to next testcase */
NULL /* pointer to next testcase */
}; };
@ -141,19 +140,17 @@ null_cipher_test_0 = {
* note: the decrypt function is idential to the encrypt function * note: the decrypt function is idential to the encrypt function
*/ */
cipher_type_t null_cipher = { const srtp_cipher_type_t srtp_null_cipher = {
(cipher_alloc_func_t) null_cipher_alloc, srtp_null_cipher_alloc,
(cipher_dealloc_func_t) null_cipher_dealloc, srtp_null_cipher_dealloc,
(cipher_init_func_t) null_cipher_init, srtp_null_cipher_init,
(cipher_set_aad_func_t) 0, 0, /* set_aad */
(cipher_encrypt_func_t) null_cipher_encrypt, srtp_null_cipher_encrypt,
(cipher_decrypt_func_t) null_cipher_encrypt, srtp_null_cipher_encrypt,
(cipher_set_iv_func_t) null_cipher_set_iv, srtp_null_cipher_set_iv,
(cipher_get_tag_func_t) 0, 0, /* get_tag */
(char *) null_cipher_description, srtp_null_cipher_description,
(int) 0, &srtp_null_cipher_test_0,
(cipher_test_case_t *) &null_cipher_test_0, SRTP_NULL_CIPHER
(debug_module_t *) NULL,
(cipher_type_id_t) NULL_CIPHER
}; };

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,38 +43,39 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "auth.h" #include "auth.h"
#include "err.h" /* for srtp_debug */
#include "datatypes.h" /* for octet_string */
/* the debug module for authentiation */ /* the debug module for authentiation */
debug_module_t mod_auth = { srtp_debug_module_t srtp_mod_auth = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"auth func" /* printable name for module */ "auth func" /* printable name for module */
}; };
int int srtp_auth_get_key_length (const srtp_auth_t *a)
auth_get_key_length(const auth_t *a) { {
return a->key_len; return a->key_len;
} }
int int srtp_auth_get_tag_length (const srtp_auth_t *a)
auth_get_tag_length(const auth_t *a) { {
return a->out_len; return a->out_len;
} }
int int srtp_auth_get_prefix_length (const srtp_auth_t *a)
auth_get_prefix_length(const auth_t *a) { {
return a->prefix_len; return a->prefix_len;
}
int
auth_type_get_ref_count(const auth_type_t *at) {
return at->ref_count;
} }
/* /*
* auth_type_test() tests an auth function of type ct against * srtp_auth_type_test() tests an auth function of type ct against
* test cases provided in a list test_data of values of key, data, and tag * test cases provided in a list test_data of values of key, data, and tag
* that is known to be good * that is known to be good
*/ */
@ -82,102 +83,108 @@ auth_type_get_ref_count(const auth_type_t *at) {
/* should be big enough for most occasions */ /* should be big enough for most occasions */
#define SELF_TEST_TAG_BUF_OCTETS 32 #define SELF_TEST_TAG_BUF_OCTETS 32
err_status_t srtp_err_status_t
auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) { srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *test_data)
const auth_test_case_t *test_case = test_data; {
auth_t *a; const srtp_auth_test_case_t *test_case = test_data;
err_status_t status; srtp_auth_t *a;
uint8_t tag[SELF_TEST_TAG_BUF_OCTETS]; srtp_err_status_t status;
int i, case_num = 0; uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
int i, case_num = 0;
debug_print(mod_auth, "running self-test for auth function %s", debug_print(srtp_mod_auth, "running self-test for auth function %s",
at->description); at->description);
/*
* check to make sure that we have at least one test case, and
* return an error if we don't - we need to be paranoid here
*/
if (test_case == NULL)
return err_status_cant_check;
/* loop over all test cases */ /*
while (test_case != NULL) { * check to make sure that we have at least one test case, and
* return an error if we don't - we need to be paranoid here
/* check test case parameters */ */
if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) if (test_case == NULL) {
return err_status_bad_param; return srtp_err_status_cant_check;
/* allocate auth */
status = auth_type_alloc(at, &a, test_case->key_length_octets,
test_case->tag_length_octets);
if (status)
return status;
/* initialize auth */
status = auth_init(a, test_case->key);
if (status) {
auth_dealloc(a);
return status;
} }
/* zeroize tag then compute */ /* loop over all test cases */
octet_string_set_to_zero(tag, test_case->tag_length_octets); while (test_case != NULL) {
status = auth_compute(a, test_case->data,
test_case->data_length_octets, tag);
if (status) {
auth_dealloc(a);
return status;
}
debug_print(mod_auth, "key: %s",
octet_string_hex_string(test_case->key,
test_case->key_length_octets));
debug_print(mod_auth, "data: %s",
octet_string_hex_string(test_case->data,
test_case->data_length_octets));
debug_print(mod_auth, "tag computed: %s",
octet_string_hex_string(tag, test_case->tag_length_octets));
debug_print(mod_auth, "tag expected: %s",
octet_string_hex_string(test_case->tag,
test_case->tag_length_octets));
/* check the result */ /* check test case parameters */
status = err_status_ok; if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) {
for (i=0; i < test_case->tag_length_octets; i++) return srtp_err_status_bad_param;
if (tag[i] != test_case->tag[i]) { }
status = err_status_algo_fail;
debug_print(mod_auth, "test case %d failed", case_num); /* allocate auth */
debug_print(mod_auth, " (mismatch at octet %d)", i); status = srtp_auth_type_alloc(at, &a, test_case->key_length_octets,
} test_case->tag_length_octets);
if (status) { if (status) {
auth_dealloc(a); return status;
return err_status_algo_fail; }
/* initialize auth */
status = srtp_auth_init(a, test_case->key);
if (status) {
srtp_auth_dealloc(a);
return status;
}
/* 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);
if (status) {
srtp_auth_dealloc(a);
return status;
}
debug_print(srtp_mod_auth, "key: %s",
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));
debug_print(srtp_mod_auth, "tag expected: %s",
srtp_octet_string_hex_string(test_case->tag,
test_case->tag_length_octets));
/* check the result */
status = srtp_err_status_ok;
for (i = 0; i < test_case->tag_length_octets; i++) {
if (tag[i] != test_case->tag[i]) {
status = srtp_err_status_algo_fail;
debug_print(srtp_mod_auth, "test case %d failed", case_num);
debug_print(srtp_mod_auth, " (mismatch at octet %d)", i);
}
}
if (status) {
srtp_auth_dealloc(a);
return srtp_err_status_algo_fail;
}
/* deallocate the auth function */
status = srtp_auth_dealloc(a);
if (status) {
return status;
}
/*
* the auth function passed the test case, so move on to the next test
* case in the list; if NULL, we'll quit and return an OK
*/
test_case = test_case->next_test_case;
++case_num;
} }
/* deallocate the auth function */ return srtp_err_status_ok;
status = auth_dealloc(a);
if (status)
return status;
/*
* the auth function passed the test case, so move on to the next test
* case in the list; if NULL, we'll quit and return an OK
*/
test_case = test_case->next_test_case;
++case_num;
}
return err_status_ok;
} }
/* /*
* auth_type_self_test(at) performs auth_type_test on at's internal * auth_type_self_test(at) performs srtp_auth_type_test on at's internal
* list of test data. * list of test data.
*/ */
err_status_t srtp_err_status_t srtp_auth_type_self_test (const srtp_auth_type_t *at)
auth_type_self_test(const auth_type_t *at) { {
return auth_type_test(at, at->test_data); return srtp_auth_type_test(at, at->test_data);
} }

View File

@ -1,32 +1,32 @@
/* /*
* hmac.c * hmac.c
* *
* implementation of hmac auth_type_t * implementation of hmac srtp_auth_type_t
* *
* David A. McGrew * David A. McGrew
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright(c) 2001-2006 Cisco Systems, Inc. * Copyright(c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -42,227 +42,225 @@
* *
*/ */
#include "hmac.h" #ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "hmac.h"
#include "alloc.h" #include "alloc.h"
/* the debug module for authentiation */ /* the debug module for authentiation */
debug_module_t mod_hmac = { srtp_debug_module_t srtp_mod_hmac = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"hmac sha-1" /* printable name for module */ "hmac sha-1" /* printable name for module */
}; };
err_status_t static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
hmac_alloc(auth_t **a, int key_len, int out_len) { {
extern auth_type_t hmac; extern const srtp_auth_type_t srtp_hmac;
uint8_t *pointer; uint8_t *pointer;
debug_print(mod_hmac, "allocating auth func with key length %d", key_len); debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
debug_print(mod_hmac, " tag length %d", out_len); debug_print(srtp_mod_hmac, " tag length %d", out_len);
/*
* check key length - note that we don't support keys larger
* than 20 bytes yet
*/
if (key_len > 20)
return err_status_bad_param;
/* check output length - should be less than 20 bytes */
if (out_len > 20)
return err_status_bad_param;
/* allocate memory for auth and hmac_ctx_t structures */
pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
if (pointer == NULL)
return err_status_alloc_fail;
/* set pointers */
*a = (auth_t *)pointer;
(*a)->type = &hmac;
(*a)->state = pointer + sizeof(auth_t);
(*a)->out_len = out_len;
(*a)->key_len = key_len;
(*a)->prefix_len = 0;
/* increment global count of all hmac uses */
hmac.ref_count++;
return err_status_ok;
}
err_status_t
hmac_dealloc(auth_t *a) {
extern auth_type_t hmac;
/* zeroize entire state*/
octet_string_set_to_zero((uint8_t *)a,
sizeof(hmac_ctx_t) + sizeof(auth_t));
/* free memory */
crypto_free(a);
/* decrement global count of all hmac uses */
hmac.ref_count--;
return err_status_ok;
}
err_status_t
hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) {
int i;
uint8_t ipad[64];
/* /*
* check key length - note that we don't support keys larger * check key length - note that we don't support keys larger
* than 20 bytes yet * than 20 bytes yet
*/ */
if (key_len > 20) if (key_len > 20) {
return err_status_bad_param; return srtp_err_status_bad_param;
}
/*
* set values of ipad and opad by exoring the key into the
* appropriate constant values
*/
for (i=0; i < key_len; i++) {
ipad[i] = key[i] ^ 0x36;
state->opad[i] = key[i] ^ 0x5c;
}
/* set the rest of ipad, opad to constant values */
for ( ; i < 64; i++) {
ipad[i] = 0x36;
((uint8_t *)state->opad)[i] = 0x5c;
}
debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64)); /* check output length - should be less than 20 bytes */
if (out_len > 20) {
/* initialize sha1 context */ return srtp_err_status_bad_param;
sha1_init(&state->init_ctx); }
/* hash ipad ^ key */ /* allocate memory for auth and srtp_hmac_ctx_t structures */
sha1_update(&state->init_ctx, ipad, 64); pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); if (pointer == NULL) {
return srtp_err_status_alloc_fail;
}
return err_status_ok; /* set pointers */
*a = (srtp_auth_t*)pointer;
(*a)->type = &srtp_hmac;
(*a)->state = pointer + sizeof(srtp_auth_t);
(*a)->out_len = out_len;
(*a)->key_len = key_len;
(*a)->prefix_len = 0;
return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
hmac_start(hmac_ctx_t *state) { {
/* zeroize entire state*/
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); octet_string_set_to_zero(a, sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
return err_status_ok; /* free memory */
srtp_crypto_free(a);
return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) { {
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
int i;
uint8_t ipad[64];
debug_print(mod_hmac, "input: %s", /*
octet_string_hex_string(message, msg_octets)); * check key length - note that we don't support keys larger
* than 20 bytes yet
/* hash message into sha1 context */ */
sha1_update(&state->ctx, message, msg_octets); if (key_len > 20) {
return srtp_err_status_bad_param;
}
return err_status_ok; /*
* set values of ipad and opad by exoring the key into the
* appropriate constant values
*/
for (i = 0; i < key_len; i++) {
ipad[i] = key[i] ^ 0x36;
state->opad[i] = key[i] ^ 0x5c;
}
/* set the rest of ipad, opad to constant values */
for (; i < 64; i++) {
ipad[i] = 0x36;
((uint8_t*)state->opad)[i] = 0x5c;
}
debug_print(srtp_mod_hmac, "ipad: %s", srtp_octet_string_hex_string(ipad, 64));
/* initialize sha1 context */
srtp_sha1_init(&state->init_ctx);
/* hash ipad ^ key */
srtp_sha1_update(&state->init_ctx, ipad, 64);
memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_start (void *statev)
hmac_compute(hmac_ctx_t *state, const void *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];
uint32_t H[5];
int i;
/* check tag length, return error if we can't provide the value expected */ memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
if (tag_len > 20)
return err_status_bad_param;
/* hash message, copy output into H */
hmac_update(state, (const uint8_t*)message, msg_octets);
sha1_final(&state->ctx, H);
/* return srtp_err_status_ok;
* note that we don't need to debug_print() the input, since the }
* function hmac_update() already did that for us
*/
debug_print(mod_hmac, "intermediate state: %s",
octet_string_hex_string((uint8_t *)H, 20));
/* re-initialize hash context */ static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
sha1_init(&state->ctx); {
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
/* hash opad ^ key */
sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
/* hash the result of the inner hash */ debug_print(srtp_mod_hmac, "input: %s",
sha1_update(&state->ctx, (uint8_t *)H, 20); srtp_octet_string_hex_string(message, msg_octets));
/* the result is returned in the array hash_value[] */
sha1_final(&state->ctx, hash_value);
/* copy hash_value to *result */ /* hash message into sha1 context */
for (i=0; i < tag_len; i++) srtp_sha1_update(&state->ctx, message, msg_octets);
result[i] = ((uint8_t *)hash_value)[i];
debug_print(mod_hmac, "output: %s", return srtp_err_status_ok;
octet_string_hex_string((uint8_t *)hash_value, tag_len)); }
return 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)
{
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
uint32_t hash_value[5];
uint32_t H[5];
int i;
/* check tag length, return error if we can't provide the value expected */
if (tag_len > 20) {
return srtp_err_status_bad_param;
}
/* hash message, copy output into H */
srtp_hmac_update(state, message, msg_octets);
srtp_sha1_final(&state->ctx, H);
/*
* note that we don't need to debug_print() the input, since the
* function hmac_update() already did that for us
*/
debug_print(srtp_mod_hmac, "intermediate state: %s",
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);
/* hash the result of the inner hash */
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];
}
debug_print(srtp_mod_hmac, "output: %s",
srtp_octet_string_hex_string((uint8_t*)hash_value, tag_len));
return srtp_err_status_ok;
} }
/* begin test case 0 */ /* begin test case 0 */
uint8_t static const uint8_t srtp_hmac_test_case_0_key[20] = {
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, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
0x0b, 0x0b, 0x0b, 0x0b
}; };
uint8_t static const uint8_t srtp_hmac_test_case_0_data[8] = {
hmac_test_case_0_data[8] = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
}; };
uint8_t static const uint8_t srtp_hmac_test_case_0_tag[20] = {
hmac_test_case_0_tag[20] = { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1, 0x46, 0xbe, 0x00
0xf1, 0x46, 0xbe, 0x00
}; };
auth_test_case_t static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
hmac_test_case_0 = { 20, /* octets in key */
20, /* octets in key */ srtp_hmac_test_case_0_key, /* key */
hmac_test_case_0_key, /* key */ 8, /* octets in data */
8, /* octets in data */ srtp_hmac_test_case_0_data, /* data */
hmac_test_case_0_data, /* data */ 20, /* octets in tag */
20, /* octets in tag */ srtp_hmac_test_case_0_tag, /* tag */
hmac_test_case_0_tag, /* tag */ NULL /* pointer to next testcase */
NULL /* pointer to next testcase */
}; };
/* end test case 0 */ /* end test case 0 */
char hmac_description[] = "hmac sha-1 authentication function"; static const char srtp_hmac_description[] = "hmac sha-1 authentication function";
/* /*
* auth_type_t hmac is the hmac metaobject * srtp_auth_type_t hmac is the hmac metaobject
*/ */
auth_type_t const srtp_auth_type_t srtp_hmac = {
hmac = { srtp_hmac_alloc,
(auth_alloc_func) hmac_alloc, srtp_hmac_dealloc,
(auth_dealloc_func) hmac_dealloc, srtp_hmac_init,
(auth_init_func) hmac_init, srtp_hmac_compute,
(auth_compute_func) hmac_compute, srtp_hmac_update,
(auth_update_func) hmac_update, srtp_hmac_start,
(auth_start_func) hmac_start, srtp_hmac_description,
(char *) hmac_description, &srtp_hmac_test_case_0,
(int) 0, /* instance count */ SRTP_HMAC_SHA1
(auth_test_case_t *) &hmac_test_case_0,
(debug_module_t *) &mod_hmac,
(auth_type_id_t) HMAC_SHA1
}; };

View File

@ -1,14 +1,14 @@
/* /*
* hmac_ossl.c * hmac_ossl.c
* *
* Implementation of hmac auth_type_t that leverages OpenSSL * Implementation of hmac srtp_auth_type_t that leverages OpenSSL
* *
* John A. Foley * John A. Foley
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright(c) 2013, Cisco Systems, Inc. * Copyright(c) 2013-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,256 +42,217 @@
* *
*/ */
#include "hmac.h" #ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "auth.h"
#include "alloc.h" #include "alloc.h"
#include "err.h" /* for srtp_debug */
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/hmac.h>
#define SHA1_DIGEST_SIZE 20
/* the debug module for authentiation */ /* the debug module for authentiation */
debug_module_t mod_hmac = { srtp_debug_module_t srtp_mod_hmac = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"hmac sha-1 openssl" /* printable name for module */ "hmac sha-1 openssl" /* printable name for module */
}; };
err_status_t static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
hmac_alloc (auth_t **a, int key_len, int out_len)
{ {
extern auth_type_t hmac; extern const srtp_auth_type_t srtp_hmac;
uint8_t *pointer;
hmac_ctx_t *new_hmac_ctx;
debug_print(mod_hmac, "allocating auth func with key length %d", key_len); debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
debug_print(mod_hmac, " tag length %d", out_len); debug_print(srtp_mod_hmac, " tag length %d", out_len);
/*
* check key length - note that we don't support keys larger
* than 20 bytes yet
*/
if (key_len > 20) {
return err_status_bad_param;
}
/* check output length - should be less than 20 bytes */ /* check output length - should be less than 20 bytes */
if (out_len > 20) { if (out_len > SHA1_DIGEST_SIZE) {
return err_status_bad_param; return srtp_err_status_bad_param;
} }
/* allocate memory for auth and hmac_ctx_t structures */ /* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated
pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t)); using HMAC_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */
if (pointer == NULL) { #if OPENSSL_VERSION_NUMBER < 0x10100000L
return err_status_alloc_fail; {
/* allocate memory for auth and HMAC_CTX structures */
uint8_t* pointer;
HMAC_CTX *new_hmac_ctx;
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)->state = pointer + sizeof(srtp_auth_t);
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));
if (*a == NULL) {
return srtp_err_status_alloc_fail;
}
(*a)->state = HMAC_CTX_new();
if ((*a)->state == NULL) {
srtp_crypto_free(*a);
*a = NULL;
return srtp_err_status_alloc_fail;
}
#endif
/* set pointers */ /* set pointers */
*a = (auth_t*)pointer; (*a)->type = &srtp_hmac;
(*a)->type = &hmac;
(*a)->state = pointer + sizeof(auth_t);
(*a)->out_len = out_len; (*a)->out_len = out_len;
(*a)->key_len = key_len; (*a)->key_len = key_len;
(*a)->prefix_len = 0; (*a)->prefix_len = 0;
new_hmac_ctx = (hmac_ctx_t*)((*a)->state);
memset(new_hmac_ctx, 0, sizeof(hmac_ctx_t));
/* increment global count of all hmac uses */ return srtp_err_status_ok;
hmac.ref_count++;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
hmac_dealloc (auth_t *a)
{ {
extern auth_type_t hmac; HMAC_CTX *hmac_ctx;
hmac_ctx_t *hmac_ctx;
hmac_ctx = (hmac_ctx_t*)a->state; hmac_ctx = (HMAC_CTX*)a->state;
if (hmac_ctx->ctx_initialized) {
EVP_MD_CTX_cleanup(&hmac_ctx->ctx); #if OPENSSL_VERSION_NUMBER < 0x10100000L
} HMAC_CTX_cleanup(hmac_ctx);
if (hmac_ctx->init_ctx_initialized) {
EVP_MD_CTX_cleanup(&hmac_ctx->init_ctx);
}
/* zeroize entire state*/ /* zeroize entire state*/
octet_string_set_to_zero((uint8_t*)a, octet_string_set_to_zero(a, sizeof(HMAC_CTX) + sizeof(srtp_auth_t));
sizeof(hmac_ctx_t) + sizeof(auth_t));
#else
HMAC_CTX_free(hmac_ctx);
/* zeroize entire state*/
octet_string_set_to_zero(a, sizeof(srtp_auth_t));
#endif
/* free memory */ /* free memory */
crypto_free(a); srtp_crypto_free(a);
/* decrement global count of all hmac uses */ return srtp_err_status_ok;
hmac.ref_count--;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_start (void *statev)
hmac_init (hmac_ctx_t *state, const uint8_t *key, int key_len)
{ {
int i; HMAC_CTX *state = (HMAC_CTX *)statev;
uint8_t ipad[64];
/* if (HMAC_Init_ex(state, NULL, 0, NULL, NULL) == 0)
* check key length - note that we don't support keys larger return srtp_err_status_auth_fail;
* than 20 bytes yet
*/
if (key_len > 20) {
return err_status_bad_param;
}
/* return srtp_err_status_ok;
* set values of ipad and opad by exoring the key into the
* appropriate constant values
*/
for (i = 0; i < key_len; i++) {
ipad[i] = key[i] ^ 0x36;
state->opad[i] = key[i] ^ 0x5c;
}
/* set the rest of ipad, opad to constant values */
for (; i < 64; i++) {
ipad[i] = 0x36;
((uint8_t*)state->opad)[i] = 0x5c;
}
debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
/* initialize sha1 context */
sha1_init(&state->init_ctx);
state->init_ctx_initialized = 1;
/* hash ipad ^ key */
sha1_update(&state->init_ctx, ipad, 64);
return (hmac_start(state));
} }
err_status_t static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
hmac_start (hmac_ctx_t *state)
{ {
if (state->ctx_initialized) { HMAC_CTX *state = (HMAC_CTX *)statev;
EVP_MD_CTX_cleanup(&state->ctx);
} if (HMAC_Init_ex(state, key, key_len, EVP_sha1(), NULL) == 0)
if (!EVP_MD_CTX_copy(&state->ctx, &state->init_ctx)) { return srtp_err_status_auth_fail;
return err_status_auth_fail;
} else { return srtp_err_status_ok;
state->ctx_initialized = 1;
return err_status_ok;
}
} }
err_status_t static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
hmac_update (hmac_ctx_t *state, const uint8_t *message, int msg_octets)
{ {
HMAC_CTX *state = (HMAC_CTX *)statev;
debug_print(mod_hmac, "input: %s", debug_print(srtp_mod_hmac, "input: %s",
octet_string_hex_string(message, msg_octets)); srtp_octet_string_hex_string(message, msg_octets));
/* hash message into sha1 context */ if (HMAC_Update(state, message, msg_octets) == 0)
sha1_update(&state->ctx, message, msg_octets); return srtp_err_status_auth_fail;
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message,
hmac_compute (hmac_ctx_t *state, const void *message,
int msg_octets, int tag_len, uint8_t *result) int msg_octets, int tag_len, uint8_t *result)
{ {
uint32_t hash_value[5]; HMAC_CTX *state = (HMAC_CTX *)statev;
uint32_t H[5]; uint8_t hash_value[SHA1_DIGEST_SIZE];
int i; int i;
unsigned int len;
/* check tag length, return error if we can't provide the value expected */ /* check tag length, return error if we can't provide the value expected */
if (tag_len > 20) { if (tag_len > SHA1_DIGEST_SIZE) {
return err_status_bad_param; return srtp_err_status_bad_param;
} }
/* hash message, copy output into H */ /* hash message, copy output into H */
sha1_update(&state->ctx, message, msg_octets); if (HMAC_Update(state, message, msg_octets) == 0)
sha1_final(&state->ctx, H); return srtp_err_status_auth_fail;
/* if (HMAC_Final(state, hash_value, &len) == 0)
* note that we don't need to debug_print() the input, since the return srtp_err_status_auth_fail;
* function hmac_update() already did that for us
*/
debug_print(mod_hmac, "intermediate state: %s",
octet_string_hex_string((uint8_t*)H, 20));
/* re-initialize hash context */ if (len < tag_len)
sha1_init(&state->ctx); return srtp_err_status_auth_fail;
/* hash opad ^ key */
sha1_update(&state->ctx, (uint8_t*)state->opad, 64);
/* hash the result of the inner hash */
sha1_update(&state->ctx, (uint8_t*)H, 20);
/* the result is returned in the array hash_value[] */
sha1_final(&state->ctx, hash_value);
/* copy hash_value to *result */ /* copy hash_value to *result */
for (i = 0; i < tag_len; i++) { for (i = 0; i < tag_len; i++) {
result[i] = ((uint8_t*)hash_value)[i]; result[i] = hash_value[i];
} }
debug_print(mod_hmac, "output: %s", debug_print(srtp_mod_hmac, "output: %s",
octet_string_hex_string((uint8_t*)hash_value, tag_len)); srtp_octet_string_hex_string(hash_value, tag_len));
return err_status_ok; return srtp_err_status_ok;
} }
/* begin test case 0 */ /* begin test case 0 */
uint8_t static const uint8_t srtp_hmac_test_case_0_key[SHA1_DIGEST_SIZE] = {
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, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b 0x0b, 0x0b, 0x0b, 0x0b
}; };
uint8_t static const uint8_t srtp_hmac_test_case_0_data[8] = {
hmac_test_case_0_data[8] = {
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */ 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
}; };
uint8_t static const uint8_t srtp_hmac_test_case_0_tag[SHA1_DIGEST_SIZE] = {
hmac_test_case_0_tag[20] = {
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
0xf1, 0x46, 0xbe, 0x00 0xf1, 0x46, 0xbe, 0x00
}; };
auth_test_case_t static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
hmac_test_case_0 = { sizeof(srtp_hmac_test_case_0_key), /* octets in key */
20, /* octets in key */ srtp_hmac_test_case_0_key, /* key */
hmac_test_case_0_key, /* key */ sizeof(srtp_hmac_test_case_0_data), /* octets in data */
8, /* octets in data */ srtp_hmac_test_case_0_data, /* data */
hmac_test_case_0_data, /* data */ sizeof(srtp_hmac_test_case_0_tag), /* octets in tag */
20, /* octets in tag */ srtp_hmac_test_case_0_tag, /* tag */
hmac_test_case_0_tag, /* tag */ NULL /* pointer to next testcase */
NULL /* pointer to next testcase */
}; };
/* end test case 0 */ /* end test case 0 */
char hmac_description[] = "hmac sha-1 authentication function"; static const char srtp_hmac_description[] = "hmac sha-1 authentication function";
/* /*
* auth_type_t hmac is the hmac metaobject * srtp_auth_type_t hmac is the hmac metaobject
*/ */
auth_type_t const srtp_auth_type_t srtp_hmac = {
hmac = { srtp_hmac_alloc,
(auth_alloc_func) hmac_alloc, srtp_hmac_dealloc,
(auth_dealloc_func) hmac_dealloc, srtp_hmac_init,
(auth_init_func) hmac_init, srtp_hmac_compute,
(auth_compute_func) hmac_compute, srtp_hmac_update,
(auth_update_func) hmac_update, srtp_hmac_start,
(auth_start_func) hmac_start, srtp_hmac_description,
(char*) hmac_description, &srtp_hmac_test_case_0,
(int) 0, /* instance count */ SRTP_HMAC_SHA1
(auth_test_case_t*) &hmac_test_case_0,
(debug_module_t*) &mod_hmac,
(auth_type_id_t) HMAC_SHA1
}; };

View File

@ -9,26 +9,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -44,119 +44,117 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "null_auth.h" #include "null_auth.h"
#include "err.h" /* for srtp_debug */
#include "alloc.h" #include "alloc.h"
/* null_auth uses the auth debug module */ /* null_auth uses the auth debug module */
extern debug_module_t mod_auth; extern srtp_debug_module_t srtp_mod_auth;
err_status_t static srtp_err_status_t srtp_null_auth_alloc (srtp_auth_t **a, int key_len, int out_len)
null_auth_alloc(auth_t **a, int key_len, int out_len) { {
extern auth_type_t null_auth; extern const srtp_auth_type_t srtp_null_auth;
uint8_t *pointer; uint8_t *pointer;
debug_print(mod_auth, "allocating auth func with key length %d", key_len); debug_print(srtp_mod_auth, "allocating auth func with key length %d", key_len);
debug_print(mod_auth, " tag length %d", out_len); debug_print(srtp_mod_auth, " tag length %d", out_len);
/* allocate memory for auth and null_auth_ctx_t structures */ /* allocate memory for auth and srtp_null_auth_ctx_t structures */
pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t)); pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
if (pointer == NULL) if (pointer == NULL) {
return err_status_alloc_fail; return srtp_err_status_alloc_fail;
}
/* set pointers */ /* set pointers */
*a = (auth_t *)pointer; *a = (srtp_auth_t*)pointer;
(*a)->type = &null_auth; (*a)->type = &srtp_null_auth;
(*a)->state = pointer + sizeof (auth_t); (*a)->state = pointer + sizeof(srtp_auth_t);
(*a)->out_len = out_len; (*a)->out_len = out_len;
(*a)->prefix_len = out_len; (*a)->prefix_len = out_len;
(*a)->key_len = key_len; (*a)->key_len = key_len;
/* increment global count of all null_auth uses */ return srtp_err_status_ok;
null_auth.ref_count++;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_auth_dealloc (srtp_auth_t *a)
null_auth_dealloc(auth_t *a) { {
extern auth_type_t null_auth; extern const srtp_auth_type_t srtp_null_auth;
/* zeroize entire state*/
octet_string_set_to_zero((uint8_t *)a,
sizeof(null_auth_ctx_t) + sizeof(auth_t));
/* free memory */ /* zeroize entire state*/
crypto_free(a); octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
/* decrement global count of all null_auth uses */
null_auth.ref_count--;
return err_status_ok; /* free memory */
srtp_crypto_free(a);
return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_auth_init (void *statev, const uint8_t *key, int key_len)
null_auth_init(null_auth_ctx_t *state, 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 */
/* accept any length of key, and do nothing */ return srtp_err_status_ok;
return err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_auth_compute (void *statev, const uint8_t *message,
null_auth_compute(null_auth_ctx_t *state, uint8_t *message, int msg_octets, int tag_len, uint8_t *result)
int msg_octets, int tag_len, uint8_t *result) { {
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_auth_update (void *statev, const uint8_t *message,
null_auth_update(null_auth_ctx_t *state, uint8_t *message, int msg_octets)
int msg_octets) { {
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t static srtp_err_status_t srtp_null_auth_start (void *statev)
null_auth_start(null_auth_ctx_t *state) { {
return err_status_ok; /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
return srtp_err_status_ok;
} }
/* /*
* auth_type_t - defines description, test case, and null_auth * srtp_auth_type_t - defines description, test case, and null_auth
* metaobject * metaobject
*/ */
/* begin test case 0 */ /* begin test case 0 */
auth_test_case_t static const srtp_auth_test_case_t srtp_null_auth_test_case_0 = {
null_auth_test_case_0 = { 0, /* octets in key */
0, /* octets in key */ NULL, /* key */
NULL, /* key */ 0, /* octets in data */
0, /* octets in data */ NULL, /* data */
NULL, /* data */ 0, /* octets in tag */
0, /* octets in tag */ NULL, /* tag */
NULL, /* tag */ NULL /* pointer to next testcase */
NULL /* pointer to next testcase */
}; };
/* end test case 0 */ /* end test case 0 */
char null_auth_description[] = "null authentication function"; static const char srtp_null_auth_description[] = "null authentication function";
auth_type_t const srtp_auth_type_t srtp_null_auth = {
null_auth = { srtp_null_auth_alloc,
(auth_alloc_func) null_auth_alloc, srtp_null_auth_dealloc,
(auth_dealloc_func) null_auth_dealloc, srtp_null_auth_init,
(auth_init_func) null_auth_init, srtp_null_auth_compute,
(auth_compute_func) null_auth_compute, srtp_null_auth_update,
(auth_update_func) null_auth_update, srtp_null_auth_start,
(auth_start_func) null_auth_start, srtp_null_auth_description,
(char *) null_auth_description, &srtp_null_auth_test_case_0,
(int) 0, /* instance count */ SRTP_NULL_AUTH
(auth_test_case_t *) &null_auth_test_case_0,
(debug_module_t *) NULL,
(auth_type_id_t) NULL_AUTH
}; };

View File

@ -9,26 +9,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -44,12 +44,15 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "sha1.h" #include "sha1.h"
debug_module_t mod_sha1 = { srtp_debug_module_t srtp_mod_sha1 = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"sha-1" /* printable module name */ "sha-1" /* printable module name */
}; };
/* SN == Rotate left N bits */ /* SN == Rotate left N bits */
@ -57,14 +60,14 @@ debug_module_t mod_sha1 = {
#define S5(X) ((X << 5) | (X >> 27)) #define S5(X) ((X << 5) | (X >> 27))
#define S30(X) ((X << 30) | (X >> 2)) #define S30(X) ((X << 30) | (X >> 2))
#define f0(B,C,D) ((B & C) | (~B & D)) #define f0(B, C, D) ((B & C) | (~B & D))
#define f1(B,C,D) (B ^ C ^ D) #define f1(B, C, D) (B ^ C ^ D)
#define f2(B,C,D) ((B & C) | (B & D) | (C & D)) #define f2(B, C, D) ((B & C) | (B & D) | (C & D))
#define f3(B,C,D) (B ^ C ^ D) #define f3(B, C, D) (B ^ C ^ D)
/* /*
* nota bene: the variable K0 appears in the curses library, so we * nota bene: the variable K0 appears in the curses library, so we
* give longer names to these variables to avoid spurious warnings * give longer names to these variables to avoid spurious warnings
* on systems that uses curses * on systems that uses curses
*/ */
@ -73,18 +76,18 @@ uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */ uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */ uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
void void srtp_sha1 (const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) { {
sha1_ctx_t ctx; srtp_sha1_ctx_t ctx;
sha1_init(&ctx); srtp_sha1_init(&ctx);
sha1_update(&ctx, msg, octets_in_msg); srtp_sha1_update(&ctx, msg, octets_in_msg);
sha1_final(&ctx, hash_value); srtp_sha1_final(&ctx, hash_value);
} }
/* /*
* sha1_core(M, H) computes the core compression function, where M is * srtp_sha1_core(M, H) computes the core compression function, where M is
* the next part of the message (in network byte order) and H is the * the next part of the message (in network byte order) and H is the
* intermediate state { H0, H1, ...} (in host byte order) * intermediate state { H0, H1, ...} (in host byte order)
* *
@ -95,310 +98,316 @@ sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) {
* (crypto/cipher/seal.c) * (crypto/cipher/seal.c)
*/ */
void void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
sha1_core(const uint32_t M[16], uint32_t hash_value[5]) { {
uint32_t H0; uint32_t H0;
uint32_t H1; uint32_t H1;
uint32_t H2; uint32_t H2;
uint32_t H3; uint32_t H3;
uint32_t H4; uint32_t H4;
uint32_t W[80]; uint32_t W[80];
uint32_t A, B, C, D, E, TEMP; uint32_t A, B, C, D, E, TEMP;
int t; int t;
/* copy hash_value into H0, H1, H2, H3, H4 */ /* copy hash_value into H0, H1, H2, H3, H4 */
H0 = hash_value[0]; H0 = hash_value[0];
H1 = hash_value[1]; H1 = hash_value[1];
H2 = hash_value[2]; H2 = hash_value[2];
H3 = hash_value[3]; H3 = hash_value[3];
H4 = hash_value[4]; H4 = hash_value[4];
/* copy/xor message into array */ /* copy/xor message into array */
W[0] = be32_to_cpu(M[0]); W[0] = be32_to_cpu(M[0]);
W[1] = be32_to_cpu(M[1]); W[1] = be32_to_cpu(M[1]);
W[2] = be32_to_cpu(M[2]); W[2] = be32_to_cpu(M[2]);
W[3] = be32_to_cpu(M[3]); W[3] = be32_to_cpu(M[3]);
W[4] = be32_to_cpu(M[4]); W[4] = be32_to_cpu(M[4]);
W[5] = be32_to_cpu(M[5]); W[5] = be32_to_cpu(M[5]);
W[6] = be32_to_cpu(M[6]); W[6] = be32_to_cpu(M[6]);
W[7] = be32_to_cpu(M[7]); W[7] = be32_to_cpu(M[7]);
W[8] = be32_to_cpu(M[8]); W[8] = be32_to_cpu(M[8]);
W[9] = be32_to_cpu(M[9]); W[9] = be32_to_cpu(M[9]);
W[10] = be32_to_cpu(M[10]); W[10] = be32_to_cpu(M[10]);
W[11] = be32_to_cpu(M[11]); W[11] = be32_to_cpu(M[11]);
W[12] = be32_to_cpu(M[12]); W[12] = be32_to_cpu(M[12]);
W[13] = be32_to_cpu(M[13]); W[13] = be32_to_cpu(M[13]);
W[14] = be32_to_cpu(M[14]); W[14] = be32_to_cpu(M[14]);
W[15] = be32_to_cpu(M[15]); W[15] = be32_to_cpu(M[15]);
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = 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[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[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[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[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[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[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[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[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[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[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[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[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[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[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[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);
/* process the remainder of the array */ /* process the remainder of the array */
for (t=32; t < 80; t++) { for (t = 32; t < 80; t++) {
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]; TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP); W[t] = S1(TEMP);
}
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;
}
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;
}
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;
}
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;
}
hash_value[0] = H0 + A;
hash_value[1] = H1 + B;
hash_value[2] = H2 + C;
hash_value[3] = H3 + D;
hash_value[4] = H4 + E;
return;
}
void
sha1_init(sha1_ctx_t *ctx) {
/* initialize state vector */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
ctx->H[2] = 0x98badcfe;
ctx->H[3] = 0x10325476;
ctx->H[4] = 0xc3d2e1f0;
/* indicate that message buffer is empty */
ctx->octets_in_buffer = 0;
/* reset message bit-count to zero */
ctx->num_bits_in_msg = 0;
}
void
sha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) {
int i;
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
*/
octets_in_msg -= (64 - ctx->octets_in_buffer);
for (i=ctx->octets_in_buffer; i < 64; i++)
buf[i] = *msg++;
ctx->octets_in_buffer = 0;
/* process a whole block */
debug_print(mod_sha1, "(update) running sha1_core()", NULL);
sha1_core(ctx->M, ctx->H);
} else {
debug_print(mod_sha1, "(update) not running sha1_core()", NULL);
for (i=ctx->octets_in_buffer;
i < (ctx->octets_in_buffer + octets_in_msg); i++)
buf[i] = *msg++;
ctx->octets_in_buffer += octets_in_msg;
octets_in_msg = 0;
} }
} 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;
}
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;
}
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;
}
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;
}
hash_value[0] = H0 + A;
hash_value[1] = H1 + B;
hash_value[2] = H2 + C;
hash_value[3] = H3 + D;
hash_value[4] = H4 + E;
return;
}
void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
{
/* initialize state vector */
ctx->H[0] = 0x67452301;
ctx->H[1] = 0xefcdab89;
ctx->H[2] = 0x98badcfe;
ctx->H[3] = 0x10325476;
ctx->H[4] = 0xc3d2e1f0;
/* indicate that message buffer is empty */
ctx->octets_in_buffer = 0;
/* 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)
{
int i;
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
*/
octets_in_msg -= (64 - ctx->octets_in_buffer);
for (i = ctx->octets_in_buffer; i < 64; i++) {
buf[i] = *msg++;
}
ctx->octets_in_buffer = 0;
/* process a whole block */
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);
for (i = ctx->octets_in_buffer;
i < (ctx->octets_in_buffer + octets_in_msg); i++) {
buf[i] = *msg++;
}
ctx->octets_in_buffer += octets_in_msg;
octets_in_msg = 0;
}
}
} }
/* /*
* sha1_final(ctx, output) computes the result for ctx and copies it * srtp_sha1_final(ctx, output) computes the result for ctx and copies it
* into the twenty octets located at *output * into the twenty octets located at *output
*/ */
void void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
sha1_final(sha1_ctx_t *ctx, uint32_t *output) { {
uint32_t A, B, C, D, E, TEMP; uint32_t A, B, C, D, E, TEMP;
uint32_t W[80]; uint32_t W[80];
int i, t; int i, t;
/* /*
* process the remaining octets_in_buffer, padding and terminating as * process the remaining octets_in_buffer, padding and terminating as
* necessary * necessary
*/
{
int tail = ctx->octets_in_buffer % 4;
/* copy/xor message into array */
for (i=0; i < (ctx->octets_in_buffer+3)/4; i++)
W[i] = be32_to_cpu(ctx->M[i]);
/* set the high bit of the octet immediately following the message */
switch (tail) {
case (3):
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffffff00) | 0x80;
W[i] = 0x0;
break;
case (2):
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffff0000) | 0x8000;
W[i] = 0x0;
break;
case (1):
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xff000000) | 0x800000;
W[i] = 0x0;
break;
case (0):
W[i] = 0x80000000;
break;
}
/* zeroize remaining words */
for (i++ ; i < 15; i++)
W[i] = 0x0;
/*
* if there is room at the end of the word array, then set the
* last word to the bit-length of the message; otherwise, set that
* word to zero and then we need to do one more run of the
* compression algo.
*/ */
if (ctx->octets_in_buffer < 56) {
W[15] = ctx->num_bits_in_msg; int tail = ctx->octets_in_buffer % 4;
else if (ctx->octets_in_buffer < 60)
W[15] = 0x0; /* copy/xor message into array */
for (i = 0; i < (ctx->octets_in_buffer + 3) / 4; i++) {
W[i] = be32_to_cpu(ctx->M[i]);
}
/* set the high bit of the octet immediately following the message */
switch (tail) {
case (3):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffffff00) | 0x80;
W[i] = 0x0;
break;
case (2):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffff0000) | 0x8000;
W[i] = 0x0;
break;
case (1):
W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xff000000) | 0x800000;
W[i] = 0x0;
break;
case (0):
W[i] = 0x80000000;
break;
}
/* zeroize remaining words */
for (i++; i < 15; i++) {
W[i] = 0x0;
}
/*
* if there is room at the end of the word array, then set the
* last word to the bit-length of the message; otherwise, set that
* word to zero and then we need to do one more run of the
* compression algo.
*/
if (ctx->octets_in_buffer < 56) {
W[15] = ctx->num_bits_in_msg;
} else if (ctx->octets_in_buffer < 60) {
W[15] = 0x0;
}
/* process the word array */
for (t = 16; t < 80; t++) {
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP);
}
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
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;
}
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;
}
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;
}
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;
}
ctx->H[0] += A;
ctx->H[1] += B;
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
/* process the word array */
for (t=16; t < 80; t++) {
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = S1(TEMP);
} }
A = ctx->H[0]; debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
for (t=0; t < 20; t++) { if (ctx->octets_in_buffer >= 56) {
TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
E = D; D = C; C = S30(B); B = A; A = TEMP; debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again", NULL);
}
for ( ; t < 40; t++) { /* we need to do one final run of the compression algo */
TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
E = D; D = C; C = S30(B); B = A; A = TEMP; /*
} * set initial part of word array to zeros, and set the
for ( ; t < 60; t++) { * final part to the number of bits in the message
TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2; */
E = D; D = C; C = S30(B); B = A; A = TEMP; for (i = 0; i < 15; i++) {
} W[i] = 0x0;
for ( ; t < 80; t++) { }
TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3; W[15] = ctx->num_bits_in_msg;
E = D; D = C; C = S30(B); B = A; A = TEMP;
/* process the word array */
for (t = 16; t < 80; t++) {
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
W[t] = S1(TEMP);
}
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
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;
}
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;
}
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;
}
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;
}
ctx->H[0] += A;
ctx->H[1] += B;
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
} }
ctx->H[0] += A; /* copy result into output buffer */
ctx->H[1] += B; output[0] = be32_to_cpu(ctx->H[0]);
ctx->H[2] += C; output[1] = be32_to_cpu(ctx->H[1]);
ctx->H[3] += D; output[2] = be32_to_cpu(ctx->H[2]);
ctx->H[4] += E; output[3] = be32_to_cpu(ctx->H[3]);
output[4] = be32_to_cpu(ctx->H[4]);
} /* indicate that message buffer in context is empty */
ctx->octets_in_buffer = 0;
debug_print(mod_sha1, "(final) running sha1_core()", NULL); return;
if (ctx->octets_in_buffer >= 56) {
debug_print(mod_sha1, "(final) running sha1_core() again", NULL);
/* we need to do one final run of the compression algo */
/*
* set initial part of word array to zeros, and set the
* final part to the number of bits in the message
*/
for (i=0; i < 15; i++)
W[i] = 0x0;
W[15] = ctx->num_bits_in_msg;
/* process the word array */
for (t=16; t < 80; t++) {
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = S1(TEMP);
}
A = ctx->H[0];
B = ctx->H[1];
C = ctx->H[2];
D = ctx->H[3];
E = ctx->H[4];
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;
}
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;
}
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;
}
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;
}
ctx->H[0] += A;
ctx->H[1] += B;
ctx->H[2] += C;
ctx->H[3] += D;
ctx->H[4] += E;
}
/* copy result into output buffer */
output[0] = be32_to_cpu(ctx->H[0]);
output[1] = be32_to_cpu(ctx->H[1]);
output[2] = be32_to_cpu(ctx->H[2]);
output[3] = be32_to_cpu(ctx->H[3]);
output[4] = be32_to_cpu(ctx->H[4]);
/* indicate that message buffer in context is empty */
ctx->octets_in_buffer = 0;
return;
} }

View File

@ -1 +0,0 @@
config.h

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,48 +43,39 @@
* *
*/ */
#ifndef _AES_H #ifndef AES_H
#define _AES_H #define AES_H
#include "config.h"
#include "datatypes.h" #include "datatypes.h"
#include "gf2_8.h"
#include "err.h" #include "err.h"
#ifdef __cplusplus
extern "C" {
#endif
/* aes internals */ /* aes internals */
typedef struct { typedef struct {
v128_t round[15]; v128_t round[15];
int num_rounds; int num_rounds;
} aes_expanded_key_t; } srtp_aes_expanded_key_t;
err_status_t srtp_err_status_t srtp_aes_expand_encryption_key(
aes_expand_encryption_key(const uint8_t *key, const uint8_t *key,
int key_len, int key_len,
aes_expanded_key_t *expanded_key); srtp_aes_expanded_key_t *expanded_key);
err_status_t srtp_err_status_t srtp_aes_expand_decryption_key(
aes_expand_decryption_key(const uint8_t *key, const uint8_t *key,
int key_len, int key_len,
aes_expanded_key_t *expanded_key); srtp_aes_expanded_key_t *expanded_key);
void void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
void void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
#if 0 #ifdef __cplusplus
/* }
* internal functions #endif
*/
void #endif /* AES_H */
aes_init_sbox(void);
void
aes_compute_tables(void);
#endif
#endif /* _AES_H */

View File

@ -1,52 +0,0 @@
/*
* aes_cbc.h
*
* Header for AES Cipher Blobk Chaining Mode.
*
* David A. McGrew
* Cisco Systems, Inc.
*
*/
#ifndef AES_CBC_H
#define AES_CBC_H
#include "aes.h"
#include "cipher.h"
typedef struct {
v128_t state; /* cipher chaining state */
v128_t previous; /* previous ciphertext block */
uint8_t key[32];
int key_len;
aes_expanded_key_t expanded_key; /* the cipher key */
} aes_cbc_ctx_t;
err_status_t
aes_cbc_set_key(aes_cbc_ctx_t *c,
const unsigned char *key);
err_status_t
aes_cbc_encrypt(aes_cbc_ctx_t *c,
unsigned char *buf,
unsigned int *bytes_in_data);
err_status_t
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
int key_len);
err_status_t
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv, int direction);
err_status_t
aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data);
err_status_t
aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
unsigned char *data,
unsigned int *bytes_in_data);
#endif /* AES_CBC_H */

View File

@ -8,26 +8,26 @@
* *
*/ */
/* /*
* *
* Copyright (c) 2013, Cisco Systems, Inc. * Copyright (c) 2013-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -48,16 +48,16 @@
#include "cipher.h" #include "cipher.h"
#include "srtp.h" #include "srtp.h"
#include "datatypes.h"
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/aes.h> #include <openssl/aes.h>
typedef struct { typedef struct {
v256_t key; int key_size;
int key_size; int tag_len;
int tag_len; EVP_CIPHER_CTX* ctx;
EVP_CIPHER_CTX ctx; srtp_cipher_direction_t dir;
cipher_direction_t dir; } srtp_aes_gcm_ctx_t;
} aes_gcm_ctx_t;
#endif /* AES_GCM_OSSL_H */ #endif /* AES_GCM_OSSL_H */

View File

@ -8,6 +8,42 @@
* *
*/ */
/*
*
* Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef AES_ICM_H #ifndef AES_ICM_H
#define AES_ICM_H #define AES_ICM_H
@ -15,46 +51,13 @@
#include "cipher.h" #include "cipher.h"
typedef struct { typedef struct {
v128_t counter; /* holds the counter value */ v128_t counter; /* holds the counter value */
v128_t offset; /* initial offset value */ v128_t offset; /* initial offset value */
v128_t keystream_buffer; /* buffers bytes of keystream */ v128_t keystream_buffer; /* buffers bytes of keystream */
aes_expanded_key_t expanded_key; /* the cipher key */ srtp_aes_expanded_key_t expanded_key; /* the cipher key */
int bytes_in_buffer; /* number of unused bytes in buffer */ int bytes_in_buffer; /* number of unused bytes in buffer */
} aes_icm_ctx_t; int key_size; /* AES key size + 14 byte SALT */
} srtp_aes_icm_ctx_t;
err_status_t
aes_icm_context_init(aes_icm_ctx_t *c,
const unsigned char *key,
int key_len);
err_status_t
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction);
err_status_t
aes_icm_encrypt(aes_icm_ctx_t *c,
unsigned char *buf, unsigned int *bytes_to_encr);
err_status_t
aes_icm_output(aes_icm_ctx_t *c,
unsigned char *buf, int bytes_to_output);
err_status_t
aes_icm_dealloc(cipher_t *c);
err_status_t
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
unsigned char *buf,
unsigned int *enc_len,
int forIsmacryp);
err_status_t
aes_icm_alloc_ismacryp(cipher_t **c,
int key_len,
int forIsmacryp);
uint16_t
aes_icm_bytes_encrypted(aes_icm_ctx_t *c);
#endif /* AES_ICM_H */ #endif /* AES_ICM_H */

View File

@ -9,7 +9,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2005,2012, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -47,27 +47,16 @@
#define AES_ICM_H #define AES_ICM_H
#include "cipher.h" #include "cipher.h"
#include "datatypes.h"
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/aes.h> #include <openssl/aes.h>
#define SALT_SIZE 14
#define AES_128_KEYSIZE AES_BLOCK_SIZE
#define AES_192_KEYSIZE AES_BLOCK_SIZE + AES_BLOCK_SIZE / 2
#define AES_256_KEYSIZE AES_BLOCK_SIZE * 2
#define AES_128_KEYSIZE_WSALT AES_128_KEYSIZE + SALT_SIZE
#define AES_192_KEYSIZE_WSALT AES_192_KEYSIZE + SALT_SIZE
#define AES_256_KEYSIZE_WSALT AES_256_KEYSIZE + SALT_SIZE
typedef struct { typedef struct {
v128_t counter; /* holds the counter value */ v128_t counter; /* holds the counter value */
v128_t offset; /* initial offset value */ v128_t offset; /* initial offset value */
v256_t key;
int key_size; int key_size;
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX* ctx;
} aes_icm_ctx_t; } srtp_aes_icm_ctx_t;
err_status_t aes_icm_openssl_set_iv(aes_icm_ctx_t *c, void *iv, int dir);
#endif /* AES_ICM_H */ #endif /* AES_ICM_H */

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,10 +48,16 @@
#include "datatypes.h" #include "datatypes.h"
void * #ifdef __cplusplus
crypto_alloc(size_t size); extern "C" {
#endif
void void * srtp_crypto_alloc(size_t size);
crypto_free(void *ptr);
void srtp_crypto_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif /* CRYPTO_ALLOC_H */ #endif /* CRYPTO_ALLOC_H */

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,129 +43,124 @@
* *
*/ */
#ifndef AUTH_H #ifndef SRTP_AUTH_H
#define AUTH_H #define SRTP_AUTH_H
#include "datatypes.h" #include "srtp.h"
#include "err.h" /* error codes */ #include "crypto_types.h" /* for values of auth_type_id_t */
#include "crypto.h" /* for auth_type_id_t */
#include "crypto_types.h" /* for values of auth_type_id_t */
typedef struct auth_type_t *auth_type_pointer; #ifdef __cplusplus
typedef struct auth_t *auth_pointer_t; extern "C" {
#endif
typedef err_status_t (*auth_alloc_func) typedef const struct srtp_auth_type_t *srtp_auth_type_pointer;
(auth_pointer_t *ap, int key_len, int out_len); typedef struct srtp_auth_t *srtp_auth_pointer_t;
typedef err_status_t (*auth_init_func) typedef srtp_err_status_t (*srtp_auth_alloc_func)
(void *state, const uint8_t *key, int key_len); (srtp_auth_pointer_t *ap, int key_len, int out_len);
typedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap); typedef srtp_err_status_t (*srtp_auth_init_func)
(void *state, const uint8_t *key, int key_len);
typedef err_status_t (*auth_compute_func) typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap);
(void *state, uint8_t *buffer, int octets_to_auth,
int tag_len, uint8_t *tag);
typedef err_status_t (*auth_update_func) typedef srtp_err_status_t (*srtp_auth_compute_func)
(void *state, uint8_t *buffer, int octets_to_auth); (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_start_func)(void *state);
typedef err_status_t (*auth_start_func)(void *state);
/* some syntactic sugar on these function types */ /* some syntactic sugar on these function types */
#define srtp_auth_type_alloc(at, a, klen, outlen) \
((at)->alloc((a), (klen), (outlen)))
#define auth_type_alloc(at, a, klen, outlen) \ #define srtp_auth_init(a, key) \
((at)->alloc((a), (klen), (outlen))) (((a)->type)->init((a)->state, (key), ((a)->key_len)))
#define auth_init(a, key) \ #define srtp_auth_compute(a, buf, len, res) \
(((a)->type)->init((a)->state, (key), ((a)->key_len))) (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
#define auth_compute(a, buf, len, res) \ #define srtp_auth_update(a, buf, len) \
(((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res))) (((a)->type)->update((a)->state, (buf), (len)))
#define auth_update(a, buf, len) \ #define srtp_auth_start(a)(((a)->type)->start((a)->state))
(((a)->type)->update((a)->state, (buf), (len)))
#define auth_start(a)(((a)->type)->start((a)->state)) #define srtp_auth_dealloc(c) (((c)->type)->dealloc(c))
#define auth_dealloc(c) (((c)->type)->dealloc(c))
/* functions to get information about a particular auth_t */ /* functions to get information about a particular auth_t */
int srtp_auth_get_key_length(const struct srtp_auth_t *a);
int int srtp_auth_get_tag_length(const struct srtp_auth_t *a);
auth_get_key_length(const struct auth_t *a);
int int srtp_auth_get_prefix_length(const struct srtp_auth_t *a);
auth_get_tag_length(const struct auth_t *a);
int
auth_get_prefix_length(const struct auth_t *a);
/* /*
* auth_test_case_t is a (list of) key/message/tag values that are * srtp_auth_test_case_t is a (list of) key/message/tag values that are
* known to be correct for a particular cipher. this data can be used * known to be correct for a particular cipher. this data can be used
* to test an implementation in an on-the-fly self test of the * to test an implementation in an on-the-fly self test of the
* correcness of the implementation. (see the auth_type_self_test() * correctness of the implementation. (see the srtp_auth_type_self_test()
* function below) * 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 */
} srtp_auth_test_case_t;
typedef struct auth_test_case_t { /* srtp_auth_type_t */
int key_length_octets; /* octets in key */ typedef struct srtp_auth_type_t {
uint8_t *key; /* key */ srtp_auth_alloc_func alloc;
int data_length_octets; /* octets in data */ srtp_auth_dealloc_func dealloc;
uint8_t *data; /* data */ srtp_auth_init_func init;
int tag_length_octets; /* octets in tag */ srtp_auth_compute_func compute;
uint8_t *tag; /* tag */ srtp_auth_update_func update;
struct auth_test_case_t *next_test_case; /* pointer to next testcase */ srtp_auth_start_func start;
} auth_test_case_t; const char *description;
const srtp_auth_test_case_t *test_data;
srtp_auth_type_id_t id;
} srtp_auth_type_t;
/* auth_type_t */ typedef struct srtp_auth_t {
const srtp_auth_type_t *type;
typedef struct auth_type_t { void *state;
auth_alloc_func alloc; int out_len; /* length of output tag in octets */
auth_dealloc_func dealloc; int key_len; /* length of key in octets */
auth_init_func init; int prefix_len; /* length of keystream prefix */
auth_compute_func compute; } srtp_auth_t;
auth_update_func update;
auth_start_func start;
char *description;
int ref_count;
auth_test_case_t *test_data;
debug_module_t *debug;
auth_type_id_t id;
} auth_type_t;
typedef struct auth_t {
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 */
} auth_t;
/*
* auth_type_self_test() tests an auth_type against test cases
* provided in an array of values of key/message/tag that is known to
* be good
*/
err_status_t
auth_type_self_test(const auth_type_t *at);
/*
* auth_type_test() tests an auth_type against external test cases
* provided in an array of values of key/message/tag that is known to
* be good
*/
err_status_t
auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data);
/* /*
* auth_type_get_ref_count(at) returns the reference count (the number * srtp_auth_type_self_test() tests an auth_type against test cases
* of instantiations) of the 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_self_test(const srtp_auth_type_t *at);
int /*
auth_type_get_ref_count(const auth_type_t *at); * srtp_auth_type_test() tests an auth_type against external test cases
* provided in an array of values of key/message/tag that is known to
* be good
*/
srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
const srtp_auth_test_case_t *test_data);
#endif /* AUTH_H */ /*
* srtp_replace_auth_type(ct, id)
*
* replaces srtp's kernel's auth type implementation for the auth_type id
* with a new one passed in externally. The new auth type must pass all the
* existing auth_type's self tests as well as its own.
*/
srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *ct, srtp_auth_type_id_t id);
#ifdef __cplusplus
}
#endif
#endif /* SRTP_AUTH_H */

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,212 +43,180 @@
*/ */
#ifndef CIPHER_H #ifndef SRTP_CIPHER_H
#define CIPHER_H #define SRTP_CIPHER_H
#include "datatypes.h" #include "srtp.h"
#include "rdbx.h" /* for xtd_seq_num_t */ #include "crypto_types.h" /* for values of cipher_type_id_t */
#include "err.h" /* for error codes */
#include "crypto.h" /* for cipher_type_id_t */
#include "crypto_types.h" /* for values of cipher_type_id_t */
/** #ifdef __cplusplus
* @brief cipher_direction_t defines a particular cipher operation. extern "C" {
#endif
/*
* srtp_cipher_direction_t defines a particular cipher operation.
* *
* A cipher_direction_t is an enum that describes a particular cipher * A srtp_cipher_direction_t is an enum that describes a particular cipher
* operation, i.e. encryption or decryption. For some ciphers, this * operation, i.e. encryption or decryption. For some ciphers, this
* distinction does not matter, but for others, it is essential. * distinction does not matter, but for others, it is essential.
*/ */
typedef enum {
typedef enum { srtp_direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
direction_encrypt, /**< encryption (convert plaintext to ciphertext) */ srtp_direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
direction_decrypt, /**< decryption (convert ciphertext to plaintext) */ srtp_direction_any /**< encryption or decryption */
direction_any /**< encryption or decryption */ } srtp_cipher_direction_t;
} cipher_direction_t;
/* /*
* the cipher_pointer and cipher_type_pointer definitions are needed * the srtp_cipher_pointer_t definition is needed
* as cipher_t and cipher_type_t are not yet defined * as srtp_cipher_t is not yet defined
*/ */
typedef struct srtp_cipher_t *srtp_cipher_pointer_t;
typedef struct cipher_type_t *cipher_type_pointer_t;
typedef struct cipher_t *cipher_pointer_t;
/* /*
* a cipher_alloc_func_t allocates (but does not initialize) a 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)
typedef err_status_t (*cipher_alloc_func_t) (srtp_cipher_pointer_t *cp, int key_len, int tag_len);
(cipher_pointer_t *cp, int key_len, int tag_len);
/*
* a cipher_init_func_t [re-]initializes a cipher_t with a given key
*/
typedef err_status_t (*cipher_init_func_t)
(void *state, const uint8_t *key, int key_len);
/* a cipher_dealloc_func_t de-allocates a cipher_t */
typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp);
/* a cipher_set_segment_func_t sets the segment index of a cipher_t */
typedef err_status_t (*cipher_set_segment_func_t)
(void *state, xtd_seq_num_t idx);
/*
* a cipher_set_aad_func_t processes the AAD data for AEAD ciphers
*/
typedef err_status_t (*cipher_set_aad_func_t)
(void *state, uint8_t *aad, unsigned int aad_len);
/* a cipher_encrypt_func_t encrypts data in-place */
typedef err_status_t (*cipher_encrypt_func_t)
(void *state, uint8_t *buffer, unsigned int *octets_to_encrypt);
/* a cipher_decrypt_func_t decrypts data in-place */
typedef err_status_t (*cipher_decrypt_func_t)
(void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);
/*
* a cipher_set_iv_func_t function sets the current initialization vector
*/
typedef err_status_t (*cipher_set_iv_func_t)
(cipher_pointer_t cp, void *iv, cipher_direction_t direction);
/* /*
* a cipher_get_tag_funct_t function is used to get the authentication * 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);
/* 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);
/*
* 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);
/* 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);
/* 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);
/*
* 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);
/*
* a cipher_get_tag_func_t function is used to get the authentication
* tag that was calculated by an AEAD cipher. * tag that was calculated by an AEAD cipher.
*/ */
typedef err_status_t (*cipher_get_tag_func_t) typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)
(void *state, void *tag, int *len); (void *state, uint8_t *tag, uint32_t *len);
/* /*
* cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t, * srtp_cipher_test_case_t is a (list of) key, salt, plaintext, ciphertext,
* plaintext, and ciphertext values that are known to be correct for a * and aad values that are known to be correct for a
* particular cipher. this data can be used to test an implementation * particular cipher. this data can be used to test an implementation
* in an on-the-fly self test of the correcness of the implementation. * in an on-the-fly self test of the correctness of the implementation.
* (see the cipher_type_self_test() function below) * (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 */
} srtp_cipher_test_case_t;
typedef struct cipher_test_case_t { /* srtp_cipher_type_t defines the 'metadata' for a particular cipher type */
int key_length_octets; /* octets in key */ typedef struct srtp_cipher_type_t {
uint8_t *key; /* key */ srtp_cipher_alloc_func_t alloc;
uint8_t *idx; /* packet index */ srtp_cipher_dealloc_func_t dealloc;
int plaintext_length_octets; /* octets in plaintext */ srtp_cipher_init_func_t init;
uint8_t *plaintext; /* plaintext */ srtp_cipher_set_aad_func_t set_aad;
int ciphertext_length_octets; /* octets in plaintext */ srtp_cipher_encrypt_func_t encrypt;
uint8_t *ciphertext; /* ciphertext */ srtp_cipher_encrypt_func_t decrypt;
int aad_length_octets; /* octets in AAD */ srtp_cipher_set_iv_func_t set_iv;
uint8_t *aad; /* AAD */ srtp_cipher_get_tag_func_t get_tag;
int tag_length_octets; /* Length of AEAD tag */ const char *description;
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */ const srtp_cipher_test_case_t *test_data;
} cipher_test_case_t; srtp_cipher_type_id_t id;
} srtp_cipher_type_t;
/* cipher_type_t defines the 'metadata' for a particular cipher type */
typedef struct cipher_type_t {
cipher_alloc_func_t alloc;
cipher_dealloc_func_t dealloc;
cipher_init_func_t init;
cipher_set_aad_func_t set_aad;
cipher_encrypt_func_t encrypt;
cipher_encrypt_func_t decrypt;
cipher_set_iv_func_t set_iv;
cipher_get_tag_func_t get_tag;
char *description;
int ref_count;
cipher_test_case_t *test_data;
debug_module_t *debug;
cipher_type_id_t id;
} cipher_type_t;
/* /*
* cipher_t defines an instantiation of a particular cipher, with fixed * srtp_cipher_t defines an instantiation of a particular cipher, with fixed
* key length, key and salt values * key length, key and salt values
*/ */
typedef struct srtp_cipher_t {
typedef struct cipher_t { const srtp_cipher_type_t *type;
cipher_type_t *type; void *state;
void *state; int key_len;
int key_len; int algorithm;
int algorithm; } srtp_cipher_t;
} cipher_t;
/* some syntactic sugar on these function types */
#define cipher_type_alloc(ct, c, klen, tlen) ((ct)->alloc((c), (klen), (tlen)))
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
#define cipher_init(c, k) (((c)->type)->init(((c)->state), (k), ((c)->key_len)))
#define cipher_encrypt(c, buf, len) \
(((c)->type)->encrypt(((c)->state), (buf), (len)))
#define cipher_get_tag(c, buf, len) \
(((c)->type)->get_tag(((c)->state), (buf), (len)))
#define cipher_decrypt(c, buf, len) \
(((c)->type)->decrypt(((c)->state), (buf), (len)))
#define cipher_set_iv(c, n, dir) \
((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n), (dir))) : \
err_status_no_such_op)
#define cipher_set_aad(c, a, l) \
(((c) && (((c)->type)->set_aad)) ? \
(((c)->type)->set_aad(((c)->state), (a), (l))) : \
err_status_no_such_op)
err_status_t
cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);
/* some bookkeeping functions */ /* some bookkeeping functions */
int srtp_cipher_get_key_length(const srtp_cipher_t *c);
int
cipher_get_key_length(const cipher_t *c);
/*
* cipher_type_self_test() tests a cipher against test cases provided in
* an array of values of key/xtd_seq_num_t/plaintext/ciphertext
* that is known to be good
*/
err_status_t
cipher_type_self_test(const cipher_type_t *ct);
/*
* cipher_type_test() tests a cipher against external test cases provided in
* an array of values of key/xtd_seq_num_t/plaintext/ciphertext
* that is known to be good
*/
err_status_t
cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data);
/* /*
* cipher_bits_per_second(c, l, t) computes (and estimate of) the * 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
* that is known to be good
*/
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
* 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_cipher_bits_per_second(c, l, t) computes (an estimate of) the
* number of bits that a cipher implementation can encrypt in a second * number of bits that a cipher implementation can encrypt in a second
* *
* c is a cipher (which MUST be allocated and initialized already), l * c is a cipher (which MUST be allocated and initialized already), l
* is the length in octets of the test data to be encrypted, and t is * is the length in octets of the test data to be encrypted, and t is
* the number of trials * the number of trials
* *
* if an error is encountered, then the value 0 is returned * 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_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct, srtp_cipher_t **c, int key_len, int tlen);
cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials); 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);
#endif /* CIPHER_H */ /*
* srtp_replace_cipher_type(ct, id)
*
* replaces srtp's existing cipher implementation for the cipher_type id
* with a new one passed in externally. The new cipher must pass all the
* existing cipher_type's self tests as well as its own.
*/
srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *ct, srtp_cipher_type_id_t id);
#ifdef __cplusplus
}
#endif
#endif /* SRTP_CIPHER_H */

View File

@ -1,43 +0,0 @@
/*
* crypto.h
*
* API for libcrypto
*
* David A. McGrew
* Cisco Systems, Inc.
*/
#ifndef CRYPTO_H
#define CRYPTO_H
/**
* @brief A cipher_type_id_t is an identifier for a particular cipher
* type.
*
* A cipher_type_id_t is an integer that represents a particular
* cipher type, e.g. the Advanced Encryption Standard (AES). A
* NULL_CIPHER is avaliable; this cipher leaves the data unchanged,
* and can be selected to indicate that no encryption is to take
* place.
*
* @ingroup Ciphers
*/
typedef uint32_t cipher_type_id_t;
/**
* @brief An auth_type_id_t is an identifier for a particular authentication
* function.
*
* An auth_type_id_t is an integer that represents a particular
* authentication function type, e.g. HMAC-SHA1. A NULL_AUTH is
* avaliable; this authentication function performs no computation,
* and can be selected to indicate that no authentication is to take
* place.
*
* @ingroup Authentication
*/
typedef uint32_t auth_type_id_t;
#endif /* CRYPTO_H */

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright(c) 2001-2006 Cisco Systems, Inc. * Copyright(c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -46,16 +46,15 @@
#ifndef CRYPTO_KERNEL #ifndef CRYPTO_KERNEL
#define CRYPTO_KERNEL #define CRYPTO_KERNEL
#include "rand_source.h" #include "cipher.h"
#include "prng.h"
#include "cipher.h"
#include "auth.h" #include "auth.h"
#include "cryptoalg.h"
#include "stat.h"
#include "err.h" #include "err.h"
#include "crypto_types.h" #include "crypto_types.h"
#include "key.h" #include "key.h"
#include "crypto.h"
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* crypto_kernel_state_t defines the possible states: * crypto_kernel_state_t defines the possible states:
@ -63,40 +62,36 @@
* insecure - not yet initialized * insecure - not yet initialized
* secure - initialized and passed self-tests * secure - initialized and passed self-tests
*/ */
typedef enum { typedef enum {
crypto_kernel_state_insecure, srtp_crypto_kernel_state_insecure,
crypto_kernel_state_secure srtp_crypto_kernel_state_secure
} crypto_kernel_state_t; } srtp_crypto_kernel_state_t;
/*
* linked list of cipher types
*/
typedef struct kernel_cipher_type {
cipher_type_id_t id;
cipher_type_t *cipher_type;
struct kernel_cipher_type *next;
} kernel_cipher_type_t;
/*
* linked list of auth types
*/
typedef struct kernel_auth_type {
auth_type_id_t id;
auth_type_t *auth_type;
struct kernel_auth_type *next;
} kernel_auth_type_t;
/* /*
* linked list of debug modules * linked list of cipher types
*/ */
typedef struct srtp_kernel_cipher_type {
srtp_cipher_type_id_t id;
const srtp_cipher_type_t *cipher_type;
struct srtp_kernel_cipher_type *next;
} srtp_kernel_cipher_type_t;
typedef struct kernel_debug_module { /*
debug_module_t *mod; * linked list of auth types
struct kernel_debug_module *next; */
} kernel_debug_module_t; typedef struct srtp_kernel_auth_type {
srtp_auth_type_id_t id;
const srtp_auth_type_t *auth_type;
struct srtp_kernel_auth_type *next;
} srtp_kernel_auth_type_t;
/*
* linked list of debug modules
*/
typedef struct srtp_kernel_debug_module {
srtp_debug_module_t *mod;
struct srtp_kernel_debug_module *next;
} srtp_kernel_debug_module_t;
/* /*
@ -105,177 +100,111 @@ typedef struct kernel_debug_module {
* note that there is *exactly one* instance of this data type, * note that there is *exactly one* instance of this data type,
* a global variable defined in crypto_kernel.c * a global variable defined in crypto_kernel.c
*/ */
typedef struct { typedef struct {
crypto_kernel_state_t state; /* current state of kernel */ srtp_crypto_kernel_state_t state; /* current state of kernel */
kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */ srtp_kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */
kernel_auth_type_t *auth_type_list; /* list of all auth func types */ srtp_kernel_auth_type_t *auth_type_list; /* list of all auth func types */
kernel_debug_module_t *debug_module_list; /* list of all debug modules */ srtp_kernel_debug_module_t *debug_module_list; /* list of all debug modules */
} crypto_kernel_t; } srtp_crypto_kernel_t;
/* /*
* crypto_kernel_t external api * srtp_crypto_kernel_t external api
*/ */
/* /*
* The function crypto_kernel_init() initialized the crypto kernel and * The function srtp_crypto_kernel_init() initialized the crypto kernel and
* runs the self-test operations on the random number generators and * runs the self-test operations on the random number generators and
* crypto algorithms. Possible return values are: * crypto algorithms. Possible return values are:
* *
* err_status_ok initialization successful * srtp_err_status_ok initialization successful
* <other> init failure * <other> init failure
* *
* If any value other than err_status_ok is returned, the * If any value other than srtp_err_status_ok is returned, the
* crypto_kernel MUST NOT be used. * crypto_kernel MUST NOT be used.
*/ */
srtp_err_status_t srtp_crypto_kernel_init(void);
err_status_t
crypto_kernel_init(void);
/* /*
* The function crypto_kernel_shutdown() de-initializes the * The function srtp_crypto_kernel_shutdown() de-initializes the
* crypto_kernel, zeroizes keys and other cryptographic material, and * crypto_kernel, zeroizes keys and other cryptographic material, and
* deallocates any dynamically allocated memory. Possible return * deallocates any dynamically allocated memory. Possible return
* values are: * values are:
* *
* err_status_ok shutdown successful * srtp_err_status_ok shutdown successful
* <other> shutdown failure * <other> shutdown failure
* *
*/ */
srtp_err_status_t srtp_crypto_kernel_shutdown(void);
err_status_t
crypto_kernel_shutdown(void);
/* /*
* The function crypto_kernel_stats() checks the the crypto_kernel, * The function srtp_crypto_kernel_stats() checks the the crypto_kernel,
* running tests on the ciphers, auth funcs, and rng, and prints out a * running tests on the ciphers, auth funcs, and rng, and prints out a
* status report. Possible return values are: * status report. Possible return values are:
* *
* err_status_ok all tests were passed * srtp_err_status_ok all tests were passed
* <other> a test failed * <other> a test failed
* *
*/ */
srtp_err_status_t srtp_crypto_kernel_status(void);
err_status_t
crypto_kernel_status(void);
/* /*
* crypto_kernel_list_debug_modules() outputs a list of debugging modules * srtp_crypto_kernel_list_debug_modules() outputs a list of debugging modules
* *
*/ */
srtp_err_status_t srtp_crypto_kernel_list_debug_modules(void);
err_status_t
crypto_kernel_list_debug_modules(void);
/* /*
* crypto_kernel_load_cipher_type() * 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);
err_status_t srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct, srtp_auth_type_id_t id);
crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
err_status_t srtp_err_status_t srtp_crypto_kernel_load_debug_module(srtp_debug_module_t *new_dm);
crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);
/* /*
* crypto_kernel_replace_cipher_type(ct, id) * srtp_crypto_kernel_alloc_cipher(id, cp, key_len);
*
* replaces the crypto kernel's existing cipher for the cipher_type id
* with a new one passed in externally. The new cipher must pass all the
* existing cipher_type's self tests as well as its own.
*/
err_status_t
crypto_kernel_replace_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
/*
* crypto_kernel_replace_auth_type(ct, id)
*
* replaces the crypto kernel's existing cipher for the auth_type id
* with a new one passed in externally. The new auth type must pass all the
* existing auth_type's self tests as well as its own.
*/
err_status_t
crypto_kernel_replace_auth_type(auth_type_t *ct, auth_type_id_t id);
err_status_t
crypto_kernel_load_debug_module(debug_module_t *new_dm);
/*
* crypto_kernel_alloc_cipher(id, cp, key_len);
* *
* allocates a cipher of type id at location *cp, with key length * allocates a cipher of type id at location *cp, with key length
* key_len octets. Return values are: * key_len octets. Return values are:
* *
* err_status_ok no problems * srtp_err_status_ok no problems
* err_status_alloc_fail an allocation failure occured * srtp_err_status_alloc_fail an allocation failure occured
* err_status_fail couldn't find cipher with identifier 'id' * 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);
err_status_t
crypto_kernel_alloc_cipher(cipher_type_id_t id,
cipher_pointer_t *cp,
int key_len,
int tag_len);
/* /*
* crypto_kernel_alloc_auth(id, ap, key_len, tag_len); * srtp_crypto_kernel_alloc_auth(id, ap, key_len, tag_len);
* *
* allocates an auth function of type id at location *ap, with key * allocates an auth function of type id at location *ap, with key
* length key_len octets and output tag length of tag_len. Return * length key_len octets and output tag length of tag_len. Return
* values are: * values are:
* *
* err_status_ok no problems * srtp_err_status_ok no problems
* err_status_alloc_fail an allocation failure occured * srtp_err_status_alloc_fail an allocation failure occured
* err_status_fail couldn't find auth with identifier 'id' * 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);
err_status_t
crypto_kernel_alloc_auth(auth_type_id_t id,
auth_pointer_t *ap,
int key_len,
int tag_len);
/* /*
* crypto_kernel_set_debug_module(mod_name, v) * srtp_crypto_kernel_set_debug_module(mod_name, v)
* *
* sets dynamic debugging to the value v (0 for off, 1 for on) for the * sets dynamic debugging to the value v (0 for off, 1 for on) for the
* debug module with the name mod_name * debug module with the name mod_name
* *
* returns err_status_ok on success, err_status_fail otherwise * 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);
err_status_t #ifdef __cplusplus
crypto_kernel_set_debug_module(char *mod_name, int v); }
#endif
/**
* @brief writes a random octet string.
*
* The function call crypto_get_random(dest, len) writes len octets of
* random data to the location to which dest points, and returns an
* error code. This error code @b must be checked, and if a failure is
* reported, the data in the buffer @b must @b not be used.
*
* @warning If the return code is not checked, then non-random
* data may be in the buffer. This function will fail
* unless it is called after crypto_kernel_init().
*
* @return
* - err_status_ok if no problems occured.
* - [other] a problem occured, and no assumptions should
* be made about the contents of the destination
* buffer.
*
* @ingroup SRTP
*/
err_status_t
crypto_get_random(unsigned char *buffer, unsigned int length);
#endif /* CRYPTO_KERNEL */ #endif /* CRYPTO_KERNEL */

View File

@ -1,239 +0,0 @@
/*
* math.h
*
* crypto math operations and data types
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MATH_H
#define MATH_H
#include "datatypes.h"
unsigned char
v32_weight(v32_t a);
unsigned char
v32_distance(v32_t x, v32_t y);
unsigned int
v32_dot_product(v32_t a, v32_t b);
char *
v16_bit_string(v16_t x);
char *
v32_bit_string(v32_t x);
char *
v64_bit_string(const v64_t *x);
char *
octet_hex_string(uint8_t x);
char *
v16_hex_string(v16_t x);
char *
v32_hex_string(v32_t x);
char *
v64_hex_string(const v64_t *x);
int
hex_char_to_nibble(uint8_t c);
int
is_hex_string(char *s);
v16_t
hex_string_to_v16(char *s);
v32_t
hex_string_to_v32(char *s);
v64_t
hex_string_to_v64(char *s);
/* the matrix A[] is stored in column format, i.e., A[i] is
the ith column of the matrix */
uint8_t
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);
void
v16_copy_octet_string(v16_t *x, const uint8_t s[2]);
void
v32_copy_octet_string(v32_t *x, const uint8_t s[4]);
void
v64_copy_octet_string(v64_t *x, const uint8_t s[8]);
void
v128_add(v128_t *z, v128_t *x, v128_t *y);
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
void
octet_string_set_to_zero(uint8_t *s, int len);
/*
* the matrix A[] is stored in column format, i.e., A[i] is the ith
* column of the matrix
*/
uint8_t
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);
#if 0
#if WORDS_BIGENDIAN
#define _v128_add(z, x, y) { \
uint64_t tmp; \
\
tmp = x->v32[3] + y->v32[3]; \
z->v32[3] = (uint32_t) tmp; \
\
tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \
z->v32[2] = (uint32_t) tmp; \
\
tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \
z->v32[1] = (uint32_t) tmp; \
\
tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \
z->v32[0] = (uint32_t) tmp; \
}
#else /* assume little endian architecture */
#define _v128_add(z, x, y) { \
uint64_t tmp; \
\
tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \
z->v32[3] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \
+ htonl(tmp >> 32); \
z->v32[2] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \
+ htonl(tmp >> 32); \
z->v32[1] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \
+ htonl(tmp >> 32); \
z->v32[0] = ntohl((uint32_t) tmp); \
}
#endif /* WORDS_BIGENDIAN */
#endif
#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);
int
v128_is_eq(const 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_and(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);
int
v128_get_bit(const 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_set_bit_to(v128_t *x, int i, int y);
#endif /* DATATYPES_USE_MACROS */
/*
* octet_string_is_eq(a,b, len) returns 1 if the length len strings a
* and b are not equal, returns 0 otherwise
*/
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
void
octet_string_set_to_zero(uint8_t *s, int len);
#endif /* MATH_H */

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright(c) 2001-2006,2013 Cisco Systems, Inc. * Copyright(c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,207 +42,75 @@
* *
*/ */
#ifndef CRYPTO_TYPES_H #ifndef SRTP_CRYPTO_TYPES_H
#define CRYPTO_TYPES_H #define SRTP_CRYPTO_TYPES_H
/** /*
* @defgroup Algos Cryptographic Algorithms * The null cipher performs no encryption.
* *
* * The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the
* This library provides several different cryptographic algorithms,
* each of which can be selected by using the cipher_type_id_t and
* auth_type_id_t. These algorithms are documented below.
*
* Authentication functions that use the Universal Security Transform
* (UST) must be used in conjunction with a cipher other than the null
* cipher. These functions require a per-message pseudorandom input
* that is generated by the cipher.
*
* The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the
* strongest available authentication function and cipher,
* respectively. They are resolved at compile time to the strongest
* available algorithm. The stronghold algorithms can serve as did
* the keep of a medieval fortification; they provide the strongest
* defense (or the last refuge).
*
* @{
*/
/**
* @defgroup Ciphers Cipher Types
*
* @brief Each cipher type is identified by an unsigned integer. The
* cipher types available in this edition of libSRTP are given
* by the #defines below.
*
* A cipher_type_id_t is an identifier for a cipher_type; only values
* given by the #defines above (or those present in the file
* crypto_types.h) should be used.
*
* The identifier STRONGHOLD_CIPHER indicates the strongest available
* cipher, allowing an application to choose the strongest available
* algorithm without any advance knowledge about the avaliable
* algorithms.
*
* @{
*/
/**
* @brief The null cipher performs no encryption.
*
* The NULL_CIPHER leaves its inputs unaltered, during both the
* encryption and decryption operations. This cipher can be chosen * encryption and decryption operations. This cipher can be chosen
* to indicate that no encryption is to be performed. * to indicate that no encryption is to be performed.
*/ */
#define NULL_CIPHER 0 #define SRTP_NULL_CIPHER 0
/** /*
* @brief AES Integer Counter Mode (AES ICM) * AES-128 Integer Counter Mode (AES ICM)
* *
* AES ICM is the variant of counter mode that is used by Secure RTP. * AES-128 ICM is the variant of counter mode that is used by
* This cipher uses a 16-, 24-, or 32-octet key concatenated with a * Secure RTP. This cipher uses a 16-octet key concatenated with a
* 14-octet offset (or salt) value. * 14-octet offset (or salt) value.
*/ */
#define AES_ICM 1 #define SRTP_AES_ICM_128 1
/** /*
* @brief AES-128 Integer Counter Mode (AES ICM) * AES-192 Integer Counter Mode (AES ICM)
* AES-128 ICM is a deprecated alternate name for AES ICM.
*/
#define AES_128_ICM AES_ICM
/**
* @brief SEAL 3.0
*
* SEAL is the Software-Optimized Encryption Algorithm of Coppersmith
* and Rogaway. Nota bene: this cipher is IBM proprietary.
*/
#define SEAL 2
/**
* @brief AES Cipher Block Chaining mode (AES CBC)
* *
* AES CBC is the AES Cipher Block Chaining mode. * AES-128 ICM is the variant of counter mode that is used by
* This cipher uses a 16-, 24-, or 32-octet key. * Secure RTP. This cipher uses a 24-octet key concatenated with a
* 14-octet offset (or salt) value.
*/ */
#define AES_CBC 3 #define SRTP_AES_ICM_192 4
/** /*
* @brief AES-128 Cipher Block Chaining mode (AES CBC) * AES-256 Integer Counter Mode (AES ICM)
* *
* AES-128 CBC is a deprecated alternate name for AES CBC. * 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 AES_128_CBC AES_CBC #define SRTP_AES_ICM_256 5
/** /*
* @brief Strongest available cipher. * AES-128_GCM Galois Counter Mode (AES GCM)
*
* This identifier resolves to the strongest cipher type available.
*/
#define STRONGHOLD_CIPHER AES_ICM
/**
* @brief AES-192 Integer Counter Mode (AES ICM)
* AES-192 ICM is a deprecated alternate name for AES ICM.
*/
#define AES_192_ICM 4
/**
* @brief AES-256 Integer Counter Mode (AES ICM)
* AES-256 ICM is a deprecated alternate name for AES ICM.
*/
#define AES_256_ICM 5
/**
* @brief AES-128_GCM Galois Counter Mode (AES GCM)
* *
* AES-128 GCM is the variant of galois counter mode that is used by * AES-128 GCM is the variant of galois counter mode that is used by
* Secure RTP. This cipher uses a 16-octet key. * Secure RTP. This cipher uses a 16-octet key.
*/ */
#define AES_128_GCM 6 #define SRTP_AES_GCM_128 6
/** /*
* @brief 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. * Secure RTP. This cipher uses a 32-octet key.
*/ */
#define AES_256_GCM 7 #define SRTP_AES_GCM_256 7
/** /*
* @} * The null authentication function performs no authentication.
*/
/**
* @defgroup Authentication Authentication Function Types
*
* @brief Each authentication function type is identified by an
* unsigned integer. The authentication function types available in
* this edition of libSRTP are given by the #defines below.
*
* An auth_type_id_t is an identifier for an authentication function type;
* only values given by the #defines above (or those present in the
* file crypto_types.h) should be used.
*
* The identifier STRONGHOLD_AUTH indicates the strongest available
* authentication function, allowing an application to choose the
* strongest available algorithm without any advance knowledge about
* the avaliable algorithms. The stronghold algorithms can serve as
* did the keep of a medieval fortification; they provide the
* strongest defense (or the last refuge).
*
* @{
*/
/**
* @brief The null authentication function performs no authentication.
* *
* The NULL_AUTH function does nothing, and can be selected to indicate * The NULL_AUTH function does nothing, and can be selected to indicate
* that authentication should not be performed. * that authentication should not be performed.
*/ */
#define NULL_AUTH 0 #define SRTP_NULL_AUTH 0
/** /*
* @brief UST with TMMH Version 2 * HMAC-SHA1
* *
* UST_TMMHv2 implements the Truncated Multi-Modular Hash using * SRTP_HMAC_SHA1 implements the Hash-based MAC using the NIST Secure
* UST. This function must be used in conjunction with a cipher other
* than the null cipher.
* with a cipher.
*/
#define UST_TMMHv2 1
/**
* @brief (UST) AES-128 XORMAC
*
* UST_AES_128_XMAC implements AES-128 XORMAC, using UST. Nota bene:
* the XORMAC algorithm is IBM proprietary.
*/
#define UST_AES_128_XMAC 2
/**
* @brief HMAC-SHA1
*
* HMAC_SHA1 implements the Hash-based MAC using the NIST Secure
* Hash Algorithm version 1 (SHA1). * Hash Algorithm version 1 (SHA1).
*/ */
#define HMAC_SHA1 3 #define SRTP_HMAC_SHA1 3
/** #endif /* SRTP_CRYPTO_TYPES_H */
* @brief Strongest available authentication function.
*
* This identifier resolves to the strongest available authentication
* function.
*/
#define STRONGHOLD_AUTH HMAC_SHA1
/**
* @}
*/
/**
* @}
*/
#endif /* CRYPTO_TYPES_H */

View File

@ -1,133 +0,0 @@
/*
* cryptoalg.h
*
* API for authenticated encryption crypto algorithms
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CRYPTOALG_H
#define CRYPTOALG_H
#include "err.h"
/**
* @defgroup Crypto Cryptography
*
* Zed uses a simple interface to a cryptographic transform.
*
* @{
*/
/**
* @brief applies a crypto algorithm
*
* The function pointer cryptoalg_func_t points to a function that
* implements a crypto transform, and provides a uniform API for
* accessing crypto mechanisms.
*
* @param key location of secret key
*
* @param clear data to be authenticated but not encrypted
*
* @param clear_len length of data to be authenticated but not encrypted
*
* @param iv location to write the Initialization Vector (IV)
*
* @param protect location of the data to be encrypted and
* authenticated (before the function call), and the ciphertext
* and authentication tag (after the call)
*
* @param protected_len location of the length of the data to be
* encrypted and authenticated (before the function call), and the
* length of the ciphertext (after the call)
*
*/
typedef err_status_t (*cryptoalg_func_t)
(void *key,
const void *clear,
unsigned clear_len,
void *iv,
void *protect,
unsigned *protected_len);
typedef
err_status_t (*cryptoalg_inv_t)
(void *key, /* location of secret key */
const void *clear, /* data to be authenticated only */
unsigned clear_len, /* length of data to be authenticated only */
void *iv, /* location of iv */
void *opaque, /* data to be decrypted and authenticated */
unsigned *opaque_len /* location of the length of data to be
* decrypted and authd (before and after)
*/
);
typedef struct cryptoalg_ctx_t {
cryptoalg_func_t enc;
cryptoalg_inv_t dec;
unsigned key_len;
unsigned iv_len;
unsigned auth_tag_len;
unsigned max_expansion;
} cryptoalg_ctx_t;
typedef cryptoalg_ctx_t *cryptoalg_t;
#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)
#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)
#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)
int
cryptoalg_get_id(cryptoalg_t c);
cryptoalg_t
cryptoalg_find_by_id(int id);
/**
* @}
*/
#endif /* CRYPTOALG_H */

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,23 +44,25 @@
*/ */
#ifndef _DATATYPES_H #ifndef DATATYPES_H
#define _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 "alloc.h"
#include <stdarg.h> #include <stdarg.h>
#ifndef SRTP_KERNEL #include <stdio.h>
# include <stdio.h> #include <string.h>
# include <string.h> #include <time.h>
# include <time.h> #ifdef HAVE_NETINET_IN_H
# ifdef HAVE_NETINET_IN_H # include <netinet/in.h>
# include <netinet/in.h> #elif defined HAVE_WINSOCK2_H
# elif defined HAVE_WINSOCK2_H # include <winsock2.h>
# include <winsock2.h> #endif
# endif
#ifdef __cplusplus
extern "C" {
#endif #endif
@ -115,13 +117,10 @@ typedef union {
int int
octet_get_weight(uint8_t octet); octet_get_weight(uint8_t octet);
char *
octet_bit_string(uint8_t x);
#define MAX_PRINT_STRING_LEN 1024 #define MAX_PRINT_STRING_LEN 1024
char * char *
octet_string_hex_string(const void *str, int length); srtp_octet_string_hex_string(const void *str, int length);
char * char *
v128_bit_string(v128_t *x); v128_bit_string(v128_t *x);
@ -129,34 +128,6 @@ v128_bit_string(v128_t *x);
char * char *
v128_hex_string(v128_t *x); v128_hex_string(v128_t *x);
uint8_t
nibble_to_hex_char(uint8_t nibble);
char *
char_to_hex_string(char *x, int num_char);
uint8_t
hex_string_to_octet(char *s);
/*
* hex_string_to_octet_string(raw, hex, len) converts the hexadecimal
* string at *hex (of length len octets) to the equivalent raw data
* and writes it to *raw.
*
* if a character in the hex string that is not a hexadeciaml digit
* (0123456789abcdefABCDEF) is encountered, the function stops writing
* data to *raw
*
* the number of hex digits copied (which is two times the number of
* octets in *raw) is returned
*/
int
hex_string_to_octet_string(char *raw, char *hex, int len);
v128_t
hex_string_to_v128(char *s);
void void
v128_copy_octet_string(v128_t *x, const uint8_t s[16]); v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
@ -274,51 +245,6 @@ v128_right_shift(v128_t *x, int shift_index);
_v128_clear_bit(x, bit) \ _v128_clear_bit(x, bit) \
) )
#if 0
/* nothing uses this */
#ifdef WORDS_BIGENDIAN
#define _v128_add(z, x, y) { \
uint64_t tmp; \
\
tmp = x->v32[3] + y->v32[3]; \
z->v32[3] = (uint32_t) tmp; \
\
tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \
z->v32[2] = (uint32_t) tmp; \
\
tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \
z->v32[1] = (uint32_t) tmp; \
\
tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \
z->v32[0] = (uint32_t) tmp; \
}
#else /* assume little endian architecture */
#define _v128_add(z, x, y) { \
uint64_t tmp; \
\
tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \
z->v32[3] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \
+ htonl(tmp >> 32); \
z->v32[2] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \
+ htonl(tmp >> 32); \
z->v32[1] = ntohl((uint32_t) tmp); \
\
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \
+ htonl(tmp >> 32); \
z->v32[0] = ntohl((uint32_t) tmp); \
}
#endif /* WORDS_BIGENDIAN */
#endif /* 0 */
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */ #ifdef DATATYPES_USE_MACROS /* little functions are really macros */
#define v128_set_to_zero(z) _v128_set_to_zero(z) #define v128_set_to_zero(z) _v128_set_to_zero(z)
@ -372,18 +298,31 @@ v128_set_bit_to(v128_t *x, int i, int y);
#endif /* DATATYPES_USE_MACROS */ #endif /* DATATYPES_USE_MACROS */
/* /*
* octet_string_is_eq(a,b, len) returns 1 if the length len strings a * octet_string_is_eq(a, b, len) returns 1 if the length len strings a
* and b are not equal, returns 0 otherwise * and b are not equal. It returns 0 otherwise. The running time of the
* comparison depends only on len, making this safe to use for (e.g.)
* verifying authentication tags.
*/ */
int int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len); 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 void
octet_string_set_to_zero(uint8_t *s, int len); 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);
#ifndef SRTP_KERNEL_LINUX #if defined(HAVE_CONFIG_H)
/* /*
* Convert big endian integers to CPU byte order. * Convert big endian integers to CPU byte order.
@ -399,7 +338,7 @@ octet_string_set_to_zero(uint8_t *s, int len);
# define be64_to_cpu(x) bswap_64((x)) # define be64_to_cpu(x) bswap_64((x))
#else #else
#if defined(__GNUC__) && defined(HAVE_X86) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__sun) #if defined(__GNUC__) && defined(HAVE_X86)
/* Fall back. */ /* Fall back. */
static inline uint32_t be32_to_cpu(uint32_t v) { static inline uint32_t be32_to_cpu(uint32_t v) {
/* optimized for x86. */ /* optimized for x86. */
@ -426,7 +365,7 @@ static inline uint64_t be64_to_cpu(uint64_t v) {
return v; return v;
} }
#endif /* ! SRTP_KERNEL_LINUX */ #endif
#endif /* WORDS_BIGENDIAN */ #endif /* WORDS_BIGENDIAN */
@ -509,4 +448,8 @@ bitvector_left_shift(bitvector_t *x, int index);
char * char *
bitvector_bit_string(bitvector_t *x, char* buf, int len); bitvector_bit_string(bitvector_t *x, char* buf, int len);
#endif /* _DATATYPES_H */ #ifdef __cplusplus
}
#endif
#endif /* DATATYPES_H */

View File

@ -1,32 +1,32 @@
/* /*
* err.h * err.h
* *
* error status codes * error status codes
* *
* David A. McGrew * David A. McGrew
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -46,97 +46,58 @@
#ifndef ERR_H #ifndef ERR_H
#define ERR_H #define ERR_H
#include "datatypes.h" #include <stdio.h>
#include <stdarg.h>
#include "srtp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @defgroup Error Error Codes * @defgroup Error Error Codes
* *
* Error status codes are represented by the enumeration err_status_t. * Error status codes are represented by the enumeration srtp_err_status_t.
* *
* @{ * @{
*/ */
/*
* @brief err_status_t defines error codes.
*
* The enumeration err_status_t defines error codes. Note that the
* value of err_status_ok is equal to zero, which can simplify error
* checking somewhat.
*
*/
typedef enum {
err_status_ok = 0, /**< nothing to report */
err_status_fail = 1, /**< unspecified failure */
err_status_bad_param = 2, /**< unsupported parameter */
err_status_alloc_fail = 3, /**< couldn't allocate memory */
err_status_dealloc_fail = 4, /**< couldn't deallocate properly */
err_status_init_fail = 5, /**< couldn't initialize */
err_status_terminus = 6, /**< can't process as much data as requested */
err_status_auth_fail = 7, /**< authentication failure */
err_status_cipher_fail = 8, /**< cipher failure */
err_status_replay_fail = 9, /**< replay check failed (bad index) */
err_status_replay_old = 10, /**< replay check failed (index too old) */
err_status_algo_fail = 11, /**< algorithm failed test routine */
err_status_no_such_op = 12, /**< unsupported operation */
err_status_no_ctx = 13, /**< no appropriate context found */
err_status_cant_check = 14, /**< unable to perform desired validation */
err_status_key_expired = 15, /**< can't use key any more */
err_status_socket_err = 16, /**< error in use of socket */
err_status_signal_err = 17, /**< error in use POSIX signals */
err_status_nonce_bad = 18, /**< nonce check failed */
err_status_read_fail = 19, /**< couldn't read data */
err_status_write_fail = 20, /**< couldn't write data */
err_status_parse_err = 21, /**< error parsing data */
err_status_encode_err = 22, /**< error encoding data */
err_status_semaphore_err = 23,/**< error while using semaphores */
err_status_pfkey_err = 24 /**< error while using pfkey */
} err_status_t;
/** /**
* @} * @}
*/ */
typedef enum { typedef enum {
err_level_emergency = 0, srtp_err_level_error,
err_level_alert, srtp_err_level_warning,
err_level_critical, srtp_err_level_info,
err_level_error, srtp_err_level_debug
err_level_warning, } srtp_err_reporting_level_t;
err_level_notice,
err_level_info,
err_level_debug,
err_level_none
} err_reporting_level_t;
/* /*
* err_reporting_init prepares the error system. If * err_reporting_init prepares the error system. If
* ERR_REPORTING_SYSLOG is defined, it will open syslog. * ERR_REPORTING_STDOUT is defined, it will log to stdout.
* *
* The ident argument is a string that will be prepended to
* all syslog messages. It is conventionally argv[0].
*/ */
err_status_t srtp_err_status_t srtp_err_reporting_init(void);
err_reporting_init(char *ident);
#ifdef SRTP_KERNEL_LINUX typedef void (srtp_err_report_handler_func_t)(srtp_err_reporting_level_t level, const char * msg);
extern err_reporting_level_t err_level;
#else srtp_err_status_t srtp_install_err_report_handler(srtp_err_report_handler_func_t func);
/* /*
* keydaemon_report_error reports a 'printf' formatted error * srtp_err_report reports a 'printf' formatted error
* string, followed by a an arg list. The priority argument * string, followed by a an arg list. The level argument
* is equivalent to that defined for syslog. * is one of srtp_err_reporting_level_t.
* *
* Errors will be reported to ERR_REPORTING_FILE, if defined, and to * Errors will be reported to stdout, if ERR_REPORTING_STDOUT
* syslog, if ERR_REPORTING_SYSLOG is defined. * is defined.
* *
*/ */
void void
err_report(int priority, char *format, ...); srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
#endif /* ! SRTP_KERNEL_LINUX */
/* /*
@ -144,31 +105,28 @@ err_report(int priority, char *format, ...);
*/ */
typedef struct { typedef struct {
int on; /* 1 if debugging is on, 0 if it is off */ int on; /* 1 if debugging is on, 0 if it is off */
char *name; /* printable name for debug module */ const char *name; /* printable name for debug module */
} debug_module_t; } srtp_debug_module_t;
#ifdef ENABLE_DEBUGGING #ifdef ENABLE_DEBUG_LOGGING
#define debug_on(mod) (mod).on = 1
#define debug_off(mod) (mod).on = 0
/* use err_report() to report debug message */
#define debug_print(mod, format, arg) \ #define debug_print(mod, format, arg) \
if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
#define debug_print2(mod, format, arg1,arg2) \ #define debug_print2(mod, format, arg1, arg2) \
if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg1,arg2) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
#else #else
/* define macros to do nothing */ #define debug_print(mod, format, arg) \
#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) \
#define debug_on(mod) if (mod.on) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
#define debug_off(mod)
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* ERR_H */ #endif /* ERR_H */

View File

@ -1,79 +0,0 @@
/*
* gf2_8.h
*
* GF(256) implementation
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GF2_8_H
#define GF2_8_H
#include "datatypes.h" /* for uint8_t definition */
typedef uint8_t gf2_8;
#define gf2_8_field_polynomial 0x1B
/*
* gf2_8_shift(x) returns
*/
/*
* gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x'
* operation, using the field representation from AES; that is, the
* 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))
gf2_8
gf2_8_compute_inverse(gf2_8 x);
void
test_gf2_8(void);
gf2_8
gf2_8_multiply(gf2_8 x, gf2_8 y);
#endif /* GF2_8_H */

View File

@ -1,33 +1,33 @@
/* /*
* hmac.h * hmac.h
* *
* interface to hmac auth_type_t * interface to hmac srtp_auth_type_t
* *
* David A. McGrew * David A. McGrew
* Cisco Systems, Inc. * Cisco Systems, Inc.
* *
*/ */
/* /*
* *
* Copyright (c) 2001-2006,2013, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -50,33 +50,9 @@
#include "sha1.h" #include "sha1.h"
typedef struct { typedef struct {
uint8_t opad[64]; uint8_t opad[64];
sha1_ctx_t ctx; srtp_sha1_ctx_t ctx;
sha1_ctx_t init_ctx; srtp_sha1_ctx_t init_ctx;
#ifdef OPENSSL } srtp_hmac_ctx_t;
int ctx_initialized;
int init_ctx_initialized;
#endif
} hmac_ctx_t;
err_status_t
hmac_alloc(auth_t **a, int key_len, int out_len);
err_status_t
hmac_dealloc(auth_t *a);
err_status_t
hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len);
err_status_t
hmac_start(hmac_ctx_t *state);
err_status_t
hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets);
err_status_t
hmac_compute(hmac_ctx_t *state, const void *message,
int msg_octets, int tag_len, uint8_t *result);
#endif /* HMAC_H */ #endif /* HMAC_H */

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -47,13 +47,6 @@
#ifndef INTEGERS_H #ifndef INTEGERS_H
#define INTEGERS_H #define INTEGERS_H
#include "config.h" /* configuration file, using autoconf */
#ifdef SRTP_KERNEL
#include "kernel_compat.h"
#else /* SRTP_KERNEL */
/* use standard integer definitions, if they're available */ /* use standard integer definitions, if they're available */
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
@ -75,8 +68,12 @@
# include <machine/types.h> # include <machine/types.h>
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
/* Can we do 64 bit integers? */ /* Can we do 64 bit integers? */
#ifndef HAVE_UINT64_T #if !defined(HAVE_UINT64_T)
# if SIZEOF_UNSIGNED_LONG == 8 # if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long uint64_t; typedef unsigned long uint64_t;
# elif SIZEOF_UNSIGNED_LONG_LONG == 8 # elif SIZEOF_UNSIGNED_LONG_LONG == 8
@ -97,9 +94,12 @@ typedef unsigned short int uint16_t;
#ifndef HAVE_UINT32_T #ifndef HAVE_UINT32_T
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
#endif #endif
#ifndef HAVE_INT32_T
typedef int int32_t;
#endif
#ifdef NO_64BIT_MATH #if defined(NO_64BIT_MATH) && defined(HAVE_CONFIG_H)
typedef double uint64_t; typedef double uint64_t;
/* assert that sizeof(double) == 8 */ /* assert that sizeof(double) == 8 */
extern uint64_t make64(uint32_t high, uint32_t low); extern uint64_t make64(uint32_t high, uint32_t low);
@ -107,7 +107,6 @@ extern uint32_t high32(uint64_t value);
extern uint32_t low32(uint64_t value); extern uint32_t low32(uint64_t value);
#endif #endif
#endif /* SRTP_KERNEL */
/* These macros are to load and store 32-bit values from un-aligned /* These macros are to load and store 32-bit values from un-aligned
addresses. This is required for processors that do not allow unaligned addresses. This is required for processors that do not allow unaligned
@ -144,4 +143,8 @@ extern uint32_t low32(uint64_t value);
#define GET_32(addr) (*(((uint32_t *) (addr))) #define GET_32(addr) (*(((uint32_t *) (addr)))
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* INTEGERS_H */ #endif /* INTEGERS_H */

View File

@ -1,84 +0,0 @@
/*
* kernel_compat.h
*
* Compatibility stuff for building in kernel context where standard
* C headers and library are not available.
*
* Marcus Sundberg
* Ingate Systems AB
*/
/*
*
* Copyright(c) 2005 Ingate Systems AB
* 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 author(s) 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 KERNEL_COMPAT_H
#define KERNEL_COMPAT_H
#ifdef SRTP_KERNEL_LINUX
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/random.h>
#include <linux/byteorder/generic.h>
#define err_report(priority, ...) \
do {\
if (priority <= err_level) {\
printk(__VA_ARGS__);\
}\
}while(0)
#define clock() (jiffies)
#define time(x) (jiffies)
/* rand() implementation. */
#define RAND_MAX 32767
static inline int rand(void)
{
uint32_t temp;
get_random_bytes(&temp, sizeof(temp));
return temp % (RAND_MAX+1);
}
/* stdio/stdlib implementation. */
#define printf(...) printk(__VA_ARGS__)
#define exit(n) panic("%s:%d: exit(%d)\n", __FILE__, __LINE__, (n))
#endif /* SRTP_KERNEL_LINUX */
#endif /* KERNEL_COMPAT_H */

View File

@ -2,31 +2,31 @@
* key.h * key.h
* *
* key usage limits enforcement * key usage limits enforcement
* *
* David A. Mcgrew * David A. Mcgrew
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -45,38 +45,42 @@
#ifndef KEY_H #ifndef KEY_H
#define KEY_H #define KEY_H
#include "rdbx.h" /* for xtd_seq_num_t */ #include "rdbx.h" /* for srtp_xtd_seq_num_t */
#include "err.h" #include "err.h"
typedef struct key_limit_ctx_t *key_limit_t; #ifdef __cplusplus
extern "C" {
#endif
typedef struct srtp_key_limit_ctx_t *srtp_key_limit_t;
typedef enum { typedef enum {
key_event_normal, srtp_key_event_normal,
key_event_soft_limit, srtp_key_event_soft_limit,
key_event_hard_limit srtp_key_event_hard_limit
} key_event_t; } srtp_key_event_t;
err_status_t srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key, const srtp_xtd_seq_num_t s);
key_limit_set(key_limit_t key, const xtd_seq_num_t s);
err_status_t srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original, srtp_key_limit_t *new_key);
key_limit_clone(key_limit_t original, key_limit_t *new_key);
err_status_t srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key);
key_limit_check(const key_limit_t key);
key_event_t srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key);
key_limit_update(key_limit_t key);
typedef enum { typedef enum {
key_state_normal, srtp_key_state_normal,
key_state_past_soft_limit, srtp_key_state_past_soft_limit,
key_state_expired srtp_key_state_expired
} key_state_t; } srtp_key_state_t;
typedef struct key_limit_ctx_t { typedef struct srtp_key_limit_ctx_t {
xtd_seq_num_t num_left; srtp_xtd_seq_num_t num_left;
key_state_t state; srtp_key_state_t state;
} key_limit_ctx_t; } srtp_key_limit_ctx_t;
#ifdef __cplusplus
}
#endif
#endif /* KEY_H */ #endif /* KEY_H */

View File

@ -7,26 +7,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -47,22 +47,27 @@
#include "auth.h" #include "auth.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct { typedef struct {
char foo; char foo;
} null_auth_ctx_t; } srtp_null_auth_ctx_t;
err_status_t #if 0
null_auth_alloc(auth_t **a, int key_len, int out_len); srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a, int key_len, int out_len);
err_status_t srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a);
null_auth_dealloc(auth_t *a);
err_status_t srtp_err_status_t srtp_null_auth_init(srtp_null_auth_ctx_t *state, const uint8_t *key, int key_len);
null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len);
err_status_t srtp_err_status_t srtp_null_auth_compute(srtp_null_auth_ctx_t *state, uint8_t *message, int msg_octets, int tag_len, uint8_t *result);
null_auth_compute (null_auth_ctx_t *state, uint8_t *message,
int msg_octets, int tag_len, uint8_t *result);
#endif
#ifdef __cplusplus
}
#endif
#endif /* NULL_AUTH_H */ #endif /* NULL_AUTH_H */

View File

@ -9,26 +9,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -52,29 +52,7 @@
#include "cipher.h" #include "cipher.h"
typedef struct { typedef struct {
char foo ;/* empty, for now */ char foo; /* empty, for now */
} null_cipher_ctx_t; } srtp_null_cipher_ctx_t;
/*
* none of these functions do anything (though future versions may keep
* track of bytes encrypted, number of instances, and/or other info).
*/
err_status_t
null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key, int key_len);
err_status_t
null_cipher_set_segment(null_cipher_ctx_t *c,
unsigned long segment_index);
err_status_t
null_cipher_encrypt(null_cipher_ctx_t *c,
unsigned char *buf, unsigned int *bytes_to_encr);
err_status_t
null_cipher_encrypt_aligned(null_cipher_ctx_t *c,
unsigned char *buf, int bytes_to_encr);
#endif /* NULL_CIPHER_H */ #endif /* NULL_CIPHER_H */

View File

@ -1,59 +0,0 @@
/*
* prng.h
*
* pseudorandom source
*
* David A. McGrew
* Cisco Systems, Inc.
*/
#ifndef PRNG_H
#define PRNG_H
#include "rand_source.h" /* for rand_source_func_t definition */
#include "aes.h" /* for aes */
//FIXME: this is temporary until we pull in the code to use OpenSSL for RNG
#ifdef OPENSSL
#include "aes_icm_ossl.h" /* for aes ctr */
#else
#include "aes_icm.h" /* for aes ctr */
#endif
#define MAX_PRNG_OUT_LEN 0xffffffffU
/*
* x917_prng is an ANSI X9.17-like AES-based PRNG
*/
typedef struct {
v128_t state; /* state data */
aes_expanded_key_t key; /* secret key */
uint32_t octet_count; /* number of octets output since last init */
rand_source_func_t rand; /* random source for re-initialization */
} x917_prng_t;
err_status_t
x917_prng_init(rand_source_func_t random_source);
err_status_t
x917_prng_get_octet_string(uint8_t *dest, uint32_t len);
/*
* ctr_prng is an AES-CTR based PRNG
*/
typedef struct {
uint32_t octet_count; /* number of octets output since last init */
aes_icm_ctx_t state; /* state data */
rand_source_func_t rand; /* random source for re-initialization */
} ctr_prng_t;
err_status_t
ctr_prng_init(rand_source_func_t random_source);
err_status_t
ctr_prng_get_octet_string(void *dest, uint32_t len);
#endif

View File

@ -8,12 +8,52 @@
*/ */
/*
*
* Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef REPLAY_DB_H #ifndef REPLAY_DB_H
#define REPLAY_DB_H #define REPLAY_DB_H
#include "integers.h" /* for uint32_t */ #include "integers.h" /* for uint32_t */
#include "datatypes.h" /* for v128_t */ #include "datatypes.h" /* for v128_t */
#include "err.h" /* for err_status_t */ #include "err.h" /* for srtp_err_status_t */
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* if the ith least significant bit is one, then the packet index * if the ith least significant bit is one, then the packet index
@ -21,74 +61,69 @@
*/ */
typedef struct { typedef struct {
uint32_t window_start; /* packet index of the first bit in bitmask */ uint32_t window_start; /* packet index of the first bit in bitmask */
v128_t bitmask; v128_t bitmask;
} rdb_t; } srtp_rdb_t;
#define rdb_bits_in_bitmask (8*sizeof(v128_t)) #define rdb_bits_in_bitmask (8 * sizeof(v128_t))
/* /*
* rdb init * srtp_rdb_init
* *
* initalizes rdb * initalizes rdb
* *
* returns err_status_ok on success, err_status_t_fail otherwise * returns srtp_err_status_ok on success, srtp_err_status_t_fail otherwise
*/ */
srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb);
err_status_t
rdb_init(rdb_t *rdb);
/* /*
* rdb_check * srtp_rdb_check
* *
* checks to see if index appears in rdb * checks to see if index appears in rdb
* *
* returns err_status_fail if the index already appears in rdb, * returns srtp_err_status_fail if the index already appears in rdb,
* returns err_status_ok otherwise * returns srtp_err_status_ok otherwise
*/ */
srtp_err_status_t srtp_rdb_check(const srtp_rdb_t *rdb, uint32_t rdb_index);
err_status_t
rdb_check(const rdb_t *rdb, uint32_t rdb_index);
/* /*
* rdb_add_index * srtp_rdb_add_index
* *
* adds index to rdb_t (and does *not* check if index appears in db) * adds index to srtp_rdb_t (and does *not* check if index appears in db)
* *
* returns err_status_ok on success, err_status_fail otherwise * returns srtp_err_status_ok on success, srtp_err_status_fail otherwise
* *
*/ */
srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t rdb_index);
err_status_t
rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
/* /*
* the functions rdb_increment() and rdb_get_value() are for use by * the functions srtp_rdb_increment() and srtp_rdb_get_value() are for use by
* senders, not receivers - DO NOT use these functions on the same * senders, not receivers - DO NOT use these functions on the same
* rdb_t upon which rdb_add_index is used! * srtp_rdb_t upon which srtp_rdb_add_index is used!
*/ */
/* /*
* rdb_increment(db) increments the sequence number in db, if it is * srtp_rdb_increment(db) increments the sequence number in db, if it is
* not too high * not too high
* *
* return values: * return values:
* *
* err_status_ok no problem * srtp_err_status_ok no problem
* err_status_key_expired sequence number too high * srtp_err_status_key_expired sequence number too high
* *
*/ */
err_status_t srtp_err_status_t srtp_rdb_increment(srtp_rdb_t *rdb);
rdb_increment(rdb_t *rdb);
/* /*
* rdb_get_value(db) returns the current sequence number of db * srtp_rdb_get_value(db) returns the current sequence number of db
*/ */
uint32_t srtp_rdb_get_value(const srtp_rdb_t *rdb);
uint32_t
rdb_get_value(const rdb_t *rdb);
#endif /* REPLAY_DB_H */ #ifdef __cplusplus
}
#endif
#endif /* REPLAY_DB_H */

View File

@ -8,179 +8,204 @@
* *
*/ */
/*
*
* Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef RDBX_H #ifndef RDBX_H
#define RDBX_H #define RDBX_H
#include "datatypes.h" #include "datatypes.h"
#include "err.h" #include "err.h"
/* #define ROC_TEST */ #ifdef __cplusplus
extern "C" {
#endif
/* #define ROC_TEST */
#ifndef ROC_TEST #ifndef ROC_TEST
typedef uint16_t sequence_number_t; /* 16 bit sequence number */ typedef uint16_t srtp_sequence_number_t; /* 16 bit sequence number */
typedef uint32_t rollover_counter_t; /* 32 bit rollover counter */ 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 sequence_number_t; /* 8 bit sequence number */ typedef unsigned char srtp_sequence_number_t; /* 8 bit sequence number */
typedef uint16_t rollover_counter_t; /* 16 bit rollover counter */ typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */
#endif #endif
#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1)) #define seq_num_median (1 << (8 * sizeof(srtp_sequence_number_t) - 1))
#define seq_num_max (1 << (8*sizeof(sequence_number_t))) #define seq_num_max (1 << (8 * sizeof(srtp_sequence_number_t)))
/* /*
* An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended' * An rtp_xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'
* sequence number. * sequence number.
*/ */
typedef uint64_t srtp_xtd_seq_num_t;
typedef uint64_t xtd_seq_num_t;
/* /*
* An rdbx_t is a replay database with extended range; it uses an * 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. * xtd_seq_num_t and a bitmask of recently received indices.
*/ */
typedef struct { typedef struct {
xtd_seq_num_t index; srtp_xtd_seq_num_t index;
bitvector_t bitmask; bitvector_t bitmask;
} rdbx_t; } srtp_rdbx_t;
/* /*
* rdbx_init(rdbx_ptr, ws) * srtp_rdbx_init(rdbx_ptr, ws)
* *
* initializes the rdbx pointed to by its argument with the window size ws, * initializes the rdbx pointed to by its argument with the window size ws,
* setting the rollover counter and sequence number to zero * setting the rollover counter and sequence number to zero
*/ */
srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws);
err_status_t
rdbx_init(rdbx_t *rdbx, unsigned long ws);
/* /*
* rdbx_dealloc(rdbx_ptr) * srtp_rdbx_dealloc(rdbx_ptr)
* *
* frees memory associated with the rdbx * frees memory associated with the rdbx
*/ */
srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx);
err_status_t
rdbx_dealloc(rdbx_t *rdbx);
/* /*
* rdbx_estimate_index(rdbx, guess, s) * srtp_rdbx_estimate_index(rdbx, guess, s)
* *
* given an rdbx and a sequence number s (from a newly arrived packet), * given an rdbx and a sequence number s (from a newly arrived packet),
* sets the contents of *guess to contain the best guess of the packet * sets the contents of *guess to contain the best guess of the packet
* index to which s corresponds, and returns the difference between * index to which s corresponds, and returns the difference between
* *guess and the locally stored synch info * *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);
int
rdbx_estimate_index(const rdbx_t *rdbx,
xtd_seq_num_t *guess,
sequence_number_t s);
/* /*
* rdbx_check(rdbx, delta); * srtp_rdbx_check(rdbx, delta);
* *
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t * srtp_rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
* which is at rdbx->window_start + delta is in the rdb * which is at rdbx->window_start + delta is in the rdb
* *
*/ */
srtp_err_status_t srtp_rdbx_check(const srtp_rdbx_t *rdbx, int difference);
err_status_t
rdbx_check(const rdbx_t *rdbx, int difference);
/* /*
* replay_add_index(rdbx, delta) * srtp_replay_add_index(rdbx, delta)
* *
* adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db * adds the srtp_xtd_seq_num_t at rdbx->window_start + delta to replay_db
* (and does *not* check if that xtd_seq_num_t appears in db) * (and does *not* check if that xtd_seq_num_t appears in db)
* *
* this function should be called *only* after replay_check has * this function should be called *only* after replay_check has
* indicated that the index does not appear in the rdbx, and a mutex * indicated that the index does not appear in the rdbx, and a mutex
* should protect the rdbx between these calls if necessary. * should protect the rdbx between these calls if necessary.
*/ */
srtp_err_status_t srtp_rdbx_add_index(srtp_rdbx_t *rdbx, int delta);
err_status_t
rdbx_add_index(rdbx_t *rdbx, int delta);
/* /*
* rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx * 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 * to have the rollover counter value roc. If that value is less than
* the current rollover counter value, then the function returns * the current rollover counter value, then the function returns
* err_status_replay_old; otherwise, err_status_ok is returned. * 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);
err_status_t
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc);
/* /*
* rdbx_get_roc(rdbx) returns the value of the rollover counter for * srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter for
* the rdbx_t pointed to by rdbx * the srtp_rdbx_t pointed to by rdbx
* *
*/ */
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx);
xtd_seq_num_t
rdbx_get_packet_index(const rdbx_t *rdbx);
/* /*
* xtd_seq_num_t functions - these are *internal* functions of rdbx, and * srtp_xtd_seq_num_t functions - these are *internal* functions of rdbx, and
* shouldn't be used to manipulate rdbx internal values. use the rdbx * shouldn't be used to manipulate rdbx internal values. use the rdbx
* api instead! * api instead!
*/ */
/* /*
* rdbx_get_ws(rdbx_ptr) * srtp_rdbx_get_ws(rdbx_ptr)
* *
* gets the window size which was used to initialize the rdbx * gets the window size which was used to initialize the rdbx
*/ */
unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx);
unsigned long
rdbx_get_window_size(const rdbx_t *rdbx);
/* index_init(&pi) initializes a packet index pi (sets it to zero) */ /* index_init(&pi) initializes a packet index pi (sets it to zero) */
void srtp_index_init(srtp_xtd_seq_num_t *pi);
void
index_init(xtd_seq_num_t *pi);
/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */ /* 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);
void
index_advance(xtd_seq_num_t *pi, sequence_number_t s);
/* /*
* index_guess(local, guess, s) * srtp_index_guess(local, guess, s)
* *
* given a xtd_seq_num_t local (which represents the highest * given a srtp_xtd_seq_num_t local (which represents the highest
* known-to-be-good index) and a sequence number s (from a newly * known-to-be-good index) and a sequence number s (from a newly
* arrived packet), sets the contents of *guess to contain the best * arrived packet), sets the contents of *guess to contain the best
* guess of the packet index to which s corresponds, and returns the * guess of the packet index to which s corresponds, and returns the
* difference between *guess and *local * 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);
int /*
index_guess(const xtd_seq_num_t *local, * srtp_rdbx_get_roc(rdbx)
xtd_seq_num_t *guess, *
sequence_number_t s); * Get the current rollover counter
*
*/
uint32_t srtp_rdbx_get_roc(const srtp_rdbx_t *rdbx);
/*
* srtp_rdbx_set_roc_seq(rdbx, roc, seq) initalizes the srtp_rdbx_t at the
* location rdbx to have the rollover counter value roc and packet sequence
* number seq. If the new rollover counter value is less than the current
* 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);
#ifdef __cplusplus
}
#endif
#endif /* RDBX_H */ #endif /* RDBX_H */

View File

@ -9,26 +9,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -47,19 +47,31 @@
#ifndef SHA1_H #ifndef SHA1_H
#define SHA1_H #define SHA1_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h" #include "err.h"
#ifdef OPENSSL #ifdef OPENSSL
#include <openssl/evp.h> #include <openssl/evp.h>
#include <stdint.h>
#else
#include "datatypes.h"
#endif
typedef EVP_MD_CTX sha1_ctx_t; #ifdef __cplusplus
extern "C" {
#endif
#ifdef OPENSSL
/* /*
* sha1_init(&ctx) initializes the SHA1 context ctx * srtp_sha1_init(&ctx) initializes the SHA1 context ctx
* *
* sha1_update(&ctx, msg, len) hashes the len octets starting at msg * srtp_sha1_update(&ctx, msg, len) hashes the len octets starting at msg
* into the SHA1 context * into the SHA1 context
* *
* sha1_final(&ctx, output) performs the final processing of the SHA1 * srtp_sha1_final(&ctx, output) performs the final processing of the SHA1
* context and writes the result to the 20 octets at output * context and writes the result to the 20 octets at output
* *
* Return values are ignored on the EVP functions since all three * Return values are ignored on the EVP functions since all three
@ -67,81 +79,101 @@ typedef EVP_MD_CTX sha1_ctx_t;
* *
*/ */
static inline void sha1_init (sha1_ctx_t *ctx) /* 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
typedef EVP_MD_CTX srtp_sha1_ctx_t;
static inline void srtp_sha1_init (srtp_sha1_ctx_t *ctx)
{ {
EVP_MD_CTX_init(ctx); EVP_MD_CTX_init(ctx);
EVP_DigestInit(ctx, EVP_sha1()); EVP_DigestInit(ctx, EVP_sha1());
} }
static inline void sha1_update (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); EVP_DigestUpdate(ctx, M, octets_in_msg);
} }
static inline void sha1_final (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; 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;
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)
{
EVP_DigestUpdate(*ctx, M, octets_in_msg);
}
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_MD_CTX_free(*ctx);
}
#endif
#else #else
#include "datatypes.h"
typedef struct { typedef struct {
uint32_t H[5]; /* state vector */ uint32_t H[5]; /* state vector */
uint32_t M[16]; /* message buffer */ uint32_t M[16]; /* message buffer */
int octets_in_buffer; /* octets of message in buffer */ int octets_in_buffer; /* octets of message in buffer */
uint32_t num_bits_in_msg; /* total number of bits in message */ uint32_t num_bits_in_msg; /* total number of bits in message */
} sha1_ctx_t; } srtp_sha1_ctx_t;
/* /*
* sha1(&ctx, msg, len, output) hashes the len octets starting at msg * srtp_sha1_init(&ctx) initializes the SHA1 context ctx
* into the SHA1 context, then writes the result to the 20 octets at *
* output * srtp_sha1_update(&ctx, msg, len) hashes the len octets starting at msg
*
*/
void
sha1(const uint8_t *message, int octets_in_msg, uint32_t output[5]);
/*
* sha1_init(&ctx) initializes the SHA1 context ctx
*
* sha1_update(&ctx, msg, len) hashes the len octets starting at msg
* into the SHA1 context * into the SHA1 context
* *
* sha1_final(&ctx, output) performs the final processing of the SHA1 * srtp_sha1_final(&ctx, output) performs the final processing of the SHA1
* context and writes the result to the 20 octets at output * context and writes the result to the 20 octets at output
* *
*/ */
void srtp_sha1_init(srtp_sha1_ctx_t *ctx);
void void srtp_sha1_update(srtp_sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
sha1_init(sha1_ctx_t *ctx);
void void srtp_sha1_final(srtp_sha1_ctx_t * ctx, uint32_t output[5]);
sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
void
sha1_final(sha1_ctx_t *ctx, uint32_t output[5]);
/* /*
* The sha1_core function is INTERNAL to SHA-1, but it is declared * The srtp_sha1_core function is INTERNAL to SHA-1, but it is declared
* here because it is also used by the cipher SEAL 3.0 in its key * here because it is also used by the cipher SEAL 3.0 in its key
* setup algorithm. * setup algorithm.
*/ */
/* /*
* sha1_core(M, H) computes the core sha1 compression function, where M is * srtp_sha1_core(M, H) computes the core sha1 compression function, where M is
* the next part of the message and H is the intermediate state {H0, * the next part of the message and H is the intermediate state {H0,
* H1, ...} * H1, ...}
* *
* this function does not do any of the padding required in the * this function does not do any of the padding required in the
* complete sha1 function * complete sha1 function
*/ */
void srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
void
sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
#endif /* else OPENSSL */ #endif /* else OPENSSL */
#ifdef __cplusplus
}
#endif
#endif /* SHA1_H */ #endif /* SHA1_H */

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright(c) 2001-2006, Cisco Systems, Inc. * Copyright(c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,22 +48,20 @@
#define STAT_H #define STAT_H
#include "datatypes.h" /* for uint8_t */ #include "datatypes.h" /* for uint8_t */
#include "err.h" /* for err_status_t */ #include "err.h" /* for srtp_err_status_t */
#include "rand_source.h" /* for rand_source_func_t definition */
err_status_t #ifdef __cplusplus
stat_test_monobit(uint8_t *data); extern "C" {
#endif
err_status_t srtp_err_status_t stat_test_monobit(uint8_t *data);
stat_test_poker(uint8_t *data);
err_status_t srtp_err_status_t stat_test_poker(uint8_t *data);
stat_test_runs(uint8_t *data);
err_status_t srtp_err_status_t stat_test_runs(uint8_t *data);
stat_test_rand_source(rand_source_func_t rs);
err_status_t #ifdef __cplusplus
stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials); }
#endif
#endif /* STAT_H */ #endif /* STAT_H */

View File

@ -1,139 +0,0 @@
/*
* xfm.h
*
* interface for abstract crypto transform
*
* David A. McGrew
* Cisco Systems, Inc.
*/
#ifndef XFM_H
#define XFM_H
#include "crypto_kernel.h"
#include "err.h"
/**
* @defgroup Crypto Cryptography
*
* A simple interface to an abstract cryptographic transform that
* provides both confidentiality and message authentication.
*
* @{
*/
/**
* @brief applies a crypto transform
*
* The function pointer xfm_func_t points to a function that
* implements a crypto transform, and provides a uniform API for
* accessing crypto mechanisms.
*
* @param key location of secret key
*
* @param clear data to be authenticated only
*
* @param clear_len length of data to be authenticated only
*
* @param iv location to write the Initialization Vector (IV)
*
* @param protect location of the data to be encrypted and
* authenticated (before the function call), and the ciphertext
* and authentication tag (after the call)
*
* @param protected_len location of the length of the data to be
* encrypted and authenticated (before the function call), and the
* length of the ciphertext (after the call)
*
* @param auth_tag location to write auth tag
*/
typedef err_status_t (*xfm_func_t)
(void *key,
void *clear,
unsigned clear_len,
void *iv,
void *protect,
unsigned *protected_len,
void *auth_tag
);
typedef
err_status_t (*xfm_inv_t)
(void *key, /* location of secret key */
void *clear, /* data to be authenticated only */
unsigned clear_len, /* length of data to be authenticated only */
void *iv, /* location of iv */
void *opaque, /* data to be decrypted and authenticated */
unsigned *opaque_len, /* location of the length of data to be
* decrypted and authd (before and after)
*/
void *auth_tag /* location of auth tag */
);
typedef struct xfm_ctx_t {
xfm_func_t func;
xfm_inv_t inv;
unsigned key_len;
unsigned iv_len;
unsigned auth_tag_len;
} xfm_ctx_t;
typedef xfm_ctx_t *xfm_t;
#define xfm_get_key_len(xfm) ((xfm)->key_len)
#define xfm_get_iv_len(xfm) ((xfm)->iv_len)
#define xfm_get_auth_tag_len(xfm) ((xfm)->auth_tag_len)
/* cryptoalgo - 5/28 */
typedef err_status_t (*cryptoalg_func_t)
(void *key,
void *clear,
unsigned clear_len,
void *iv,
void *opaque,
unsigned *opaque_len
);
typedef
err_status_t (*cryptoalg_inv_t)
(void *key, /* location of secret key */
void *clear, /* data to be authenticated only */
unsigned clear_len, /* length of data to be authenticated only */
void *iv, /* location of iv */
void *opaque, /* data to be decrypted and authenticated */
unsigned *opaque_len /* location of the length of data to be
* decrypted and authd (before and after)
*/
);
typedef struct cryptoalg_ctx_t {
cryptoalg_func_t enc;
cryptoalg_inv_t dec;
unsigned key_len;
unsigned iv_len;
unsigned auth_tag_len;
unsigned max_expansion;
} cryptoalg_ctx_t;
typedef cryptoalg_ctx_t *cryptoalg_t;
#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)
#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)
#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)
/**
* @}
*/
#endif /* XFM_H */

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,35 +42,36 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "alloc.h" #include "alloc.h"
#include "crypto_kernel.h" #include "crypto_kernel.h"
/* the debug module for memory allocation */ /* the debug module for memory allocation */
debug_module_t mod_alloc = { srtp_debug_module_t mod_alloc = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
"alloc" /* printable name for module */ "alloc" /* printable name for module */
}; };
/* /*
* Nota bene: the debugging statements for crypto_alloc() and * Nota bene: the debugging statements for srtp_crypto_alloc() and
* crypto_free() have identical prefixes, which include the addresses * srtp_crypto_free() have identical prefixes, which include the addresses
* of the memory locations on which they are operating. This fact can * of the memory locations on which they are operating. This fact can
* be used to locate memory leaks, by turning on memory debugging, * be used to locate memory leaks, by turning on memory debugging,
* grepping for 'alloc', then matching alloc and free calls by * grepping for 'alloc', then matching alloc and free calls by
* address. * address.
*/ */
#ifdef SRTP_KERNEL_LINUX #if defined(HAVE_STDLIB_H)
#include <linux/interrupt.h> void * srtp_crypto_alloc(size_t size) {
void *
crypto_alloc(size_t size) {
void *ptr; void *ptr;
ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); ptr = malloc(size);
if (ptr) { if (ptr) {
debug_print(mod_alloc, "(location: %p) allocated", ptr); debug_print(mod_alloc, "(location: %p) allocated", ptr);
} else { } else {
@ -80,33 +81,7 @@ crypto_alloc(size_t size) {
return ptr; return ptr;
} }
void void srtp_crypto_free(void *ptr) {
crypto_free(void *ptr) {
debug_print(mod_alloc, "(location: %p) freed", ptr);
kfree(ptr);
}
#elif defined(HAVE_STDLIB_H)
void *
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);
return ptr;
}
void
crypto_free(void *ptr) {
debug_print(mod_alloc, "(location: %p) freed", ptr); debug_print(mod_alloc, "(location: %p) freed", ptr);

File diff suppressed because it is too large Load Diff

View File

@ -7,26 +7,26 @@
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright(c) 2001-2006 Cisco Systems, Inc. * Copyright(c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -42,107 +42,65 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "err.h" #include "err.h"
#include "datatypes.h"
#include <string.h>
#ifdef ERR_REPORTING_SYSLOG /* srtp_err_file is the FILE to which errors are reported */
# ifdef HAVE_SYSLOG_H
# include <syslog.h>
# endif
#endif
static FILE *srtp_err_file = NULL;
/* err_level reflects the level of errors that are reported */ srtp_err_status_t srtp_err_reporting_init ()
{
err_reporting_level_t err_level = err_level_none;
#ifdef SRTP_KERNEL_LINUX
err_status_t
err_reporting_init(char *ident) {
return err_status_ok;
}
#else /* SRTP_KERNEL_LINUX */
/* err_file is the FILE to which errors are reported */
static FILE *err_file = NULL;
err_status_t
err_reporting_init(char *ident) {
#ifdef ERR_REPORTING_SYSLOG
openlog(ident, LOG_PID, LOG_AUTHPRIV);
#endif
/*
* Believe it or not, openlog doesn't return an error on failure.
* But then, neither does the syslog() call...
*/
#ifdef ERR_REPORTING_STDOUT #ifdef ERR_REPORTING_STDOUT
err_file = stdout; srtp_err_file = stdout;
#elif defined(USE_ERR_REPORTING_FILE) #elif defined(ERR_REPORTING_FILE)
/* open file for error reporting */ /* open file for error reporting */
err_file = fopen(ERR_REPORTING_FILE, "w"); srtp_err_file = fopen(ERR_REPORTING_FILE, "w");
if (err_file == NULL) if (srtp_err_file == NULL) {
return err_status_init_fail; return srtp_err_status_init_fail;
#endif
return err_status_ok;
}
void
err_report(int priority, char *format, ...) {
va_list args;
if (priority <= err_level) {
va_start(args, format);
if (err_file != NULL) {
vfprintf(err_file, format, args);
/* fprintf(err_file, "\n"); */
} }
#ifdef ERR_REPORTING_SYSLOG
if (1) { /* FIXME: Make this a runtime option. */
int syslogpri;
switch (priority) {
case err_level_emergency:
syslogpri = LOG_EMERG;
break;
case err_level_alert:
syslogpri = LOG_ALERT;
break;
case err_level_critical:
syslogpri = LOG_CRIT;
break;
case err_level_error:
syslogpri = LOG_ERR;
break;
case err_level_warning:
syslogpri = LOG_WARNING;
break;
case err_level_notice:
syslogpri = LOG_NOTICE;
break;
case err_level_info:
syslogpri = LOG_INFO;
break;
case err_level_debug:
case err_level_none:
default:
syslogpri = LOG_DEBUG;
break;
}
vsyslog(syslogpri, format, args);
#endif #endif
va_end(args);
}
}
#endif /* SRTP_KERNEL_LINUX */
void return srtp_err_status_ok;
err_reporting_set_level(err_reporting_level_t lvl) { }
err_level = lvl;
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_report_handler = func;
return srtp_err_status_ok;
}
void srtp_err_report (srtp_err_reporting_level_t level, const char *format, ...)
{
va_list args;
if (srtp_err_file != NULL) {
va_start(args, format);
vfprintf(srtp_err_file, format, args);
va_end(args);
}
if (srtp_err_report_handler != NULL) {
va_start(args, format);
char msg[512];
if (vsnprintf(msg, sizeof(msg), format, args) > 0) {
/* strip trailing \n, callback should not have one */
size_t l = strlen(msg);
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
* call srtp_err_report() in the future, leading to recursion
*/
octet_string_set_to_zero(msg, sizeof(msg));
}
va_end(args);
}
} }

View File

@ -2,31 +2,31 @@
* key.c * key.c
* *
* key usage limits enforcement * key usage limits enforcement
* *
* David A. Mcgrew * David A. Mcgrew
* Cisco Systems, Inc. * Cisco Systems, Inc.
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -42,74 +42,79 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "key.h" #include "key.h"
#define soft_limit 0x10000 #define soft_limit 0x10000
err_status_t srtp_err_status_t srtp_key_limit_set (srtp_key_limit_t key, const srtp_xtd_seq_num_t s)
key_limit_set(key_limit_t key, const xtd_seq_num_t s) { {
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
if (high32(s) == 0 && low32(s) < soft_limit) if (high32(s) == 0 && low32(s) < soft_limit) {
return err_status_bad_param; return srtp_err_status_bad_param;
}
#else #else
if (s < soft_limit) if (s < soft_limit) {
return err_status_bad_param; return srtp_err_status_bad_param;
}
#endif #endif
key->num_left = s; key->num_left = s;
key->state = key_state_normal; key->state = srtp_key_state_normal;
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t srtp_key_limit_clone (srtp_key_limit_t original, srtp_key_limit_t *new_key)
key_limit_clone(key_limit_t original, key_limit_t *new_key) { {
if (original == NULL) if (original == NULL) {
return err_status_bad_param; return srtp_err_status_bad_param;
*new_key = original; }
return err_status_ok; *new_key = original;
return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t srtp_key_limit_check (const srtp_key_limit_t key)
key_limit_check(const key_limit_t key) { {
if (key->state == key_state_expired) if (key->state == srtp_key_state_expired) {
return err_status_key_expired; return srtp_err_status_key_expired;
return err_status_ok; }
return srtp_err_status_ok;
} }
key_event_t srtp_key_event_t srtp_key_limit_update (srtp_key_limit_t key)
key_limit_update(key_limit_t key) { {
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
if (low32(key->num_left) == 0) if (low32(key->num_left) == 0) {
{ // carry
// carry key->num_left = make64(high32(key->num_left) - 1, low32(key->num_left) - 1);
key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1); }else {
} // no carry
else key->num_left = make64(high32(key->num_left), low32(key->num_left) - 1);
{ }
// no carry if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {
key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1); return srtp_key_event_normal; /* we're above the soft limit */
} }
if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {
return key_event_normal; /* we're above the soft limit */
}
#else #else
key->num_left--; key->num_left--;
if (key->num_left >= soft_limit) { if (key->num_left >= soft_limit) {
return key_event_normal; /* we're above the soft limit */ return srtp_key_event_normal; /* we're above the soft limit */
} }
#endif #endif
if (key->state == key_state_normal) { if (key->state == srtp_key_state_normal) {
/* we just passed the soft limit, so change the state */ /* we just passed the soft limit, so change the state */
key->state = key_state_past_soft_limit; key->state = srtp_key_state_past_soft_limit;
} }
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
if (low32(key->num_left) == 0 && high32(key->num_left == 0)) if (low32(key->num_left) == 0 && high32(key->num_left == 0))
#else #else
if (key->num_left < 1) if (key->num_left < 1)
#endif #endif
{ /* we just hit the hard limit */ { /* we just hit the hard limit */
key->state = key_state_expired; key->state = srtp_key_state_expired;
return key_event_hard_limit; return srtp_key_event_hard_limit;
} }
return key_event_soft_limit; return srtp_key_event_soft_limit;
} }

View File

@ -9,7 +9,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,6 +43,14 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef OPENSSL
#include <openssl/crypto.h>
#endif
#include "datatypes.h" #include "datatypes.h"
int int
@ -98,14 +106,13 @@ octet_get_weight(uint8_t octet) {
char bit_string[MAX_PRINT_STRING_LEN]; char bit_string[MAX_PRINT_STRING_LEN];
uint8_t uint8_t
nibble_to_hex_char(uint8_t nibble) { srtp_nibble_to_hex_char(uint8_t nibble) {
char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
return buf[nibble & 0xF]; return buf[nibble & 0xF];
} }
char * char * srtp_octet_string_hex_string(const void *s, int length) {
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; int i;
@ -114,93 +121,23 @@ octet_string_hex_string(const void *s, int length) {
/* truncate string if it would be too long */ /* truncate string if it would be too long */
if (length > MAX_PRINT_STRING_LEN) if (length > MAX_PRINT_STRING_LEN)
length = MAX_PRINT_STRING_LEN-1; length = MAX_PRINT_STRING_LEN-2;
for (i=0; i < length; i+=2) { for (i=0; i < length; i+=2) {
bit_string[i] = nibble_to_hex_char(*str >> 4); bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF); bit_string[i+1] = srtp_nibble_to_hex_char(*str++ & 0xF);
} }
bit_string[i] = 0; /* null terminate string */ bit_string[i] = 0; /* null terminate string */
return bit_string; return bit_string;
} }
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 */
}
/* NOTREACHED */
#ifndef WIN32
return -1; /* this keeps compilers from complaining */
#endif
}
int
is_hex_string(char *s) {
while(*s != 0)
if (hex_char_to_nibble(*s++) == -1)
return 0;
return 1;
}
/*
* 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) {
uint8_t x;
int tmp;
int hex_len;
hex_len = 0;
while (hex_len < len) {
tmp = hex_char_to_nibble(hex[0]);
if (tmp == -1)
return hex_len;
x = (uint8_t)(tmp << 4);
hex_len++;
tmp = hex_char_to_nibble(hex[1]);
if (tmp == -1)
return hex_len;
x |= (tmp & 0xff);
hex_len++;
*raw++ = x;
hex += 2;
}
return hex_len;
}
char * char *
v128_hex_string(v128_t *x) { v128_hex_string(v128_t *x) {
int i, j; int i, j;
for (i=j=0; i < 16; i++) { for (i=j=0; i < 16; i++) {
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
} }
bit_string[j] = 0; /* null terminate string */ bit_string[j] = 0; /* null terminate string */
@ -427,7 +364,7 @@ bitvector_alloc(bitvector_t *v, unsigned long length) {
if (l == 0) if (l == 0)
v->word = NULL; v->word = NULL;
else { else {
v->word = (uint32_t*)crypto_alloc(l); v->word = (uint32_t*)srtp_crypto_alloc(l);
if (v->word == NULL) { if (v->word == NULL) {
v->word = NULL; v->word = NULL;
v->length = 0; v->length = 0;
@ -446,7 +383,7 @@ bitvector_alloc(bitvector_t *v, unsigned long length) {
void void
bitvector_dealloc(bitvector_t *v) { bitvector_dealloc(bitvector_t *v) {
if (v->word != NULL) if (v->word != NULL)
crypto_free(v->word); srtp_crypto_free(v->word);
v->word = NULL; v->word = NULL;
v->length = 0; v->length = 0;
} }
@ -507,214 +444,75 @@ bitvector_left_shift(bitvector_t *x, int shift) {
} }
int int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
uint8_t *end = b + 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) while (b < end)
if (*a++ != *b++) accumulator |= (*a++ ^ *b++);
return 1;
return 0; /* Return 1 if *not* equal. */
return accumulator != 0;
} }
void void
octet_string_set_to_zero(uint8_t *s, int len) { srtp_cleanse(void *s, size_t len)
uint8_t *end = s + len; {
volatile unsigned char *p = (volatile unsigned char *)s;
do { while(len--) *p++ = 0;
*s = 0;
} while (++s < end);
} }
void
/* octet_string_set_to_zero(void *s, size_t len)
* From RFC 1521: The Base64 Alphabet {
* #ifdef OPENSSL
* Value Encoding Value Encoding Value Encoding Value Encoding OPENSSL_cleanse(s, len);
* 0 A 17 R 34 i 51 z #else
* 1 B 18 S 35 j 52 0 srtp_cleanse(s, len);
* 2 C 19 T 36 k 53 1 #endif
* 3 D 20 U 37 l 54 2
* 4 E 21 V 38 m 55 3
* 5 F 22 W 39 n 56 4
* 6 G 23 X 40 o 57 5
* 7 H 24 Y 41 p 58 6
* 8 I 25 Z 42 q 59 7
* 9 J 26 a 43 r 60 8
* 10 K 27 b 44 s 61 9
* 11 L 28 c 45 t 62 +
* 12 M 29 d 46 u 63 /
* 13 N 30 e 47 v
* 14 O 31 f 48 w (pad) =
* 15 P 32 g 49 x
* 16 Q 33 h 50 y
*/
int
base64_char_to_sextet(uint8_t c) {
switch(c) {
case 'A':
return 0;
case 'B':
return 1;
case 'C':
return 2;
case 'D':
return 3;
case 'E':
return 4;
case 'F':
return 5;
case 'G':
return 6;
case 'H':
return 7;
case 'I':
return 8;
case 'J':
return 9;
case 'K':
return 10;
case 'L':
return 11;
case 'M':
return 12;
case 'N':
return 13;
case 'O':
return 14;
case 'P':
return 15;
case 'Q':
return 16;
case 'R':
return 17;
case 'S':
return 18;
case 'T':
return 19;
case 'U':
return 20;
case 'V':
return 21;
case 'W':
return 22;
case 'X':
return 23;
case 'Y':
return 24;
case 'Z':
return 25;
case 'a':
return 26;
case 'b':
return 27;
case 'c':
return 28;
case 'd':
return 29;
case 'e':
return 30;
case 'f':
return 31;
case 'g':
return 32;
case 'h':
return 33;
case 'i':
return 34;
case 'j':
return 35;
case 'k':
return 36;
case 'l':
return 37;
case 'm':
return 38;
case 'n':
return 39;
case 'o':
return 40;
case 'p':
return 41;
case 'q':
return 42;
case 'r':
return 43;
case 's':
return 44;
case 't':
return 45;
case 'u':
return 46;
case 'v':
return 47;
case 'w':
return 48;
case 'x':
return 49;
case 'y':
return 50;
case 'z':
return 51;
case '0':
return 52;
case '1':
return 53;
case '2':
return 54;
case '3':
return 55;
case '4':
return 56;
case '5':
return 57;
case '6':
return 58;
case '7':
return 59;
case '8':
return 60;
case '9':
return 61;
case '+':
return 62;
case '/':
return 63;
case '=':
return 64;
default:
break;
}
return -1;
} }
/* #ifdef TESTAPP_SOURCE
* base64_string_to_octet_string converts a hexadecimal string
* of length 2 * len to a raw octet string of length len
*/
int static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
base64_string_to_octet_string(char *raw, char *base64, int len) { "abcdefghijklmnopqrstuvwxyz0123456789+/";
uint8_t x;
int tmp;
int base64_len;
base64_len = 0; static int base64_block_to_octet_triple(char *out, char *in) {
while (base64_len < len) { unsigned char sextets[4] = {0};
tmp = base64_char_to_sextet(base64[0]); int j = 0;
if (tmp == -1) int i;
return base64_len;
x = (uint8_t)(tmp << 6); for (i = 0; i < 4; i++) {
base64_len++; char *p = strchr(b64chars, in[i]);
tmp = base64_char_to_sextet(base64[1]); if (p != NULL) sextets[i] = p - b64chars;
if (tmp == -1) else j++;
return base64_len;
x |= (tmp & 0xffff);
base64_len++;
*raw++ = x;
base64 += 2;
} }
return base64_len;
out[0] = (sextets[0]<<2)|(sextets[1]>>4);
if (j < 2) out[1] = (sextets[1]<<4)|(sextets[2]>>2);
if (j < 1) out[2] = (sextets[2]<<6)|sextets[3];
return j;
} }
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;
}
#endif

View File

@ -1,83 +0,0 @@
/*
* gf2_8.c
*
* GF(256) finite field implementation, with the representation used
* in the AES cipher.
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "datatypes.h"
#include "gf2_8.h"
/* gf2_8_shift() moved to gf2_8.h as an inline function */
gf2_8
gf2_8_multiply(gf2_8 x, gf2_8 y) {
gf2_8 z = 0;
if (y & 1) z ^= x; x = gf2_8_shift(x);
if (y & 2) z ^= x; x = gf2_8_shift(x);
if (y & 4) z ^= x; x = gf2_8_shift(x);
if (y & 8) z ^= x; x = gf2_8_shift(x);
if (y & 16) z ^= x; x = gf2_8_shift(x);
if (y & 32) z ^= x; x = gf2_8_shift(x);
if (y & 64) z ^= x; x = gf2_8_shift(x);
if (y & 128) z ^= x;
return z;
}
/* this should use the euclidean algorithm */
gf2_8
gf2_8_compute_inverse(gf2_8 x) {
unsigned int i;
if (x == 0) return 0; /* zero is a special case */
for (i=0; i < 256; i++)
if (gf2_8_multiply((gf2_8) i, x) == 1)
return (gf2_8) i;
return 0;
}

View File

@ -1,802 +0,0 @@
/*
* math.c
*
* crypto math operations and data types
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "crypto_math.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
};
int
low_bit[256] = {
-1, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
7, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0,
3, 0, 1, 0, 2, 0, 1, 0
};
int
high_bit[256] = {
-1, 0, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7
};
int
octet_get_weight(uint8_t octet) {
extern int octet_weight[256];
return octet_weight[octet];
}
unsigned char
v32_weight(v32_t a) {
unsigned int wt = 0;
wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */
wt += octet_weight[a.v8[1]];
wt += octet_weight[a.v8[2]];
wt += octet_weight[a.v8[3]];
return wt;
}
unsigned char
v32_distance(v32_t x, v32_t y) {
x.value ^= y.value;
return v32_weight(x);
}
unsigned int
v32_dot_product(v32_t a, v32_t b) {
a.value &= b.value;
return v32_weight(a) & 1;
}
/*
* _bit_string returns a NULL-terminated character string suitable for
* printing
*/
#define MAX_STRING_LENGTH 1024
char bit_string[MAX_STRING_LENGTH];
char *
octet_bit_string(uint8_t x) {
int mask, index;
for (mask = 1, index = 0; mask < 256; mask <<= 1)
if ((x & mask) == 0)
bit_string[index++] = '0';
else
bit_string[index++] = '1';
bit_string[index++] = 0; /* NULL terminate string */
return bit_string;
}
char *
v16_bit_string(v16_t x) {
int i, mask, index;
for (i = index = 0; i < 2; i++) {
for (mask = 1; mask < 256; mask <<= 1)
if ((x.v8[i] & mask) == 0)
bit_string[index++] = '0';
else
bit_string[index++] = '1';
}
bit_string[index++] = 0; /* NULL terminate string */
return bit_string;
}
char *
v32_bit_string(v32_t x) {
int i, mask, index;
for (i = index = 0; i < 4; i++) {
for (mask = 128; mask > 0; mask >>= 1)
if ((x.v8[i] & mask) == 0)
bit_string[index++] = '0';
else
bit_string[index++] = '1';
}
bit_string[index++] = 0; /* NULL terminate string */
return bit_string;
}
char *
v64_bit_string(const v64_t *x) {
int i, mask, index;
for (i = index = 0; i < 8; i++) {
for (mask = 1; mask < 256; mask <<= 1)
if ((x->v8[i] & mask) == 0)
bit_string[index++] = '0';
else
bit_string[index++] = '1';
}
bit_string[index++] = 0; /* NULL terminate string */
return bit_string;
}
char *
v128_bit_string(v128_t *x) {
int j, index;
uint32_t mask;
for (j=index=0; j < 4; j++) {
for (mask=0x80000000; mask > 0; mask >>= 1) {
if (x->v32[j] & mask)
bit_string[index] = '1';
else
bit_string[index] = '0';
++index;
}
}
bit_string[128] = 0; /* null terminate string */
return bit_string;
}
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' };
return buf[nibble & 0xF];
}
char *
octet_hex_string(uint8_t x) {
bit_string[0] = nibble_to_hex_char(x >> 4);
bit_string[1] = nibble_to_hex_char(x & 0xF);
bit_string[2] = 0; /* null terminate string */
return bit_string;
}
char *
octet_string_hex_string(const void *str, int length) {
const uint8_t *s = str;
int i;
/* double length, since one octet takes two hex characters */
length *= 2;
/* truncate string if it would be too long */
if (length > MAX_STRING_LENGTH)
length = MAX_STRING_LENGTH-1;
for (i=0; i < length; i+=2) {
bit_string[i] = nibble_to_hex_char(*s >> 4);
bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF);
}
bit_string[i] = 0; /* null terminate string */
return bit_string;
}
char *
v16_hex_string(v16_t x) {
int i, j;
for (i=j=0; i < 2; i++) {
bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *
v32_hex_string(v32_t x) {
int i, j;
for (i=j=0; i < 4; i++) {
bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *
v64_hex_string(const v64_t *x) {
int i, j;
for (i=j=0; i < 8; i++) {
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *
v128_hex_string(v128_t *x) {
int i, j;
for (i=j=0; i < 16; i++) {
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
char *
char_to_hex_string(char *x, int num_char) {
int i, j;
if (num_char >= 16)
num_char = 16;
for (i=j=0; i < num_char; i++) {
bit_string[j++] = nibble_to_hex_char(x[i] >> 4);
bit_string[j++] = nibble_to_hex_char(x[i] & 0xF);
}
bit_string[j] = 0; /* null terminate string */
return bit_string;
}
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 */
}
/* NOTREACHED */
return -1; /* this keeps compilers from complaining */
}
int
is_hex_string(char *s) {
while(*s != 0)
if (hex_char_to_nibble(*s++) == -1)
return 0;
return 1;
}
uint8_t
hex_string_to_octet(char *s) {
uint8_t x;
x = (hex_char_to_nibble(s[0]) << 4)
| hex_char_to_nibble(s[1] & 0xFF);
return x;
}
/*
* 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) {
uint8_t x;
int tmp;
int hex_len;
hex_len = 0;
while (hex_len < len) {
tmp = hex_char_to_nibble(hex[0]);
if (tmp == -1)
return hex_len;
x = (tmp << 4);
hex_len++;
tmp = hex_char_to_nibble(hex[1]);
if (tmp == -1)
return hex_len;
x |= (tmp & 0xff);
hex_len++;
*raw++ = x;
hex += 2;
}
return hex_len;
}
v16_t
hex_string_to_v16(char *s) {
v16_t x;
int i, j;
for (i=j=0; i < 4; i += 2, j++) {
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
| hex_char_to_nibble(s[i+1] & 0xFF);
}
return x;
}
v32_t
hex_string_to_v32(char *s) {
v32_t x;
int i, j;
for (i=j=0; i < 8; i += 2, j++) {
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
| hex_char_to_nibble(s[i+1] & 0xFF);
}
return x;
}
v64_t
hex_string_to_v64(char *s) {
v64_t x;
int i, j;
for (i=j=0; i < 16; i += 2, j++) {
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
| hex_char_to_nibble(s[i+1] & 0xFF);
}
return x;
}
v128_t
hex_string_to_v128(char *s) {
v128_t x;
int i, j;
for (i=j=0; i < 32; i += 2, j++) {
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
| hex_char_to_nibble(s[i+1] & 0xFF);
}
return x;
}
/*
* the matrix A[] is stored in column format, i.e., A[i] is the ith
* column of the matrix
*/
uint8_t
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
int index = 0;
unsigned mask;
for (mask=1; mask < 256; mask *= 2) {
if (x & mask)
b^= A[index];
++index;
}
return b;
}
void
v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
x->v8[0] = s[0];
x->v8[1] = s[1];
}
void
v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
x->v8[0] = s[0];
x->v8[1] = s[1];
x->v8[2] = s[2];
x->v8[3] = s[3];
}
void
v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
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];
}
void
v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
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];
}
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
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_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_or(v128_t *z, v128_t *x, v128_t *y) {
_v128_or(z, x, y);
}
void
v128_complement(v128_t *x) {
_v128_complement(x);
}
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);
}
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 */
static inline void
v128_left_shift2(v128_t *x, int num_bits) {
int i;
int word_shift = num_bits >> 5;
int bit_shift = num_bits & 31;
for (i=0; i < (4-word_shift); i++) {
x->v32[i] = x->v32[i+word_shift] << bit_shift;
}
for ( ; i < word_shift; i++) {
x->v32[i] = 0;
}
}
void
v128_right_shift(v128_t *x, int index) {
const int base_index = index >> 5;
const int bit_index = index & 31;
int i, from;
uint32_t b;
if (index > 127) {
v128_set_to_zero(x);
return;
}
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 index) {
int i;
const int base_index = index >> 5;
const int bit_index = index & 31;
if (index > 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;
}
/* now wrap up the final portion */
for (i = 4 - base_index; i < 4; i++)
x->v32[i] = 0;
}
#if 0
void
v128_add(v128_t *z, v128_t *x, v128_t *y) {
/* integer addition modulo 2^128 */
#ifdef WORDS_BIGENDIAN
uint64_t tmp;
tmp = x->v32[3] + y->v32[3];
z->v32[3] = (uint32_t) tmp;
tmp = x->v32[2] + y->v32[2] + (tmp >> 32);
z->v32[2] = (uint32_t) tmp;
tmp = x->v32[1] + y->v32[1] + (tmp >> 32);
z->v32[1] = (uint32_t) tmp;
tmp = x->v32[0] + y->v32[0] + (tmp >> 32);
z->v32[0] = (uint32_t) tmp;
#else /* assume little endian architecture */
uint64_t tmp;
tmp = htonl(x->v32[3]) + htonl(y->v32[3]);
z->v32[3] = ntohl((uint32_t) tmp);
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32);
z->v32[2] = ntohl((uint32_t) tmp);
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32);
z->v32[1] = ntohl((uint32_t) tmp);
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32);
z->v32[0] = ntohl((uint32_t) tmp);
#endif /* WORDS_BIGENDIAN */
}
#endif
int
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
uint8_t *end = b + len;
while (b < end)
if (*a++ != *b++)
return 1;
return 0;
}
void
octet_string_set_to_zero(uint8_t *s, int len) {
uint8_t *end = s + len;
do {
*s = 0;
} while (++s < end);
}
/* functions below not yet tested! */
int
v32_low_bit(v32_t *w) {
int value;
value = low_bit[w->v8[0]];
if (value != -1)
return value;
value = low_bit[w->v8[1]];
if (value != -1)
return value + 8;
value = low_bit[w->v8[2]];
if (value != -1)
return value + 16;
value = low_bit[w->v8[3]];
if (value == -1)
return -1;
return value + 24;
}
/* high_bit not done yet */

View File

@ -1,15 +1,55 @@
/* /*
* stats.c * stats.c
* *
* statistical tests for randomness (FIPS 140-2, Section 4.9) * statistical tests
* *
* David A. McGrew * David A. McGrew
* Cisco Systems, Inc. * 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
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "stat.h" #include "stat.h"
debug_module_t mod_stat = { srtp_debug_module_t mod_stat = {
0, /* debugging is off by default */ 0, /* debugging is off by default */
(char *)"stat test" /* printable module name */ (char *)"stat test" /* printable module name */
}; };
@ -21,26 +61,26 @@ debug_module_t mod_stat = {
#define STAT_TEST_DATA_LEN 2500 #define STAT_TEST_DATA_LEN 2500
err_status_t srtp_err_status_t
stat_test_monobit(uint8_t *data) { stat_test_monobit(uint8_t *data) {
uint8_t *data_end = data + STAT_TEST_DATA_LEN; uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t ones_count; uint16_t ones_count;
ones_count = 0; ones_count = 0;
while (data < data_end) { while (data < data_end) {
ones_count += (uint16_t)octet_get_weight(*data); ones_count += octet_get_weight(*data);
data++; data++;
} }
debug_print(mod_stat, "bit count: %d", ones_count); debug_print(mod_stat, "bit count: %d", ones_count);
if ((ones_count < 9725) || (ones_count > 10275)) if ((ones_count < 9725) || (ones_count > 10275))
return err_status_algo_fail; return srtp_err_status_algo_fail;
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t
stat_test_poker(uint8_t *data) { stat_test_poker(uint8_t *data) {
int i; int i;
uint8_t *data_end = data + STAT_TEST_DATA_LEN; uint8_t *data_end = data + STAT_TEST_DATA_LEN;
@ -66,9 +106,9 @@ stat_test_poker(uint8_t *data) {
debug_print(mod_stat, "poker test: %f\n", poker); debug_print(mod_stat, "poker test: %f\n", poker);
if ((poker < 2.16) || (poker > 46.17)) if ((poker < 2.16) || (poker > 46.17))
return err_status_algo_fail; return srtp_err_status_algo_fail;
return err_status_ok; return srtp_err_status_ok;
} }
@ -76,7 +116,7 @@ stat_test_poker(uint8_t *data) {
* runs[i] holds the number of runs of size (i-1) * runs[i] holds the number of runs of size (i-1)
*/ */
err_status_t srtp_err_status_t
stat_test_runs(uint8_t *data) { stat_test_runs(uint8_t *data) {
uint8_t *data_end = data + STAT_TEST_DATA_LEN; uint8_t *data_end = data + STAT_TEST_DATA_LEN;
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
@ -107,7 +147,7 @@ stat_test_runs(uint8_t *data) {
/* check for long runs */ /* check for long runs */
if (state > 25) { if (state > 25) {
debug_print(mod_stat, ">25 runs: %d", state); debug_print(mod_stat, ">25 runs: %d", state);
return err_status_algo_fail; return srtp_err_status_algo_fail;
} }
} else if (state < 0) { } else if (state < 0) {
@ -115,7 +155,7 @@ stat_test_runs(uint8_t *data) {
/* prefix is a gap */ /* prefix is a gap */
if (state < -25) { if (state < -25) {
debug_print(mod_stat, ">25 gaps: %d", state); debug_print(mod_stat, ">25 gaps: %d", state);
return err_status_algo_fail; /* long-runs test failed */ return srtp_err_status_algo_fail; /* long-runs test failed */
} }
if (state < -6) { if (state < -6) {
state = -6; /* group together gaps > 5 */ state = -6; /* group together gaps > 5 */
@ -135,7 +175,7 @@ stat_test_runs(uint8_t *data) {
/* prefix is a run */ /* prefix is a run */
if (state > 25) { if (state > 25) {
debug_print(mod_stat, ">25 runs (2): %d", state); debug_print(mod_stat, ">25 runs (2): %d", state);
return err_status_algo_fail; /* long-runs test failed */ return srtp_err_status_algo_fail; /* long-runs test failed */
} }
if (state > 6) { if (state > 6) {
state = 6; /* group together runs > 5 */ state = 6; /* group together runs > 5 */
@ -150,7 +190,7 @@ stat_test_runs(uint8_t *data) {
/* check for long gaps */ /* check for long gaps */
if (state < -25) { if (state < -25) {
debug_print(mod_stat, ">25 gaps (2): %d", state); debug_print(mod_stat, ">25 gaps (2): %d", state);
return err_status_algo_fail; return srtp_err_status_algo_fail;
} }
} else { } else {
@ -177,191 +217,10 @@ stat_test_runs(uint8_t *data) {
for (i=0; i < 6; i++) for (i=0; i < 6; i++)
if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
return err_status_algo_fail; return srtp_err_status_algo_fail;
return err_status_ok; return srtp_err_status_ok;
} }
/*
* the function stat_test_rand_source applys the FIPS-140-2 statistical
* tests to the random source defined by rs
*
*/
#define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */
err_status_t
stat_test_rand_source(rand_source_func_t get_rand_bytes) {
int i;
double poker;
uint8_t *data, *data_end;
uint16_t f[16] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
uint8_t buffer[RAND_SRC_BUF_OCTETS];
err_status_t status;
int ones_count = 0;
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;
/* counters for monobit, poker, and runs tests are initialized above */
/* main loop: fill buffer, update counters for stat tests */
for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) {
/* fill data buffer */
status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS);
if (status) {
debug_print(mod_stat, "couldn't get rand bytes: %d",status);
return status;
}
#if 0
debug_print(mod_stat, "%s",
octet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS));
#endif
data = buffer;
data_end = data + RAND_SRC_BUF_OCTETS;
while (data < data_end) {
/* update monobit test counter */
ones_count += octet_get_weight(*data);
/* update poker test counters */
f[*data & 0x0f]++; /* increment freq. count for low nibble */
f[(*data) >> 4]++; /* increment freq. count for high nibble */
/* update runs test counters */
/* 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++;
/* check for long runs */
if (state > 25) {
debug_print(mod_stat, ">25 runs (3): %d", state);
return err_status_algo_fail;
}
} else if (state < 0) {
/* prefix is a gap */
if (state < -25) {
debug_print(mod_stat, ">25 gaps (3): %d", state);
return 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(mod_stat, ">25 runs (4): %d", state);
return 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 (4): %d", state);
return err_status_algo_fail;
}
} else {
/* state is zero; this happens only at initialization */
state = -1;
}
}
}
/* advance data pointer */
data++;
}
}
/* check to see if test data is within bounds */
/* check monobit test data */
debug_print(mod_stat, "stat: bit count: %d", ones_count);
if ((ones_count < 9725) || (ones_count > 10275)) {
debug_print(mod_stat, "stat: failed monobit test %d", ones_count);
return err_status_algo_fail;
}
/* check poker test data */
poker = 0.0;
for (i=0; i < 16; i++)
poker += (double) f[i] * f[i];
poker *= (16.0 / 5000.0);
poker -= 5000.0;
debug_print(mod_stat, "stat: poker test: %f", poker);
if ((poker < 2.16) || (poker > 46.17)) {
debug_print(mod_stat, "stat: failed poker test", NULL);
return 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])) {
debug_print(mod_stat, "stat: failed run/gap test", NULL);
return err_status_algo_fail;
}
debug_print(mod_stat, "passed random stat test", NULL);
return err_status_ok;
}
err_status_t
stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) {
unsigned int i;
err_status_t err = err_status_algo_fail;
for (i=0; i < num_trials; i++) {
err = stat_test_rand_source(source);
if (err == err_status_ok) {
return err_status_ok;
}
debug_print(mod_stat, "failed stat test (try number %d)\n", i);
}
return err;
}

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -44,94 +44,100 @@
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "rdb.h" #include "rdb.h"
/* /*
* this implementation of a replay database works as follows: * this implementation of a replay database works as follows:
* *
* window_start is the index of the first packet in the window * window_start is the index of the first packet in the window
* bitmask a bit-buffer, containing the most recently entered * bitmask a bit-buffer, containing the most recently entered
* index as the leftmost bit * index as the leftmost bit
* *
*/ */
/* rdb_init initalizes rdb */ /* srtp_rdb_init initalizes rdb */
srtp_err_status_t srtp_rdb_init (srtp_rdb_t *rdb)
err_status_t {
rdb_init(rdb_t *rdb) { v128_set_to_zero(&rdb->bitmask);
v128_set_to_zero(&rdb->bitmask); rdb->window_start = 0;
rdb->window_start = 0; return srtp_err_status_ok;
return err_status_ok;
} }
/* /*
* rdb_check checks to see if index appears in 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)
{
err_status_t /* if the index appears after (or at very end of) the window, its good */
rdb_check(const rdb_t *rdb, uint32_t p_index) { if (p_index >= rdb->window_start + rdb_bits_in_bitmask) {
return srtp_err_status_ok;
/* 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 err_status_ok;
/* if the index appears before the window, its bad */
if (p_index < rdb->window_start)
return err_status_replay_old;
/* otherwise, the index appears within the window, so check the bitmask */ /* if the index appears before the window, its bad */
if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) if (p_index < rdb->window_start) {
return err_status_replay_fail; return srtp_err_status_replay_old;
}
/* otherwise, the index is okay */
return err_status_ok; /* otherwise, the index appears within the window, so check the bitmask */
if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) {
return srtp_err_status_replay_fail;
}
/* otherwise, the index is okay */
return srtp_err_status_ok;
} }
/* /*
* rdb_add_index adds index to rdb_t (and does *not* check if * srtp_rdb_add_index adds index to srtp_rdb_t (and does *not* check if
* index appears in db) * index appears in db)
* *
* this function should be called only after rdb_check has * this function should be called only after srtp_rdb_check has
* indicated that the index does not appear in the rdb, e.g., a mutex * indicated that the index does not appear in the rdb, e.g., a mutex
* should protect the rdb between these calls * should protect the rdb between these calls
*/ */
srtp_err_status_t srtp_rdb_add_index (srtp_rdb_t *rdb, uint32_t p_index)
{
int delta;
err_status_t /* here we *assume* that p_index > rdb->window_start */
rdb_add_index(rdb_t *rdb, uint32_t p_index) {
int delta;
/* here we *assume* that p_index > rdb->window_start */ delta = (p_index - rdb->window_start);
if (delta < rdb_bits_in_bitmask) {
delta = (p_index - rdb->window_start); /* if the p_index is within the window, set the appropriate bit */
if (delta < rdb_bits_in_bitmask) { v128_set_bit(&rdb->bitmask, delta);
/* if the p_index is within the window, set the appropriate bit */ } else {
v128_set_bit(&rdb->bitmask, delta);
} else { delta -= rdb_bits_in_bitmask - 1;
delta -= rdb_bits_in_bitmask - 1;
/* shift the window forward by delta bits*/ /* shift the window forward by delta bits*/
v128_left_shift(&rdb->bitmask, delta); v128_left_shift(&rdb->bitmask, delta);
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1); v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask - 1);
rdb->window_start += delta; rdb->window_start += delta;
} }
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t srtp_rdb_increment (srtp_rdb_t *rdb)
rdb_increment(rdb_t *rdb) { {
if (rdb->window_start++ > 0x7fffffff) if (rdb->window_start >= 0x7fffffff) {
return err_status_key_expired; return srtp_err_status_key_expired;
return err_status_ok; }
++rdb->window_start;
return srtp_err_status_ok;
} }
uint32_t uint32_t srtp_rdb_get_value (const srtp_rdb_t *rdb)
rdb_get_value(const rdb_t *rdb) { {
return rdb->window_start; return rdb->window_start;
} }

View File

@ -8,26 +8,26 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* *
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following * copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided * disclaimer in the documentation and/or other materials provided
* with the distribution. * with the distribution.
* *
* Neither the name of the Cisco Systems, Inc. nor the names of its * Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived * contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@ -43,6 +43,10 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "rdbx.h" #include "rdbx.h"
@ -65,111 +69,109 @@
/* /*
* rdbx implementation notes * rdbx implementation notes
* *
* A xtd_seq_num_t is essentially a sequence number for which some of * A srtp_xtd_seq_num_t is essentially a sequence number for which some of
* the data on the wire are implicit. It logically consists of a * the data on the wire are implicit. It logically consists of a
* rollover counter and a sequence number; the sequence number is the * rollover counter and a sequence number; the sequence number is the
* explicit part, and the rollover counter is the implicit part. * explicit part, and the rollover counter is the implicit part.
* *
* Upon receiving a sequence_number (e.g. in a newly received SRTP * Upon receiving a sequence_number (e.g. in a newly received SRTP
* packet), the complete xtd_seq_num_t can be estimated by using a * packet), the complete srtp_xtd_seq_num_t can be estimated by using a
* local xtd_seq_num_t as a basis. This is done using the function * local srtp_xtd_seq_num_t as a basis. This is done using the function
* index_guess(&local, &guess, seq_from_packet). This function * srtp_index_guess(&local, &guess, seq_from_packet). This function
* returns the difference of the guess and the local value. The local * returns the difference of the guess and the local value. The local
* xtd_seq_num_t can be moved forward to the guess using the function * srtp_xtd_seq_num_t can be moved forward to the guess using the function
* index_advance(&guess, delta), where delta is the difference. * srtp_index_advance(&guess, delta), where delta is the difference.
*
* *
* A rdbx_t consists of a xtd_seq_num_t and a bitmask. The index is highest *
* 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 * sequence number that has been received, and the bitmask indicates
* which of the recent indicies have been received as well. The * which of the recent indicies have been received as well. The
* highest bit in the bitmask corresponds to the index in the bitmask. * highest bit in the bitmask corresponds to the index in the bitmask.
*/ */
void void srtp_index_init (srtp_xtd_seq_num_t *pi)
index_init(xtd_seq_num_t *pi) { {
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
*pi = make64(0,0); *pi = make64(0, 0);
#else #else
*pi = 0; *pi = 0;
#endif #endif
} }
void void srtp_index_advance (srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
index_advance(xtd_seq_num_t *pi, sequence_number_t s) { {
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
/* a > ~b means a+b will generate a carry */ /* a > ~b means a+b will generate a carry */
/* s is uint16 here */ /* s is uint16 here */
*pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s); *pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0), low32(*pi) + s);
#else #else
*pi += s; *pi += s;
#endif #endif
} }
/* /*
* index_guess(local, guess, s) * srtp_index_guess(local, guess, s)
* *
* given a xtd_seq_num_t local (which represents the last * given a srtp_xtd_seq_num_t local (which represents the last
* known-to-be-good received xtd_seq_num_t) and a sequence number s * known-to-be-good received srtp_xtd_seq_num_t) and a sequence number s
* (from a newly arrived packet), sets the contents of *guess to * (from a newly arrived packet), sets the contents of *guess to
* contain the best guess of the packet index to which s corresponds, * contain the best guess of the packet index to which s corresponds,
* and returns the difference between *guess and *local * and returns the difference between *guess and *local
* *
* nota bene - the output is a signed integer, DON'T cast it to a * nota bene - the output is a signed integer, DON'T cast it to a
* unsigned integer! * unsigned integer!
*/ */
int int32_t srtp_index_guess (const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s)
index_guess(const xtd_seq_num_t *local, {
xtd_seq_num_t *guess,
sequence_number_t s) {
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
uint32_t local_roc = ((high32(*local) << 16) | uint32_t local_roc = ((high32(*local) << 16) |
(low32(*local) >> 16)); (low32(*local) >> 16));
uint16_t local_seq = (uint16_t) (low32(*local)); uint16_t local_seq = (uint16_t)(low32(*local));
#else #else
uint32_t local_roc = (uint32_t)(*local >> 16); uint32_t local_roc = (uint32_t)(*local >> 16);
uint16_t local_seq = (uint16_t) *local; uint16_t local_seq = (uint16_t)*local;
#endif #endif
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
uint32_t guess_roc = ((high32(*guess) << 16) | uint32_t guess_roc = ((high32(*guess) << 16) |
(low32(*guess) >> 16)); (low32(*guess) >> 16));
uint16_t guess_seq = (uint16_t) (low32(*guess)); uint16_t guess_seq = (uint16_t)(low32(*guess));
#else #else
uint32_t guess_roc = (uint32_t)(*guess >> 16); uint32_t guess_roc = (uint32_t)(*guess >> 16);
uint16_t guess_seq = (uint16_t) *guess; uint16_t guess_seq = (uint16_t)*guess;
#endif #endif
int difference; int32_t difference;
if (local_seq < seq_num_median) { if (local_seq < seq_num_median) {
if (s - local_seq > seq_num_median) { if (s - local_seq > seq_num_median) {
guess_roc = local_roc - 1; guess_roc = local_roc - 1;
difference = s - local_seq - seq_num_max; difference = s - local_seq - seq_num_max;
} else {
guess_roc = local_roc;
difference = s - local_seq;
}
} else { } else {
guess_roc = local_roc; if (local_seq - seq_num_median > s) {
difference = s - local_seq; guess_roc = local_roc + 1;
difference = s - local_seq + seq_num_max;
} else {
guess_roc = local_roc;
difference = s - local_seq;
}
} }
} else { guess_seq = s;
if (local_seq - seq_num_median > s) {
guess_roc = local_roc + 1; /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
difference = s - local_seq + seq_num_max;
} else {
guess_roc = local_roc;
difference = s - local_seq;
}
}
guess_seq = s;
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
*guess = make64(guess_roc >> 16, *guess = make64(guess_roc >> 16,
(guess_roc << 16) | guess_seq); (guess_roc << 16) | guess_seq);
#else #else
*guess = (((uint64_t) guess_roc) << 16) | guess_seq; *guess = (((uint64_t)guess_roc) << 16) | guess_seq;
#endif #endif
return difference; return difference;
} }
/* /*
@ -179,174 +181,216 @@ index_guess(const xtd_seq_num_t *local,
/* /*
* rdbx_init(&r, ws) initializes the 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)
{
if (ws == 0) {
return srtp_err_status_bad_param;
}
err_status_t if (bitvector_alloc(&rdbx->bitmask, ws) != 0) {
rdbx_init(rdbx_t *rdbx, unsigned long ws) { return srtp_err_status_alloc_fail;
if (ws == 0) }
return err_status_bad_param;
if (bitvector_alloc(&rdbx->bitmask, ws) != 0) srtp_index_init(&rdbx->index);
return err_status_alloc_fail;
index_init(&rdbx->index); return srtp_err_status_ok;
return err_status_ok;
} }
/* /*
* rdbx_dealloc(&r) frees memory for the rdbx_t pointed to by r * 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)
{
bitvector_dealloc(&rdbx->bitmask);
err_status_t return srtp_err_status_ok;
rdbx_dealloc(rdbx_t *rdbx) {
bitvector_dealloc(&rdbx->bitmask);
return err_status_ok;
} }
/* /*
* rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx * 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 * to have the rollover counter value roc. If that value is less than
* the current rollover counter value, then the function returns * the current rollover counter value, then the function returns
* err_status_replay_old; otherwise, err_status_ok is returned. * 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)
err_status_t {
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) { bitvector_set_to_zero(&rdbx->bitmask);
bitvector_set_to_zero(&rdbx->bitmask);
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
#error not yet implemented #error not yet implemented
#else #else
/* make sure that we're not moving backwards */ /* make sure that we're not moving backwards */
if (roc < (rdbx->index >> 16)) if (roc < (rdbx->index >> 16)) {
return err_status_replay_old; return srtp_err_status_replay_old;
}
rdbx->index &= 0xffff; /* retain lowest 16 bits */ rdbx->index &= 0xffff; /* retain lowest 16 bits */
rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */ rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
#endif #endif
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
* rdbx_get_packet_index(rdbx) returns the value of the packet index * srtp_rdbx_get_packet_index(rdbx) returns the value of the packet index
* for the rdbx_t pointed to by rdbx * for the srtp_rdbx_t pointed to by rdbx
* *
*/ */
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index (const srtp_rdbx_t *rdbx)
xtd_seq_num_t {
rdbx_get_packet_index(const rdbx_t *rdbx) { return rdbx->index;
return rdbx->index;
} }
/* /*
* rdbx_get_window_size(rdbx) returns the value of the window size * srtp_rdbx_get_window_size(rdbx) returns the value of the window size
* for the rdbx_t pointed to by rdbx * for the srtp_rdbx_t pointed to by rdbx
* *
*/ */
unsigned long srtp_rdbx_get_window_size (const srtp_rdbx_t *rdbx)
unsigned long {
rdbx_get_window_size(const rdbx_t *rdbx) { return bitvector_get_length(&rdbx->bitmask);
return bitvector_get_length(&rdbx->bitmask);
} }
/* /*
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t * 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 * which is at rdbx->index + delta is in the rdb
*/ */
srtp_err_status_t srtp_rdbx_check (const srtp_rdbx_t *rdbx, int delta)
{
err_status_t if (delta > 0) { /* if delta is positive, it's good */
rdbx_check(const rdbx_t *rdbx, int delta) { return srtp_err_status_ok;
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
if (delta > 0) { /* if delta is positive, it's good */ /* if delta is lower than the bitmask, it's bad */
return err_status_ok; return srtp_err_status_replay_old;
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) { } else if (bitvector_get_bit(&rdbx->bitmask,
/* if delta is lower than the bitmask, it's bad */ (int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
return err_status_replay_old; /* delta is within the window, so check the bitmask */
} else if (bitvector_get_bit(&rdbx->bitmask, return srtp_err_status_replay_fail;
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) { }
/* delta is within the window, so check the bitmask */ /* otherwise, the index is okay */
return err_status_replay_fail;
}
/* otherwise, the index is okay */
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
* rdbx_add_index adds the xtd_seq_num_t at rdbx->window_start + d to * srtp_rdbx_add_index adds the srtp_xtd_seq_num_t at rdbx->window_start + d to
* replay_db (and does *not* check if that xtd_seq_num_t appears in db) * replay_db (and does *not* check if that srtp_xtd_seq_num_t appears in db)
* *
* this function should be called only after replay_check has * this function should be called only after replay_check has
* indicated that the index does not appear in the rdbx, e.g., a mutex * indicated that the index does not appear in the rdbx, e.g., a mutex
* should protect the rdbx between these calls if need be * should protect the rdbx between these calls if need be
*/ */
srtp_err_status_t srtp_rdbx_add_index (srtp_rdbx_t *rdbx, int delta)
{
err_status_t if (delta > 0) {
rdbx_add_index(rdbx_t *rdbx, int delta) { /* shift forward by delta */
srtp_index_advance(&rdbx->index, delta);
if (delta > 0) { bitvector_left_shift(&rdbx->bitmask, delta);
/* shift forward by delta */ bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
index_advance(&rdbx->index, (sequence_number_t)delta); } else {
bitvector_left_shift(&rdbx->bitmask, delta); /* delta is in window */
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1); bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1 + delta);
} else { }
/* delta is in window */
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
}
/* note that we need not consider the case that delta == 0 */ /* note that we need not consider the case that delta == 0 */
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
* rdbx_estimate_index(rdbx, guess, s) * srtp_rdbx_estimate_index(rdbx, guess, s)
* *
* given an rdbx and a sequence number s (from a newly arrived packet), * given an rdbx and a sequence number s (from a newly arrived packet),
* sets the contents of *guess to contain the best guess of the packet * sets the contents of *guess to contain the best guess of the packet
* index to which s corresponds, and returns the difference between * index to which s corresponds, and returns the difference between
* *guess and the locally stored synch info * *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)
{
int /*
rdbx_estimate_index(const rdbx_t *rdbx, * if the sequence number and rollover counter in the rdbx are
xtd_seq_num_t *guess, * non-zero, then use the srtp_index_guess(...) function, otherwise, just
sequence_number_t s) { * 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 index_guess(...) function, otherwise, just
* set the rollover counter to zero (since the index_guess(...)
* function might incorrectly guess that the rollover counter is
* 0xffffffff)
*/
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
/* seq_num_median = 0x8000 */ /* seq_num_median = 0x8000 */
if (high32(rdbx->index) > 0 || if (high32(rdbx->index) > 0 ||
low32(rdbx->index) > seq_num_median) low32(rdbx->index) > seq_num_median)
#else #else
if (rdbx->index > seq_num_median) if (rdbx->index > seq_num_median)
#endif #endif
return index_guess(&rdbx->index, guess, s); { return srtp_index_guess(&rdbx->index, guess, s); }
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
*guess = make64(0,(uint32_t) s); *guess = make64(0, (uint32_t)s);
#else #else
*guess = s; *guess = s;
#endif #endif
#ifdef NO_64BIT_MATH #ifdef NO_64BIT_MATH
return s - (uint16_t) low32(rdbx->index); return s - (uint16_t)low32(rdbx->index);
#else #else
return s - (uint16_t) rdbx->index; return s - (uint16_t)rdbx->index;
#endif #endif
} }
/*
* srtp_rdbx_get_roc(rdbx)
*
* Get the current rollover counter
*
*/
uint32_t srtp_rdbx_get_roc(const srtp_rdbx_t *rdbx)
{
uint32_t roc;
#ifdef NO_64BIT_MATH
roc = ((high32(rdbx->index) << 16) | (low32(rdbx->index) >> 16));
#else
roc = (uint32_t)(rdbx->index >> 16);
#endif
return roc;
}
/*
* srtp_rdbx_set_roc_seq(rdbx, roc, seq) initalizes the srtp_rdbx_t at the
* location rdbx to have the rollover counter value roc and packet sequence
* number seq. If the new rollover counter value is less than the current
* 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)
{
#ifdef NO_64BIT_MATH
#error not yet implemented
#else
/* make sure that we're not moving backwards */
if (roc < (rdbx->index >> 16)) {
return srtp_err_status_replay_old;
}
rdbx->index = seq;
rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
#endif
bitvector_set_to_zero(&rdbx->bitmask);
return srtp_err_status_ok;
}

View File

@ -10,7 +10,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -45,6 +45,10 @@
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "ut_sim.h" #include "ut_sim.h"

View File

@ -1,110 +0,0 @@
/*
* ctr_prng.c
*
* counter mode based pseudorandom source
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright(c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "prng.h"
/* single, global prng structure */
ctr_prng_t ctr_prng;
err_status_t
ctr_prng_init(rand_source_func_t random_source) {
uint8_t tmp_key[32];
err_status_t status;
/* initialize output count to zero */
ctr_prng.octet_count = 0;
/* set random source */
ctr_prng.rand = random_source;
/* initialize secret key from random source */
status = random_source(tmp_key, 32);
if (status)
return status;
/* initialize aes ctr context with random key */
#ifdef OPENSSL
status = aes_icm_openssl_context_init(&ctr_prng.state, tmp_key, 30);
#else
status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30);
#endif
if (status)
return status;
return err_status_ok;
}
err_status_t
ctr_prng_get_octet_string(void *dest, uint32_t len) {
err_status_t status;
/*
* if we need to re-initialize the prng, do so now
*/
if ((aes_icm_bytes_encrypted(&ctr_prng.state) + len) > 0xffff) {
status = ctr_prng_init(ctr_prng.rand);
if (status)
return status;
}
ctr_prng.octet_count += len;
/*
* write prng output
*/
status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len);
if (status)
return status;
return err_status_ok;
}
err_status_t
ctr_prng_deinit(void) {
/* nothing */
return err_status_ok;
}

View File

@ -1,180 +0,0 @@
/*
* prng.c
*
* pseudorandom source
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright(c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "prng.h"
/* single, global prng structure */
x917_prng_t x917_prng;
err_status_t
x917_prng_init(rand_source_func_t random_source) {
uint8_t tmp_key[16];
err_status_t status;
/* initialize output count to zero */
x917_prng.octet_count = 0;
/* set random source */
x917_prng.rand = random_source;
/* initialize secret key from random source */
status = random_source(tmp_key, 16);
if (status)
return status;
/* expand aes key */
aes_expand_encryption_key(tmp_key, 16, &x917_prng.key);
/* initialize prng state from random source */
status = x917_prng.rand((uint8_t *)&x917_prng.state, 16);
if (status)
return status;
return err_status_ok;
}
err_status_t
x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
uint32_t t;
v128_t buffer;
uint32_t i, tail_len;
err_status_t status;
/*
* if we need to re-initialize the prng, do so now
*
* avoid overflows by subtracting instead of adding
*/
if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
status = x917_prng_init(x917_prng.rand);
if (status)
return status;
}
x917_prng.octet_count += len;
/* find out the time */
t = (uint32_t)time(NULL);
/* loop until we have output enough data */
for (i=0; i < len/16; i++) {
/* exor time into state */
x917_prng.state.v32[0] ^= t;
/* copy state into buffer */
v128_copy(&buffer, &x917_prng.state);
/* apply aes to buffer */
aes_encrypt(&buffer, &x917_prng.key);
/* write data to output */
*dest++ = buffer.v8[0];
*dest++ = buffer.v8[1];
*dest++ = buffer.v8[2];
*dest++ = buffer.v8[3];
*dest++ = buffer.v8[4];
*dest++ = buffer.v8[5];
*dest++ = buffer.v8[6];
*dest++ = buffer.v8[7];
*dest++ = buffer.v8[8];
*dest++ = buffer.v8[9];
*dest++ = buffer.v8[10];
*dest++ = buffer.v8[11];
*dest++ = buffer.v8[12];
*dest++ = buffer.v8[13];
*dest++ = buffer.v8[14];
*dest++ = buffer.v8[15];
/* exor time into buffer */
buffer.v32[0] ^= t;
/* encrypt buffer */
aes_encrypt(&buffer, &x917_prng.key);
/* copy buffer into state */
v128_copy(&x917_prng.state, &buffer);
}
/* if we need to output any more octets, we'll do so now */
tail_len = len % 16;
if (tail_len) {
/* exor time into state */
x917_prng.state.v32[0] ^= t;
/* copy value into buffer */
v128_copy(&buffer, &x917_prng.state);
/* apply aes to buffer */
aes_encrypt(&buffer, &x917_prng.key);
/* write data to output */
for (i=0; i < tail_len; i++) {
*dest++ = buffer.v8[i];
}
/* now update the state one more time */
/* exor time into buffer */
buffer.v32[0] ^= t;
/* encrypt buffer */
aes_encrypt(&buffer, &x917_prng.key);
/* copy buffer into state */
v128_copy(&x917_prng.state, &buffer);
}
return err_status_ok;
}
err_status_t
x917_prng_deinit(void) {
return err_status_ok;
}

View File

@ -1,65 +0,0 @@
/*
* rand_linux_kernel.c
*
* implements a random source using Linux kernel functions
*
* Marcus Sundberg
* Ingate Systems AB
*/
/*
*
* Copyright(c) 2005 Ingate Systems AB
* 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 author(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "rand_source.h"
err_status_t
rand_source_init(void) {
return err_status_ok;
}
err_status_t
rand_source_get_octet_string(void *dest, uint32_t len) {
get_random_bytes(dest, len);
return err_status_ok;
}
err_status_t
rand_source_deinit(void) {
return err_status_ok;
}

View File

@ -1,158 +0,0 @@
/*
* rand_source.c
*
* implements a random source based on /dev/random
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright(c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#ifdef DEV_URANDOM
# include <fcntl.h> /* for open() */
# include <unistd.h> /* for close() */
#elif defined(HAVE_RAND_S)
# define _CRT_RAND_S
# include <stdlib.h>
#else
# include <stdio.h>
#endif
#include "rand_source.h"
/*
* global dev_rand_fdes is file descriptor for /dev/random
*
* This variable is also used to indicate that the random source has
* been initialized. When this variable is set to the value of the
* #define RAND_SOURCE_NOT_READY, it indicates that the random source
* is not ready to be used. The value of the #define
* RAND_SOURCE_READY is for use whenever that variable is used as an
* indicator of the state of the random source, but not as a file
* descriptor.
*/
#define RAND_SOURCE_NOT_READY (-1)
#define RAND_SOURCE_READY (17)
static int dev_random_fdes = RAND_SOURCE_NOT_READY;
err_status_t
rand_source_init(void) {
if (dev_random_fdes >= 0) {
/* already open */
return err_status_ok;
}
#ifdef DEV_URANDOM
/* open random source for reading */
dev_random_fdes = open(DEV_URANDOM, O_RDONLY);
if (dev_random_fdes < 0)
return err_status_init_fail;
#elif defined(HAVE_RAND_S)
dev_random_fdes = RAND_SOURCE_READY;
#else
/* no random source available; let the user know */
fprintf(stderr, "WARNING: no real random source present!\n");
dev_random_fdes = RAND_SOURCE_READY;
#endif
return err_status_ok;
}
err_status_t
rand_source_get_octet_string(void *dest, uint32_t len) {
/*
* read len octets from /dev/random to dest, and
* check return value to make sure enough octets were
* written
*/
#ifdef DEV_URANDOM
uint8_t *dst = (uint8_t *)dest;
while (len)
{
ssize_t num_read = read(dev_random_fdes, dst, len);
if (num_read <= 0 || num_read > len)
return err_status_fail;
len -= num_read;
dst += num_read;
}
#elif defined(HAVE_RAND_S)
uint8_t *dst = (uint8_t *)dest;
while (len)
{
unsigned int val;
errno_t err = rand_s(&val);
if (err != 0)
return 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--;
}
#endif
return err_status_ok;
}
err_status_t
rand_source_deinit(void) {
if (dev_random_fdes < 0)
return err_status_dealloc_fail; /* well, we haven't really failed, *
* but there is something wrong */
#ifdef DEV_URANDOM
close(dev_random_fdes);
#endif
dev_random_fdes = RAND_SOURCE_NOT_READY;
return err_status_ok;
}

View File

@ -1,8 +0,0 @@
aes_calc
cipher_driver
datatypes_driver
env
kernel_driver
rand_gen
sha1_driver
stat_driver

View File

@ -7,6 +7,42 @@
* Cisco Systems, Inc. * 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
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* /*
Example usage (with first NIST FIPS 197 test case): Example usage (with first NIST FIPS 197 test case):
@ -18,9 +54,14 @@
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "aes.h" #include "aes.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "util.h"
void void
usage(char *prog_name) { usage(char *prog_name) {
@ -34,10 +75,10 @@ int
main (int argc, char *argv[]) { main (int argc, char *argv[]) {
v128_t data; v128_t data;
uint8_t key[AES_MAX_KEY_LEN]; uint8_t key[AES_MAX_KEY_LEN];
aes_expanded_key_t exp_key; srtp_aes_expanded_key_t exp_key;
int key_len, len; int key_len, len;
int verbose = 0; int verbose = 0;
err_status_t status; srtp_err_status_t status;
if (argc == 3) { if (argc == 3) {
/* we're not in verbose mode */ /* we're not in verbose mode */
@ -98,14 +139,14 @@ main (int argc, char *argv[]) {
} }
/* encrypt plaintext */ /* encrypt plaintext */
status = aes_expand_encryption_key(key, key_len, &exp_key); status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
if (status) { if (status) {
fprintf(stderr, fprintf(stderr,
"error: AES key expansion failed.\n"); "error: AES key expansion failed.\n");
exit(1); exit(1);
} }
aes_encrypt(&data, &exp_key); srtp_aes_encrypt(&data, &exp_key);
/* write ciphertext to output */ /* write ciphertext to output */
if (verbose) { if (verbose) {

View File

@ -1,200 +0,0 @@
/*
* auth_driver.c
*
* a driver for auth functions
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright (c) 2001-2006, Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h> /* for printf() */
#include <stdlib.h> /* for xalloc() */
#include <unistd.h> /* for getopt() */
#include "auth.h"
#include "null_auth.h"
#define PRINT_DEBUG_DATA 0
extern auth_type_t tmmhv2;
const uint16_t msg0[9] = {
0x6015, 0xf141, 0x5ba1, 0x29a0, 0xf604, 0xd1c, 0x2d9, 0xaa8a, 0x7931
};
/* key1 is for TAG_WORDS = 2 */
const uint16_t key1[47] = {
0xe627, 0x6a01, 0x5ea7, 0xf27a, 0xc536, 0x2192, 0x11be, 0xea35,
0xdb9d, 0x63d6, 0xfa8a, 0xfc45, 0xe08b, 0xd216, 0xced2, 0x7853,
0x1a82, 0x22f5, 0x90fb, 0x1c29, 0x708e, 0xd06f, 0x82c3, 0xbee6,
0x4f21, 0x6f33, 0x65c0, 0xd211, 0xc25e, 0x9138, 0x4fa3, 0x7c1f,
0x61ac, 0x3489, 0x2976, 0x8c19, 0x8252, 0xddbf, 0xcad3, 0xc28f,
0x68d6, 0x58dd, 0x504f, 0x2bbf, 0x0278, 0x70b7, 0xcfca
};
double
auth_bits_per_second(auth_t *h, int msg_len);
void
usage(char *prog_name) {
printf("usage: %s [ -t | -v ]\n", prog_name);
exit(255);
}
#define MAX_MSG_LEN 2048
int
main (int argc, char *argv[]) {
auth_t *a = NULL;
err_status_t status;
int i;
int c;
unsigned do_timing_test = 0;
unsigned do_validation = 0;
/* process input arguments */
while (1) {
c = getopt(argc, argv, "tv");
if (c == -1)
break;
switch (c) {
case 't':
do_timing_test = 1;
break;
case 'v':
do_validation = 1;
break;
default:
usage(argv[0]);
}
}
printf("auth driver\nDavid A. McGrew\nCisco Systems, Inc.\n");
if (!do_validation && !do_timing_test)
usage(argv[0]);
if (do_validation) {
printf("running self-test for %s...", tmmhv2.description);
status = tmmhv2_add_big_test();
if (status) {
printf("tmmhv2_add_big_test failed with error code %d\n", status);
exit(status);
}
status = auth_type_self_test(&tmmhv2);
if (status) {
printf("failed with error code %d\n", status);
exit(status);
}
printf("passed\n");
}
if (do_timing_test) {
/* tmmhv2 timing test */
status = auth_type_alloc(&tmmhv2, &a, 94, 4);
if (status) {
fprintf(stderr, "can't allocate tmmhv2\n");
exit(status);
}
status = auth_init(a, (uint8_t *)key1);
if (status) {
printf("error initializaing auth function\n");
exit(status);
}
printf("timing %s (tag length %d)\n",
tmmhv2.description, auth_get_tag_length(a));
for (i=8; i <= MAX_MSG_LEN; i *= 2)
printf("msg len: %d\tgigabits per second: %f\n",
i, auth_bits_per_second(a, i) / 1E9);
status = auth_dealloc(a);
if (status) {
printf("error deallocating auth function\n");
exit(status);
}
}
return 0;
}
#define NUM_TRIALS 100000
#include <time.h>
double
auth_bits_per_second(auth_t *a, int msg_len_octets) {
int i;
clock_t timer;
uint8_t *result;
int msg_len = (msg_len_octets + 1)/2;
uint16_t *msg_string;
/* create random message */
msg_string = (uint16_t *) crypto_alloc(msg_len_octets);
if (msg_string == NULL)
return 0.0; /* indicate failure */
for (i=0; i < msg_len; i++)
msg_string[i] = (uint16_t) random();
/* allocate temporary storage for authentication tag */
result = crypto_alloc(auth_get_tag_length(a));
if (result == NULL) {
free(msg_string);
return 0.0; /* indicate failure */
}
timer = clock();
for (i=0; i < NUM_TRIALS; i++) {
auth_compute(a, (uint8_t *)msg_string, msg_len_octets, (uint8_t *)result);
}
timer = clock() - timer;
free(msg_string);
free(result);
return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer;
}

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,10 +43,14 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> /* for printf() */ #include <stdio.h> /* for printf() */
#include <stdlib.h> /* for rand() */ #include <stdlib.h> /* for rand() */
#include <string.h> /* for memset() */ #include <string.h> /* for memset() */
#include <unistd.h> /* for getopt() */ #include "getopt_s.h"
#include "cipher.h" #include "cipher.h"
#ifdef OPENSSL #ifdef OPENSSL
#include "aes_icm_ossl.h" #include "aes_icm_ossl.h"
@ -54,15 +58,14 @@
#else #else
#include "aes_icm.h" #include "aes_icm.h"
#endif #endif
#include "null_cipher.h"
#define PRINT_DEBUG 0 #define PRINT_DEBUG 0
void void
cipher_driver_test_throughput(cipher_t *c); cipher_driver_test_throughput(srtp_cipher_t *c);
err_status_t srtp_err_status_t
cipher_driver_self_test(cipher_type_t *ct); cipher_driver_self_test(srtp_cipher_type_t *ct);
/* /*
@ -71,30 +74,30 @@ cipher_driver_self_test(cipher_type_t *ct);
* calls * calls
*/ */
err_status_t srtp_err_status_t
cipher_driver_test_buffering(cipher_t *c); cipher_driver_test_buffering(srtp_cipher_t *c);
/* /*
* functions for testing cipher cache thrash * functions for testing cipher cache thrash
*/ */
err_status_t srtp_err_status_t
cipher_driver_test_array_throughput(cipher_type_t *ct, cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen, int num_cipher); int klen, int num_cipher);
void void
cipher_array_test_throughput(cipher_t *ca[], int num_cipher); cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
uint64_t uint64_t
cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, cipher_array_bits_per_second(srtp_cipher_t *cipher_array[], int num_cipher,
unsigned octets_in_buffer, int num_trials); unsigned octets_in_buffer, int num_trials);
err_status_t srtp_err_status_t
cipher_array_delete(cipher_t *cipher_array[], int num_cipher); cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher);
err_status_t srtp_err_status_t
cipher_array_alloc_init(cipher_t ***cipher_array, int num_ciphers, cipher_array_alloc_init(srtp_cipher_t ***cipher_array, int num_ciphers,
cipher_type_t *ctype, int klen); srtp_cipher_type_t *ctype, int klen);
void void
usage(char *prog_name) { usage(char *prog_name) {
@ -103,7 +106,7 @@ usage(char *prog_name) {
} }
void void
check_status(err_status_t s) { check_status(srtp_err_status_t s) {
if (s) { if (s) {
printf("error (code %d)\n", s); printf("error (code %d)\n", s);
exit(s); exit(s);
@ -112,26 +115,24 @@ check_status(err_status_t s) {
} }
/* /*
* null_cipher, aes_icm, and aes_cbc are the cipher meta-objects * null_cipher and srtp_aes_icm are the cipher meta-objects
* defined in the files in crypto/cipher subdirectory. these are * defined in the files in crypto/cipher subdirectory. these are
* declared external so that we can use these cipher types here * declared external so that we can use these cipher types here
*/ */
extern cipher_type_t null_cipher; extern srtp_cipher_type_t srtp_null_cipher;
extern cipher_type_t aes_icm; extern srtp_cipher_type_t srtp_aes_icm_128;
#ifndef OPENSSL extern srtp_cipher_type_t srtp_aes_icm_256;
extern cipher_type_t aes_cbc; #ifdef OPENSSL
#else extern srtp_cipher_type_t srtp_aes_icm_192;
extern cipher_type_t aes_icm_192; extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern cipher_type_t aes_icm_256; extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
extern cipher_type_t aes_gcm_128_openssl;
extern cipher_type_t aes_gcm_256_openssl;
#endif #endif
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
cipher_t *c = NULL; srtp_cipher_t *c = NULL;
err_status_t status; srtp_err_status_t status;
unsigned char test_key[48] = { unsigned char test_key[48] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@ -147,7 +148,7 @@ main(int argc, char *argv[]) {
/* process input arguments */ /* process input arguments */
while (1) { while (1) {
q = getopt(argc, argv, "tva"); q = getopt_s(argc, argv, "tva");
if (q == -1) if (q == -1)
break; break;
switch (q) { switch (q) {
@ -164,7 +165,7 @@ main(int argc, char *argv[]) {
usage(argv[0]); usage(argv[0]);
} }
} }
printf("cipher test driver\n" printf("cipher test driver\n"
"David A. McGrew\n" "David A. McGrew\n"
"Cisco Systems, Inc.\n"); "Cisco Systems, Inc.\n");
@ -178,55 +179,44 @@ main(int argc, char *argv[]) {
int num_cipher; int num_cipher;
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher); cipher_driver_test_array_throughput(&srtp_null_cipher, 0, num_cipher);
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher); cipher_driver_test_array_throughput(&srtp_aes_icm_128, SRTP_AES_ICM_128_KEY_LEN_WSALT, num_cipher);
#ifndef OPENSSL
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher);
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher); cipher_driver_test_array_throughput(&srtp_aes_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher);
#else
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_icm_192, 38, num_cipher);
#ifdef OPENSSL
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
cipher_driver_test_array_throughput(&aes_icm_256, 46, num_cipher); 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) { for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) {
cipher_driver_test_array_throughput(&aes_gcm_128_openssl, AES_128_GCM_KEYSIZE_WSALT, num_cipher); 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) { for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) {
cipher_driver_test_array_throughput(&aes_gcm_256_openssl, AES_256_GCM_KEYSIZE_WSALT, num_cipher); cipher_driver_test_array_throughput(&srtp_aes_gcm_256_openssl, SRTP_AES_GCM_256_KEY_LEN_WSALT, num_cipher);
} }
#endif #endif
} }
if (do_validation) { if (do_validation) {
cipher_driver_self_test(&null_cipher); cipher_driver_self_test(&srtp_null_cipher);
cipher_driver_self_test(&aes_icm); cipher_driver_self_test(&srtp_aes_icm_128);
#ifndef OPENSSL cipher_driver_self_test(&srtp_aes_icm_256);
cipher_driver_self_test(&aes_cbc); #ifdef OPENSSL
#else cipher_driver_self_test(&srtp_aes_icm_192);
cipher_driver_self_test(&aes_icm_192); cipher_driver_self_test(&srtp_aes_gcm_128_openssl);
cipher_driver_self_test(&aes_icm_256); cipher_driver_self_test(&srtp_aes_gcm_256_openssl);
cipher_driver_self_test(&aes_gcm_128_openssl);
cipher_driver_self_test(&aes_gcm_256_openssl);
#endif #endif
} }
/* do timing and/or buffer_test on null_cipher */ /* do timing and/or buffer_test on srtp_null_cipher */
status = cipher_type_alloc(&null_cipher, &c, 0, 0); status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
check_status(status); check_status(status);
status = cipher_init(c, NULL); status = srtp_cipher_init(c, NULL);
check_status(status); check_status(status);
if (do_timing_test) if (do_timing_test)
@ -235,18 +225,18 @@ main(int argc, char *argv[]) {
status = cipher_driver_test_buffering(c); status = cipher_driver_test_buffering(c);
check_status(status); check_status(status);
} }
status = cipher_dealloc(c); status = srtp_cipher_dealloc(c);
check_status(status); check_status(status);
/* run the throughput test on the aes_icm cipher (128-bit key) */ /* run the throughput test on the aes_icm cipher (128-bit key) */
status = cipher_type_alloc(&aes_icm, &c, 30, 0); status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c, SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
if (status) { if (status) {
fprintf(stderr, "error: can't allocate cipher\n"); fprintf(stderr, "error: can't allocate cipher\n");
exit(status); exit(status);
} }
status = cipher_init(c, test_key); status = srtp_cipher_init(c, test_key);
check_status(status); check_status(status);
if (do_timing_test) if (do_timing_test)
@ -257,21 +247,17 @@ main(int argc, char *argv[]) {
check_status(status); check_status(status);
} }
status = cipher_dealloc(c); status = srtp_cipher_dealloc(c);
check_status(status); check_status(status);
/* repeat the tests with 256-bit keys */ /* repeat the tests with 256-bit keys */
#ifndef OPENSSL status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
status = cipher_type_alloc(&aes_icm, &c, 46, 0);
#else
status = cipher_type_alloc(&aes_icm_256, &c, 46, 0);
#endif
if (status) { if (status) {
fprintf(stderr, "error: can't allocate cipher\n"); fprintf(stderr, "error: can't allocate cipher\n");
exit(status); exit(status);
} }
status = cipher_init(c, test_key); status = srtp_cipher_init(c, test_key);
check_status(status); check_status(status);
if (do_timing_test) if (do_timing_test)
@ -282,17 +268,17 @@ main(int argc, char *argv[]) {
check_status(status); check_status(status);
} }
status = cipher_dealloc(c); status = srtp_cipher_dealloc(c);
check_status(status); check_status(status);
#ifdef OPENSSL #ifdef OPENSSL
/* run the throughput test on the aes_gcm_128_openssl cipher */ /* run the throughput test on the aes_gcm_128_openssl cipher */
status = cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8); status = srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c, SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
if (status) { if (status) {
fprintf(stderr, "error: can't allocate GCM 128 cipher\n"); fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
exit(status); exit(status);
} }
status = cipher_init(c, test_key); status = srtp_cipher_init(c, test_key);
check_status(status); check_status(status);
if (do_timing_test) { if (do_timing_test) {
cipher_driver_test_throughput(c); cipher_driver_test_throughput(c);
@ -302,16 +288,16 @@ main(int argc, char *argv[]) {
status = cipher_driver_test_buffering(c); status = cipher_driver_test_buffering(c);
check_status(status); check_status(status);
} }
status = cipher_dealloc(c); status = srtp_cipher_dealloc(c);
check_status(status); check_status(status);
/* run the throughput test on the aes_gcm_256_openssl cipher */ /* run the throughput test on the aes_gcm_256_openssl cipher */
status = cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16); status = srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c, SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
if (status) { if (status) {
fprintf(stderr, "error: can't allocate GCM 256 cipher\n"); fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
exit(status); exit(status);
} }
status = cipher_init(c, test_key); status = srtp_cipher_init(c, test_key);
check_status(status); check_status(status);
if (do_timing_test) { if (do_timing_test) {
cipher_driver_test_throughput(c); cipher_driver_test_throughput(c);
@ -321,7 +307,7 @@ main(int argc, char *argv[]) {
status = cipher_driver_test_buffering(c); status = cipher_driver_test_buffering(c);
check_status(status); check_status(status);
} }
status = cipher_dealloc(c); status = srtp_cipher_dealloc(c);
check_status(status); check_status(status);
#endif #endif
@ -329,7 +315,7 @@ main(int argc, char *argv[]) {
} }
void void
cipher_driver_test_throughput(cipher_t *c) { cipher_driver_test_throughput(srtp_cipher_t *c) {
int i; int i;
int min_enc_len = 32; int min_enc_len = 32;
int max_enc_len = 2048; /* should be a power of two */ int max_enc_len = 2048; /* should be a power of two */
@ -339,23 +325,23 @@ cipher_driver_test_throughput(cipher_t *c) {
fflush(stdout); fflush(stdout);
for (i=min_enc_len; i <= max_enc_len; i = i * 2) for (i=min_enc_len; i <= max_enc_len; i = i * 2)
printf("msg len: %d\tgigabits per second: %f\n", printf("msg len: %d\tgigabits per second: %f\n",
i, cipher_bits_per_second(c, i, num_trials) / 1e9); i, srtp_cipher_bits_per_second(c, i, num_trials) / 1e9);
} }
err_status_t srtp_err_status_t
cipher_driver_self_test(cipher_type_t *ct) { cipher_driver_self_test(srtp_cipher_type_t *ct) {
err_status_t status; srtp_err_status_t status;
printf("running cipher self-test for %s...", ct->description); printf("running cipher self-test for %s...", ct->description);
status = cipher_type_self_test(ct); status = srtp_cipher_type_self_test(ct);
if (status) { if (status) {
printf("failed with error code %d\n", status); printf("failed with error code %d\n", status);
exit(status); exit(status);
} }
printf("passed\n"); printf("passed\n");
return err_status_ok; return srtp_err_status_ok;
} }
/* /*
@ -364,16 +350,17 @@ cipher_driver_self_test(cipher_type_t *ct) {
* calls * calls
*/ */
err_status_t #define INITIAL_BUFLEN 1024
cipher_driver_test_buffering(cipher_t *c) { srtp_err_status_t
cipher_driver_test_buffering(srtp_cipher_t *c) {
int i, j, num_trials = 1000; int i, j, num_trials = 1000;
unsigned len, buflen = 1024; unsigned len, buflen = INITIAL_BUFLEN;
uint8_t buffer0[buflen], buffer1[buflen], *current, *end; uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
uint8_t idx[16] = { uint8_t idx[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34
}; };
err_status_t status; srtp_err_status_t status;
printf("testing output buffering for cipher %s...", printf("testing output buffering for cipher %s...",
c->type->description); c->type->description);
@ -381,21 +368,22 @@ cipher_driver_test_buffering(cipher_t *c) {
for (i=0; i < num_trials; i++) { for (i=0; i < num_trials; i++) {
/* set buffers to zero */ /* set buffers to zero */
for (j=0; j < buflen; j++) for (j=0; j < (int) buflen; j++) {
buffer0[j] = buffer1[j] = 0; buffer0[j] = buffer1[j] = 0;
}
/* initialize cipher */ /* initialize cipher */
status = cipher_set_iv(c, idx, direction_encrypt); status = srtp_cipher_set_iv(c, (uint8_t*)idx, srtp_direction_encrypt);
if (status) if (status)
return status; return status;
/* generate 'reference' value by encrypting all at once */ /* generate 'reference' value by encrypting all at once */
status = cipher_encrypt(c, buffer0, &buflen); status = srtp_cipher_encrypt(c, buffer0, &buflen);
if (status) if (status)
return status; return status;
/* re-initialize cipher */ /* re-initialize cipher */
status = cipher_set_iv(c, idx, direction_encrypt); status = srtp_cipher_set_iv(c, (uint8_t*)idx, srtp_direction_encrypt);
if (status) if (status)
return status; return status;
@ -411,7 +399,7 @@ cipher_driver_test_buffering(cipher_t *c) {
if (current + len > end) if (current + len > end)
len = end - current; len = end - current;
status = cipher_encrypt(c, current, &len); status = srtp_cipher_encrypt(c, current, &len);
if (status) if (status)
return status; return status;
@ -424,20 +412,21 @@ cipher_driver_test_buffering(cipher_t *c) {
} }
/* compare buffers */ /* compare buffers */
for (j=0; j < buflen; j++) for (j=0; j < (int) buflen; j++) {
if (buffer0[j] != buffer1[j]) { if (buffer0[j] != buffer1[j]) {
#if PRINT_DEBUG #if PRINT_DEBUG
printf("test case %d failed at byte %d\n", i, j); printf("test case %d failed at byte %d\n", i, j);
printf("computed: %s\n", octet_string_hex_string(buffer1, buflen)); printf("computed: %s\n", octet_string_hex_string(buffer1, buflen));
printf("expected: %s\n", octet_string_hex_string(buffer0, buflen)); printf("expected: %s\n", octet_string_hex_string(buffer0, buflen));
#endif #endif
return err_status_algo_fail; return srtp_err_status_algo_fail;
} }
}
} }
printf("passed\n"); printf("passed\n");
return err_status_ok; return srtp_err_status_ok;
} }
@ -446,40 +435,40 @@ cipher_driver_test_buffering(cipher_t *c) {
* cache thrash on cipher throughput. * cache thrash on cipher throughput.
* *
* cipher_array_alloc_init(ctype, array, num_ciphers) creates an array * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
* of cipher_t of type ctype * of srtp_cipher_t of type ctype
*/ */
err_status_t srtp_err_status_t
cipher_array_alloc_init(cipher_t ***ca, int num_ciphers, cipher_array_alloc_init(srtp_cipher_t ***ca, int num_ciphers,
cipher_type_t *ctype, int klen) { srtp_cipher_type_t *ctype, int klen) {
int i, j; int i, j;
err_status_t status; srtp_err_status_t status;
uint8_t *key; uint8_t *key;
cipher_t **cipher_array; srtp_cipher_t **cipher_array;
/* pad klen allocation, to handle aes_icm reading 16 bytes for the /* pad klen allocation, to handle aes_icm reading 16 bytes for the
14-byte salt */ 14-byte salt */
int klen_pad = ((klen + 15) >> 4) << 4; int klen_pad = ((klen + 15) >> 4) << 4;
/* allocate array of pointers to ciphers */ /* allocate array of pointers to ciphers */
cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers); cipher_array = (srtp_cipher_t **) malloc(sizeof(srtp_cipher_t *) * num_ciphers);
if (cipher_array == NULL) if (cipher_array == NULL)
return err_status_alloc_fail; return srtp_err_status_alloc_fail;
/* set ca to location of cipher_array */ /* set ca to location of cipher_array */
*ca = cipher_array; *ca = cipher_array;
/* allocate key */ /* allocate key */
key = crypto_alloc(klen_pad); key = srtp_crypto_alloc(klen_pad);
if (key == NULL) { if (key == NULL) {
free(cipher_array); free(cipher_array);
return err_status_alloc_fail; return srtp_err_status_alloc_fail;
} }
/* allocate and initialize an array of ciphers */ /* allocate and initialize an array of ciphers */
for (i=0; i < num_ciphers; i++) { for (i=0; i < num_ciphers; i++) {
/* allocate cipher */ /* allocate cipher */
status = cipher_type_alloc(ctype, cipher_array, klen, 16); status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
if (status) if (status)
return status; return status;
@ -488,7 +477,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
key[j] = (uint8_t) rand(); key[j] = (uint8_t) rand();
for (; j < klen_pad; j++) for (; j < klen_pad; j++)
key[j] = 0; key[j] = 0;
status = cipher_init(*cipher_array, key); status = srtp_cipher_init(*cipher_array, key);
if (status) if (status)
return status; return status;
@ -500,22 +489,22 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
cipher_array++; cipher_array++;
} }
crypto_free(key); srtp_crypto_free(key);
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t
cipher_array_delete(cipher_t *cipher_array[], int num_cipher) { cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher) {
int i; int i;
for (i=0; i < num_cipher; i++) { for (i=0; i < num_cipher; i++) {
cipher_dealloc(cipher_array[i]); srtp_cipher_dealloc(cipher_array[i]);
} }
free(cipher_array); free(cipher_array);
return err_status_ok; return srtp_err_status_ok;
} }
@ -532,7 +521,7 @@ cipher_array_delete(cipher_t *cipher_array[], int num_cipher) {
*/ */
uint64_t uint64_t
cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, cipher_array_bits_per_second(srtp_cipher_t *cipher_array[], int num_cipher,
unsigned octets_in_buffer, int num_trials) { unsigned octets_in_buffer, int num_trials) {
int i; int i;
v128_t nonce; v128_t nonce;
@ -541,7 +530,7 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
int cipher_index = rand() % num_cipher; int cipher_index = rand() % num_cipher;
/* Over-alloc, for NIST CBC padding */ /* Over-alloc, for NIST CBC padding */
enc_buf = crypto_alloc(octets_in_buffer+17); enc_buf = srtp_crypto_alloc(octets_in_buffer+17);
if (enc_buf == NULL) if (enc_buf == NULL)
return 0; /* indicate bad parameters by returning null */ return 0; /* indicate bad parameters by returning null */
memset(enc_buf, 0, octets_in_buffer); memset(enc_buf, 0, octets_in_buffer);
@ -550,13 +539,13 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
v128_set_to_zero(&nonce); v128_set_to_zero(&nonce);
timer = clock(); timer = clock();
for(i=0; i < num_trials; i++, nonce.v32[3] = i) { for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
/* length parameter to cipher_encrypt is in/out -- out is total, padded /* length parameter to srtp_cipher_encrypt is in/out -- out is total, padded
* length -- so reset it each time. */ * length -- so reset it each time. */
unsigned octets_to_encrypt = octets_in_buffer; unsigned octets_to_encrypt = octets_in_buffer;
/* encrypt buffer with cipher */ /* encrypt buffer with cipher */
cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt); srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t*)&nonce, srtp_direction_encrypt);
cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt); srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
/* choose a cipher at random from the array*/ /* choose a cipher at random from the array*/
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
@ -574,7 +563,7 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
} }
void void
cipher_array_test_throughput(cipher_t *ca[], int num_cipher) { cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher) {
int i; int i;
int min_enc_len = 16; int min_enc_len = 16;
int max_enc_len = 2048; /* should be a power of two */ int max_enc_len = 2048; /* should be a power of two */
@ -589,11 +578,11 @@ cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
} }
err_status_t srtp_err_status_t
cipher_driver_test_array_throughput(cipher_type_t *ct, cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
int klen, int num_cipher) { int klen, int num_cipher) {
cipher_t **ca = NULL; srtp_cipher_t **ca = NULL;
err_status_t status; srtp_err_status_t status;
status = cipher_array_alloc_init(&ca, num_cipher, ct, klen); status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
if (status) { if (status) {
@ -606,5 +595,5 @@ cipher_driver_test_array_throughput(cipher_type_t *ct,
cipher_array_delete(ca, num_cipher); cipher_array_delete(ca, num_cipher);
return err_status_ok; return srtp_err_status_ok;
} }

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,9 +44,14 @@
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> /* for printf() */ #include <stdio.h> /* for printf() */
#include <string.h> /* for strlen() */ #include <string.h> /* for strlen() */
#include "datatypes.h" #include "datatypes.h"
#include "util.h"
void void
byte_order(void); byte_order(void);
@ -205,7 +210,7 @@ test_hex_string_funcs(void) {
void void
print_string(char *s) { print_string(char *s) {
int i; size_t i;
printf("%s\n", s); printf("%s\n", s);
printf("strlen(s) = %u\n", (unsigned)strlen(s)); printf("strlen(s) = %u\n", (unsigned)strlen(s));
printf("{ "); printf("{ ");
@ -222,7 +227,7 @@ test_bswap(void) {
uint32_t x = 0x11223344; uint32_t x = 0x11223344;
uint64_t y = 0x1122334455667788LL; uint64_t y = 0x1122334455667788LL;
printf("before: %0x\nafter: %0x\n", x, be32_to_cpu(x)); printf("before: %0x\nafter: %0x\n", x, (unsigned int)be32_to_cpu(x));
printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y, printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y,
(unsigned long long)be64_to_cpu(y)); (unsigned long long)be64_to_cpu(y));

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -49,7 +49,6 @@
int int
main(void) { main(void) {
int err_count = 0; int err_count = 0;
char *str;
#ifdef WORDS_BIGENDIAN #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");
@ -80,19 +79,6 @@ main(void) {
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 #endif
#ifndef OPENSSL
#ifdef DEV_URANDOM
str = DEV_URANDOM;
#else
str = "";
#endif
printf("using %s as a random source\t(DEV_URANDOM == %s)\n",
str, str);
if (strcmp("", str) == 0) {
err_count++;
}
#endif
if (err_count) if (err_count)
printf("warning: configuration is probably in error " printf("warning: configuration is probably in error "
"(found %d problems)\n", err_count); "(found %d problems)\n", err_count);

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright(c) 2001-2006 Cisco Systems, Inc. * Copyright(c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,8 +43,12 @@
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> /* for printf() */ #include <stdio.h> /* for printf() */
#include <unistd.h> /* for getopt() */ #include "getopt_s.h"
#include "crypto_kernel.h" #include "crypto_kernel.h"
void void
@ -55,25 +59,24 @@ usage(char *prog_name) {
int int
main (int argc, char *argv[]) { main (int argc, char *argv[]) {
extern char *optarg;
int q; int q;
int do_validation = 0; int do_validation = 0;
err_status_t status; srtp_err_status_t status;
if (argc == 1) if (argc == 1)
usage(argv[0]); usage(argv[0]);
/* initialize kernel - we need to do this before anything else */ /* initialize kernel - we need to do this before anything else */
status = crypto_kernel_init(); status = srtp_crypto_kernel_init();
if (status) { if (status) {
printf("error: crypto_kernel init failed\n"); printf("error: srtp_crypto_kernel init failed\n");
exit(1); exit(1);
} }
printf("crypto_kernel successfully initalized\n"); printf("srtp_crypto_kernel successfully initalized\n");
/* process input arguments */ /* process input arguments */
while (1) { while (1) {
q = getopt(argc, argv, "vd:"); q = getopt_s(argc, argv, "vd:");
if (q == -1) if (q == -1)
break; break;
switch (q) { switch (q) {
@ -81,9 +84,9 @@ main (int argc, char *argv[]) {
do_validation = 1; do_validation = 1;
break; break;
case 'd': case 'd':
status = crypto_kernel_set_debug_module(optarg, 1); status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
if (status) { if (status) {
printf("error: set debug module (%s) failed\n", optarg); printf("error: set debug module (%s) failed\n", optarg_s);
exit(1); exit(1);
} }
break; break;
@ -93,21 +96,21 @@ main (int argc, char *argv[]) {
} }
if (do_validation) { if (do_validation) {
printf("checking crypto_kernel status...\n"); printf("checking srtp_crypto_kernel status...\n");
status = crypto_kernel_status(); status = srtp_crypto_kernel_status();
if (status) { if (status) {
printf("failed\n"); printf("failed\n");
exit(1); exit(1);
} }
printf("crypto_kernel passed self-tests\n"); printf("srtp_crypto_kernel passed self-tests\n");
} }
status = crypto_kernel_shutdown(); status = srtp_crypto_kernel_shutdown();
if (status) { if (status) {
printf("error: crypto_kernel shutdown failed\n"); printf("error: srtp_crypto_kernel shutdown failed\n");
exit(1); exit(1);
} }
printf("crypto_kernel successfully shut down\n"); printf("srtp_crypto_kernel successfully shut down\n");
return 0; return 0;
} }
@ -117,10 +120,10 @@ main (int argc, char *argv[]) {
* of the crypto_kernel * of the crypto_kernel
*/ */
err_status_t srtp_err_status_t
crypto_kernel_cipher_test(void) { crypto_kernel_cipher_test(void) {
/* not implemented yet! */ /* not implemented yet! */
return err_status_ok; return srtp_err_status_ok;
} }

View File

@ -1,140 +0,0 @@
/*
* rand_gen.c
*
* a random source (random number generator)
*
* David A. McGrew
* Cisco Systems, Inc.
*/
/*
*
* Copyright(c) 2001-2006 Cisco Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h> /* for printf() */
#include <unistd.h> /* for getopt() */
#include "crypto_kernel.h"
/*
* MAX_PRINT_STRING_LEN is defined in datatypes.h, and is the length
* of the largest hexadecimal string that can be generated by the
* function octet_string_hex_string().
*/
#define BUF_LEN (MAX_PRINT_STRING_LEN/2)
void
usage(char *prog_name) {
printf("usage: %s -n <num_bytes> [-l][ -d debug_module ]*\n"
" -n <num> output <num> random bytes, where <num>"
" is between zero and %d\n"
" -l list the avaliable debug modules\n"
" -d <mod> turn on debugging module <mod>\n",
prog_name, BUF_LEN);
exit(255);
}
int
main (int argc, char *argv[]) {
extern char *optarg;
int q;
int num_octets = 0;
unsigned do_list_mods = 0;
err_status_t status;
if (argc == 1)
usage(argv[0]);
/* initialize kernel - we need to do this before anything else */
status = crypto_kernel_init();
if (status) {
printf("error: crypto_kernel init failed\n");
exit(1);
}
/* process input arguments */
while (1) {
q = getopt(argc, argv, "ld:n:");
if (q == -1)
break;
switch (q) {
case 'd':
status = crypto_kernel_set_debug_module(optarg, 1);
if (status) {
printf("error: set debug module (%s) failed\n", optarg);
exit(1);
}
break;
case 'l':
do_list_mods = 1;
break;
case 'n':
num_octets = atoi(optarg);
if (num_octets < 0 || num_octets > BUF_LEN)
usage(argv[0]);
break;
default:
usage(argv[0]);
}
}
if (do_list_mods) {
status = crypto_kernel_list_debug_modules();
if (status) {
printf("error: list of debug modules failed\n");
exit(1);
}
}
if (num_octets > 0) {
uint8_t buffer[BUF_LEN];
status = crypto_get_random(buffer, num_octets);
if (status) {
printf("error: failure in random source\n");
} else {
printf("%s\n", octet_string_hex_string(buffer, num_octets));
}
}
status = crypto_kernel_shutdown();
if (status) {
printf("error: crypto_kernel shutdown failed\n");
exit(1);
}
return 0;
}

View File

@ -1,76 +0,0 @@
/*
* Soak test the RNG for exhaustion failures
*/
#include <stdio.h> /* for printf() */
#include <unistd.h> /* for getopt() */
#include "crypto_kernel.h"
#define BUF_LEN (MAX_PRINT_STRING_LEN/2)
int main(int argc, char *argv[])
{
int q;
extern char *optarg;
int num_octets = 0;
err_status_t status;
uint32_t iterations = 0;
int print_values = 0;
if (argc == 1) {
exit(255);
}
status = crypto_kernel_init();
if (status) {
printf("error: crypto_kernel init failed\n");
exit(1);
}
while (1) {
q = getopt(argc, argv, "pvn:");
if (q == -1) {
break;
}
switch (q) {
case 'p':
print_values = 1;
break;
case 'n':
num_octets = atoi(optarg);
if (num_octets < 0 || num_octets > BUF_LEN) {
exit(255);
}
break;
case 'v':
num_octets = 30;
print_values = 0;
break;
default:
exit(255);
}
}
if (num_octets > 0) {
while (iterations < 300000) {
uint8_t buffer[BUF_LEN];
status = crypto_get_random(buffer, num_octets);
if (status) {
printf("iteration %d error: failure in random source\n", iterations);
exit(255);
} else if (print_values) {
printf("%s\n", octet_string_hex_string(buffer, num_octets));
}
iterations++;
}
}
status = crypto_kernel_shutdown();
if (status) {
printf("error: crypto_kernel shutdown failed\n");
exit(1);
}
return 0;
}

View File

@ -9,7 +9,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,8 +43,14 @@
* *
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "sha1.h" #include "sha1.h"
#include "util.h"
#define SHA_PASS 0 #define SHA_PASS 0
#define SHA_FAIL 1 #define SHA_FAIL 1
@ -62,7 +68,7 @@ typedef struct hash_test_case_t {
hash_test_case_t *sha1_test_case_list; hash_test_case_t *sha1_test_case_list;
err_status_t srtp_err_status_t
hash_test_case_add(hash_test_case_t **list_ptr, hash_test_case_add(hash_test_case_t **list_ptr,
char *hex_data, char *hex_data,
unsigned data_len, unsigned data_len,
@ -74,15 +80,19 @@ hash_test_case_add(hash_test_case_t **list_ptr,
test_case = malloc(sizeof(hash_test_case_t)); test_case = malloc(sizeof(hash_test_case_t));
if (test_case == NULL) if (test_case == NULL)
return err_status_alloc_fail; return srtp_err_status_alloc_fail;
tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2); tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2);
if (tmp_len != data_len*2) if (tmp_len != data_len*2) {
return err_status_parse_err; free(test_case);
return srtp_err_status_parse_err;
}
tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2); tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2);
if (tmp_len != hash_len*2) if (tmp_len != hash_len*2) {
return err_status_parse_err; free(test_case);
return srtp_err_status_parse_err;
}
test_case->data_len = data_len; test_case->data_len = data_len;
test_case->hash_len = hash_len; test_case->hash_len = hash_len;
@ -91,25 +101,25 @@ hash_test_case_add(hash_test_case_t **list_ptr,
test_case->next_test_case = list_head; test_case->next_test_case = list_head;
*list_ptr = test_case; *list_ptr = test_case;
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t
sha1_test_case_validate(const hash_test_case_t *test_case) { sha1_test_case_validate(const hash_test_case_t *test_case) {
sha1_ctx_t ctx; srtp_sha1_ctx_t ctx;
uint32_t hash_value[5]; uint32_t hash_value[5];
if (test_case == NULL) if (test_case == NULL)
return err_status_bad_param; return srtp_err_status_bad_param;
if (test_case->hash_len != 20) if (test_case->hash_len != 20)
return err_status_bad_param; return srtp_err_status_bad_param;
if (test_case->data_len > MAX_HASH_DATA_LEN) if (test_case->data_len > MAX_HASH_DATA_LEN)
return err_status_bad_param; return srtp_err_status_bad_param;
sha1_init(&ctx); srtp_sha1_init(&ctx);
sha1_update(&ctx, test_case->data, test_case->data_len); srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
sha1_final(&ctx, hash_value); srtp_sha1_final(&ctx, hash_value);
if (0 == memcmp(test_case->hash, hash_value, 20)) { if (0 == memcmp(test_case->hash, hash_value, 20)) {
#if VERBOSE #if VERBOSE
printf("PASSED: reference value: %s\n", printf("PASSED: reference value: %s\n",
@ -117,7 +127,7 @@ sha1_test_case_validate(const hash_test_case_t *test_case) {
printf("PASSED: computed value: %s\n", printf("PASSED: computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20)); octet_string_hex_string((const uint8_t *)hash_value, 20));
#endif #endif
return err_status_ok; return srtp_err_status_ok;
} }
printf("reference value: %s\n", printf("reference value: %s\n",
@ -125,7 +135,7 @@ sha1_test_case_validate(const hash_test_case_t *test_case) {
printf("computed value: %s\n", printf("computed value: %s\n",
octet_string_hex_string((const uint8_t *)hash_value, 20)); octet_string_hex_string((const uint8_t *)hash_value, 20));
return err_status_algo_fail; return srtp_err_status_algo_fail;
} }
@ -135,10 +145,10 @@ struct hex_sha1_test_case_t {
char hex_hash[40]; char hex_hash[40];
}; };
err_status_t srtp_err_status_t
sha1_add_test_cases(void) { sha1_add_test_cases(void) {
int i; int i;
err_status_t err; srtp_err_status_t err;
/* /*
* these test cases are taken from the "SHA-1 Sample Vectors" * these test cases are taken from the "SHA-1 Sample Vectors"
@ -482,10 +492,10 @@ sha1_add_test_cases(void) {
} }
} }
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t
sha1_dealloc_test_cases(void) { sha1_dealloc_test_cases(void) {
hash_test_case_t *t, *next; hash_test_case_t *t, *next;
@ -496,15 +506,15 @@ sha1_dealloc_test_cases(void) {
sha1_test_case_list = NULL; sha1_test_case_list = NULL;
return err_status_ok; return srtp_err_status_ok;
} }
err_status_t srtp_err_status_t
sha1_validate(void) { sha1_validate(void) {
hash_test_case_t *test_case; hash_test_case_t *test_case;
err_status_t err; srtp_err_status_t err;
err = sha1_add_test_cases(); err = sha1_add_test_cases();
if (err) { if (err) {
@ -513,7 +523,7 @@ sha1_validate(void) {
} }
if (sha1_test_case_list == NULL) if (sha1_test_case_list == NULL)
return err_status_cant_check; return srtp_err_status_cant_check;
test_case = sha1_test_case_list; test_case = sha1_test_case_list;
while (test_case != NULL) { while (test_case != NULL) {
@ -527,14 +537,14 @@ sha1_validate(void) {
sha1_dealloc_test_cases(); sha1_dealloc_test_cases();
return err_status_ok; return srtp_err_status_ok;
} }
int int
main (void) { main (void) {
err_status_t err; srtp_err_status_t err;
printf("sha1 test driver\n"); printf("sha1 test driver\n");

View File

@ -7,6 +7,45 @@
* Cisco Systems, Inc. * 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
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> /* for printf() */ #include <stdio.h> /* for printf() */
@ -20,11 +59,11 @@ typedef struct {
void *state; void *state;
} random_source_t; } random_source_t;
err_status_t srtp_err_status_t
random_source_alloc(void); random_source_alloc(void);
void void
err_check(err_status_t s) { err_check(srtp_err_status_t s) {
if (s) { if (s) {
printf("error (code %d)\n", s); printf("error (code %d)\n", s);
exit(1); exit(1);
@ -36,12 +75,13 @@ main (int argc, char *argv[]) {
uint8_t buffer[2532]; uint8_t buffer[2532];
unsigned int buf_len = 2500; unsigned int buf_len = 2500;
int i, j; int i, j;
extern cipher_type_t aes_icm; extern srtp_cipher_type_t srtp_aes_icm_128;
extern srtp_cipher_type_t srtp_aes_icm_256;
#ifdef OPENSSL #ifdef OPENSSL
extern cipher_type_t aes_gcm_128_openssl; extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
extern cipher_type_t aes_gcm_256_openssl; extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
#endif #endif
cipher_t *c; srtp_cipher_t *c;
uint8_t key[46] = { 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,
@ -77,10 +117,10 @@ main (int argc, char *argv[]) {
/* set buffer to cipher output */ /* set buffer to cipher output */
for (i=0; i < 2500; i++) for (i=0; i < 2500; i++)
buffer[i] = 0; buffer[i] = 0;
err_check(cipher_type_alloc(&aes_icm, &c, 30, 0)); err_check(srtp_cipher_type_alloc(&srtp_aes_icm_128, &c, SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
err_check(cipher_init(c, key)); err_check(srtp_cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */ /* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer)); printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer)); printf("poker %d\n", stat_test_poker(buffer));
@ -94,8 +134,8 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) for (i=0; i < 2500; i++)
buffer[i] = 0; buffer[i] = 0;
nonce.v32[3] = i; nonce.v32[3] = i;
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) { if (stat_test_runs(buffer)) {
num_fail++; num_fail++;
} }
@ -105,16 +145,16 @@ main (int argc, char *argv[]) {
printf("(nota bene: a small fraction of stat_test failures does not \n" printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n"); "indicate that the random source is invalid)\n");
err_check(cipher_dealloc(c)); err_check(srtp_cipher_dealloc(c));
printf("running stat_tests on AES-256-ICM, expecting success\n"); printf("running stat_tests on AES-256-ICM, expecting success\n");
/* set buffer to cipher output */ /* set buffer to cipher output */
for (i=0; i < 2500; i++) for (i=0; i < 2500; i++)
buffer[i] = 0; buffer[i] = 0;
err_check(cipher_type_alloc(&aes_icm, &c, 46, 0)); err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
err_check(cipher_init(c, key)); err_check(srtp_cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */ /* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer)); printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer)); printf("poker %d\n", stat_test_poker(buffer));
@ -128,8 +168,8 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) for (i=0; i < 2500; i++)
buffer[i] = 0; buffer[i] = 0;
nonce.v32[3] = i; nonce.v32[3] = i;
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
if (stat_test_runs(buffer)) { if (stat_test_runs(buffer)) {
num_fail++; num_fail++;
} }
@ -142,10 +182,10 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) { for (i=0; i < 2500; i++) {
buffer[i] = 0; buffer[i] = 0;
} }
err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8)); err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c, SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
err_check(cipher_init(c, key)); err_check(srtp_cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */ /* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer)); printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer)); printf("poker %d\n", stat_test_poker(buffer));
@ -158,8 +198,8 @@ main (int argc, char *argv[]) {
buffer[i] = 0; buffer[i] = 0;
} }
nonce.v32[3] = i; nonce.v32[3] = i;
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500; buf_len = 2500;
if (stat_test_runs(buffer)) { if (stat_test_runs(buffer)) {
num_fail++; num_fail++;
@ -171,10 +211,10 @@ main (int argc, char *argv[]) {
for (i=0; i < 2500; i++) { for (i=0; i < 2500; i++) {
buffer[i] = 0; buffer[i] = 0;
} }
err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16)); err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c, SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
err_check(cipher_init(c, key)); err_check(srtp_cipher_init(c, key));
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
/* run tests on cipher outout */ /* run tests on cipher outout */
printf("monobit %d\n", stat_test_monobit(buffer)); printf("monobit %d\n", stat_test_monobit(buffer));
printf("poker %d\n", stat_test_poker(buffer)); printf("poker %d\n", stat_test_poker(buffer));
@ -187,8 +227,8 @@ main (int argc, char *argv[]) {
buffer[i] = 0; buffer[i] = 0;
} }
nonce.v32[3] = i; nonce.v32[3] = i;
err_check(cipher_set_iv(c, &nonce, direction_encrypt)); err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
err_check(cipher_encrypt(c, buffer, &buf_len)); err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
buf_len = 2500; buf_len = 2500;
if (stat_test_runs(buffer)) { if (stat_test_runs(buffer)) {
num_fail++; num_fail++;
@ -201,7 +241,7 @@ main (int argc, char *argv[]) {
printf("(nota bene: a small fraction of stat_test failures does not \n" printf("(nota bene: a small fraction of stat_test failures does not \n"
"indicate that the random source is invalid)\n"); "indicate that the random source is invalid)\n");
err_check(cipher_dealloc(c)); err_check(srtp_cipher_dealloc(c));
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

2412
libs/srtp/doc/Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,8 @@
# Cisco Systems, Inc. # Cisco Systems, Inc.
# #
# This makefile does not use the autoconf system; we don't really need # This makefile does not use the autoconf system; we don't really need
# it. We just run doxygen then latex. If you don't have either of # it. We just run doxygen.
# these, then there is no way that you can make your own # The most up to date documentation can be found at www.github.com/cisco/libsrtp
# documentation. Of course, you can just go online at pick up the
# documentation from http://srtp.sourceforge.net.
srcdir = @srcdir@ srcdir = @srcdir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
@ -18,27 +16,17 @@ VPATH = @srcdir@
version = $(shell cat $(top_srcdir)/VERSION) version = $(shell cat $(top_srcdir)/VERSION)
.PHONY: libsrtpdoc clean
.PHONY: libsrtpdoc cryptodoc clean libsrtpdoc:
libsrtpdoc: @if test ! -e Doxyfile.in; then \
@if test ! -e Doxyfile; then \
echo "*** Sorry, can't build doc outside source dir"; exit 1; \ echo "*** Sorry, can't build doc outside source dir"; exit 1; \
fi fi
sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex sed 's/LIBSRTPVERSIONNUMBER/$(version)/' Doxyfile.in > Doxyfile
doxygen doxygen
sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp
mv latex/index.tmp latex/index.tex
cd latex; make
cp latex/refman.pdf libsrtp.pdf
cryptodoc: clean
doxygen crypto.dox
cd latex; make
cp latex/refman.pdf crypto.pdf
clean: clean:
rm -rf latex/ header.tex
for a in * ; do \ rm -rf html/ Doxyfile
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \ for a in * ; do \
done; if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
done;

1479
libs/srtp/doc/docs.css Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,115 +0,0 @@
% header.tex
%
% header file for the libSRTP documentation - based on the header
% file generated by doxygen, with the initial chapters of the
% original libSRTP documentation tacked on
%
\documentclass[letterpaper]{book}
\usepackage{makeidx}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{float}
\usepackage{textcomp}
\usepackage{alltt}
\usepackage{times}
\usepackage{graphicx}
\ifx\pdfoutput\undefined
\usepackage[ps2pdf,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\else
\usepackage[pdftex,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\fi
\usepackage{doxygen}
\makeindex
\setcounter{tocdepth}{1}
\renewcommand{\footrulewidth}{0.4pt}
% these lengths are from DAM
\textwidth = 6.5 in
%\textheight = 9 in
\oddsidemargin = 0.0 in
\evensidemargin = 0.0 in
\topmargin = 0.0 in
\headheight = 0.0 in
%\headsep = 0.0 in
\parskip = 0.2in
\parindent = 0.0in
% these header and footer definitions from DAM
\lhead{libSRTP}
\chead{}
\rhead{\rightmark}
%\rhead{\slshape }
\lfoot{}
\cfoot{ \thepage }
\rfoot{}
%\fancyhead[LE,RO]{\rightmark }
%\fancyhead[LO,RE]{\slshape }
% let's use the palatino font
\fontfamily{ppl}
\selectfont
\begin{document}
\begin{titlepage}
\vspace*{4cm}
%\begin{center}
{\Huge
libSRTP LIBSRTPVERSION Overview and Reference Manual\\
\hrulefill
}\\
\vspace*{0cm}
\begin{flushright}
{\Large David A. McGrew \\ \texttt{mcgrew@cisco.com} }\\
\vspace*{0.5cm}
\end{flushright}
%\end{center}
%\includegraphics[scale=.8]{phone}
\end{titlepage}
\clearemptydoublepage
\vspace*{3cm}
{\LARGE Preface}
\vspace{1cm}
The original implementation and documentation of libSRTP was written
by David McGrew of Cisco Systems, Inc. in order to promote the use,
understanding, and interoperability of Secure RTP. Michael Jerris
contributed support for building under MSVC. Andris Pavenis
contributed many important fixes. Brian West contributed changes to
enable dynamic linking. Yves Shumann reported documentation bugs.
Randell Jesup contributed a working SRTCP implementation and other
fixes. Alex Vanzella and Will Clark contributed changes so that the
AES ICM implementation can be used for ISMA media encryption. Steve
Underwood contributed x86\_64 portability changes. We also give
thanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill
Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and
others for contributions, comments, and corrections.
This reference material in this documenation was generated using the
\texttt{doxygen} utility for automatic documentation of source code.
\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc.
\thispagestyle{empty}
\clearemptydoublepage
\pagenumbering{roman}
\tableofcontents
%\clearemptydoublepage
\clearemptydoublepage
\pagenumbering{arabic}

View File

@ -1,395 +0,0 @@
/**
@mainpage Introduction to libSRTP
This document describes libSRTP, the Open Source Secure RTP library
from Cisco Systems, Inc. RTP is the Real-time Transport Protocol, an
IETF standard for the transport of real-time data such as telephony,
audio, and video, defined by RFC 3550. Secure RTP (SRTP) is an RTP
profile for providing confidentiality to RTP data and authentication
to the RTP header and payload. SRTP is an IETF Proposed Standard,
defined in RFC 3711, and was developed in the IETF Audio/Video
Transport (AVT) Working Group. This library supports all of the
mandatory features of SRTP, but not all of the optional features. See
the @ref Features section for more detailed information.
This document is organized as follows. The first chapter provides
background material on SRTP and overview of libSRTP. The following
chapters provide a detailed reference to the libSRTP API and related
functions. The reference material is created automatically (using the
doxygen utility) from comments embedded in some of the C header
files. The documentation is organized into modules in order to improve
its clarity. These modules do not directly correspond to files. An
underlying cryptographic kernel provides much of the basic
functionality of libSRTP, but is mostly undocumented because it does
its work behind the scenes.
@section LICENSE License and Disclaimer
libSRTP is distributed under the following license, which is included
in the source code distribution. It is reproduced in the manual in
case you got the library from another source.
@latexonly
\begin{quote}
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:
\begin{itemize}
\item Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
\item 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.
\item 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.
\end{itemize}
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.
\end{quote}
@endlatexonly
@section Features Supported Features
This library supports all of the mandatory-to-implement features of
SRTP (as defined by the most recent Internet Draft). Some of these
features can be selected (or de-selected) at run time by setting an
appropriate policy; this is done using the structure srtp_policy_t.
Some other behaviors of the protocol can be adapted by defining an
approriate event handler for the exceptional events; see the @ref
SRTPevents section.
Some options that are not included in the specification are supported.
Most notably, the TMMH authentication function is included, though it
was removed from the SRTP Internet Draft during the summer of 2002.
@latexonly
Some options that are described in the SRTP specification are not
supported. This includes
\begin{itemize}
\item the Master Key Index (MKI),
\item key derivation rates other than zero,
\item the cipher F8,
\item anti-replay lists with sizes other than 128,
\item the use of the packet index to select between master keys.
\end{itemize}
@endlatexonly
The user should be aware that it is possible to misuse this libary,
and that the result may be that the security level it provides is
inadequate. If you are implementing a feature using this library, you
will want to read the Security Considerations section of the Internet
Draft. In addition, it is important that you read and understand the
terms outlined in the @ref LICENSE section.
@section Installing Installing and Building libSRTP
@latexonly
To install libSRTP, download the latest release of the distribution
from \texttt{srtp.sourceforge.net}. The format of the names of the
distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the
version number, \texttt{B} is the major release number, \texttt{C} is
the minor release number, and \texttt{tgz} is the file
extension\footnote{The extension \texttt{.tgz} is identical to
\texttt{tar.gz}, and indicates a compressed tar file.} You probably
want to get the most recent release. Unpack the distribution and
extract the source files; the directory into which the source files
will go is named \texttt{srtp}.
libSRTP uses the GNU \texttt{autoconf} and \texttt{make}
utilities\footnote{BSD make will not work; if both versions of make
are on your platform, you can invoke GNU make as \texttt{gmake}.}. In
the \texttt{srtp} directory, run the configure script and then make:
\begin{verbatim}
./configure [ options ]
make
\end{verbatim}
The configure script accepts the following options:
\begin{quote}
\begin{description}
\item[--help] provides a usage summary.
\item[--disable-debug] compiles libSRTP without the runtime
dynamic debugging system.
\item[--enable-generic-aesicm] compile in changes for ismacryp
\item[--enable-syslog] use syslog for error reporting.
\item[--disable-stdout] diables stdout for error reporting.
\item[--enable-console] use \texttt{/dev/console} for error reporting
\item[--gdoi] use GDOI key management (disabled at present).
\end{description}
\end{quote}
By default, dynamic debugging is enabled and stdout is used for
debugging. You can use the configure options to have the debugging
output sent to syslog or the system console. Alternatively, you can
define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other
file that can be opened by libSRTP, and debug messages will be sent to
it.
This package has been tested on the following platforms: Mac OS X
(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and
OpenBSD (sparc-unknown-openbsd2.7).
@endlatexonly
@section Applications Applications
@latexonly
Several test drivers and a simple and portable srtp application are
included in the \texttt{test/} subdirectory.
\begin{center}
\begin{tabular}{ll}
\hline
Test driver & Function tested \\
\hline
kernel\_driver & crypto kernel (ciphers, auth funcs, rng) \\
srtp\_driver & srtp in-memory tests (does not use the network) \\
rdbx\_driver & rdbx (extended replay database) \\
roc\_driver & extended sequence number functions \\
replay\_driver & replay database \\
cipher\_driver & ciphers \\
auth\_driver & hash functions \\
\hline
\end{tabular}
\end{center}
The app rtpw is a simple rtp application which reads words from
/usr/dict/words and then sends them out one at a time using [s]rtp.
Manual srtp keying uses the -k option; automated key management
using gdoi will be added later.
The usage for rtpw is
\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip
dest\_port] | [-l]}
Either the -s (sender) or -r (receiver) option must be chosen. The
values dest\_ip, dest\_port are the IP address and UDP port to which
the dictionary will be sent, respectively. The options are:
\begin{center}
\begin{tabular}{ll}
-s & (S)RTP sender - causes app to send words \\
-r & (S)RTP receive - causes app to receive words \\
-k $<$key$>$ & use SRTP master key $<$key$>$, where the
key is a hexadecimal value (without the
leading "0x") \\
-e & encrypt/decrypt (for data confidentiality)
(requires use of -k option as well)\\
-a & message authentication
(requires use of -k option as well) \\
-l & list the available debug modules \\
-d $<$debug$>$ & turn on debugging for module $<$debug$>$ \\
\end{tabular}
\end{center}
In order to get a random 30-byte value for use as a key/salt pair, you
can use the \texttt{rand\_gen} utility in the \texttt{test/}
subdirectory.
An example of an SRTP session using two rtpw programs follows:
\begin{verbatim}
[sh1] set k=`test/rand_gen -n 30`
[sh1] echo $k
c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
sending word: aalii
sending word: aam
sending word: Aani
sending word: aardvark
...
[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
\end{verbatim}
@endlatexonly
@section Review Secure RTP Background
In this section we review SRTP and introduce some terms that are used
in libSRTP. An RTP session is defined by a pair of destination
transport addresses, that is, a network address plus a pair of UDP
ports for RTP and RTCP. RTCP, the RTP control protocol, is used to
coordinate between the participants in an RTP session, e.g. to provide
feedback from receivers to senders. An @e SRTP @e session is
similarly defined; it is just an RTP session for which the SRTP
profile is being used. An SRTP session consists of the traffic sent
to the SRTP or SRTCP destination transport addresses. Each
participant in a session is identified by a synchronization source
(SSRC) identifier. Some participants may not send any SRTP traffic;
they are called receivers, even though they send out SRTCP traffic,
such as receiver reports.
RTP allows multiple sources to send RTP and RTCP traffic during the
same session. The synchronization source identifier (SSRC) is used to
distinguish these sources. In libSRTP, we call the SRTP and SRTCP
traffic from a particular source a @e stream. Each stream has its own
SSRC, sequence number, rollover counter, and other data. A particular
choice of options, cryptographic mechanisms, and keys is called a @e
policy. Each stream within a session can have a distinct policy
applied to it. A session policy is a collection of stream policies.
A single policy can be used for all of the streams in a given session,
though the case in which a single @e key is shared across multiple
streams requires care. When key sharing is used, the SSRC values that
identify the streams @b must be distinct. This requirement can be
enforced by using the convention that each SRTP and SRTCP key is used
for encryption by only a single sender. In other words, the key is
shared only across streams that originate from a particular device (of
course, other SRTP participants will need to use the key for
decryption). libSRTP supports this enforcement by detecting the case
in which a key is used for both inbound and outbound data.
@section Overview libSRTP Overview
libSRTP provides functions for protecting RTP and RTCP. RTP packets
can be encrypted and authenticated (using the srtp_protect()
function), turning them into SRTP packets. Similarly, SRTP packets
can be decrypted and have their authentication verified (using the
srtp_unprotect() function), turning them into RTP packets. Similar
functions apply security to RTCP packets.
The typedef srtp_stream_t points to a structure holding all of the
state associated with an SRTP stream, including the keys and
parameters for cipher and message authentication functions and the
anti-replay data. A particular srtp_stream_t holds the information
needed to protect a particular RTP and RTCP stream. This datatype
is intentionally opaque in order to better seperate the libSRTP
API from its implementation.
Within an SRTP session, there can be multiple streams, each
originating from a particular sender. Each source uses a distinct
stream context to protect the RTP and RTCP stream that it is
originating. The typedef srtp_t points to a structure holding all of
the state associated with an SRTP session. There can be multiple
stream contexts associated with a single srtp_t. A stream context
cannot exist indepent from an srtp_t, though of course an srtp_t can
be created that contains only a single stream context. A device
participating in an SRTP session must have a stream context for each
source in that session, so that it can process the data that it
receives from each sender.
In libSRTP, a session is created using the function srtp_create().
The policy to be implemented in the session is passed into this
function as an srtp_policy_t structure. A single one of these
structures describes the policy of a single stream. These structures
can also be linked together to form an entire session policy. A linked
list of srtp_policy_t structures is equivalent to a session policy.
In such a policy, we refer to a single srtp_policy_t as an @e element.
An srtp_policy_t strucutre contains two crypto_policy_t structures
that describe the cryptograhic policies for RTP and RTCP, as well as
the SRTP master key and the SSRC value. The SSRC describes what to
protect (e.g. which stream), and the crypto_policy_t structures
describe how to protect it. The key is contained in a policy element
because it simplifies the interface to the library. In many cases, it
is desirable to use the same cryptographic policies across all of the
streams in a session, but to use a distinct key for each stream. A
crypto_policy_t structure can be initialized by using either the
crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default()
functions, which set a crypto policy structure to the default policies
for RTP and RTCP protection, respectively.
@section Example Example Code
This section provides a simple example of how to use libSRTP. The
example code lacks error checking, but is functional. Here we assume
that the value ssrc is already set to describe the SSRC of the stream
that we are sending, and that the functions get_rtp_packet() and
send_srtp_packet() are available to us. The former puts an RTP packet
into the buffer and returns the number of octets written to that
buffer. The latter sends the RTP packet in the buffer, given the
length as its second argument.
@verbatim
srtp_t session;
srtp_policy_t policy;
uint8_t key[30];
// initialize libSRTP
srtp_init();
// set policy to describe a policy for an SRTP stream
crypto_policy_set_rtp_default(&policy.rtp);
crypto_policy_set_rtcp_default(&policy.rtcp);
policy.ssrc = ssrc;
policy.key = key;
policy.next = NULL;
// set key to random value
crypto_get_random(key, 30);
// allocate and initialize the SRTP session
srtp_create(&session, &policy);
// main loop: get rtp packets, send srtp packets
while (1) {
char rtp_buffer[2048];
unsigned len;
len = get_rtp_packet(rtp_buffer);
srtp_protect(session, rtp_buffer, &len);
send_srtp_packet(rtp_buffer, len);
}
@endverbatim
@section ISMAcryp ISMA Encryption Support
The Internet Streaming Media Alliance (ISMA) specifies a way
to pre-encrypt a media file prior to streaming. This method
is an alternative to SRTP encryption, which is potentially
useful when a particular media file will be streamed
multiple times. The specification is available online
at http://www.isma.tv/specreq.nsf/SpecRequest.
libSRTP provides the encryption and decryption functions needed for ISMAcryp
in the library @t libaesicm.a, which is included in the default
Makefile target. This library is used by the MPEG4IP project; see
http://mpeg4ip.sourceforge.net/.
Note that ISMAcryp does not provide authentication for
RTP nor RTCP, nor confidentiality for RTCP.
ISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp
streams while using ISMAcryp encryption to protect the media itself.
*/

View File

@ -1,21 +0,0 @@
SRTP and ICM References
September, 2005
This document provides references for the various cryptographic
functions used in libSRTP and libaesicm.
Secure RTP is defined in RFC 3711, which is included in this
distribution for convenience. The counter mode definition is in
Section 4.1.1 of the SRTP draft.
SHA-1 is defined in FIPS-180-1, available online at the NIST website.
HMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available
in RFC2202, which are available online at http://www.ietf.org/rfc/
ICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in
ISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and
Authentication) is defined in that specification. It is available
from http://www.isma.tv/.

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2005 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -59,96 +59,82 @@
* *
*/ */
#ifndef EKT_H #ifndef SRTP_EKT_H
#define EKT_H #define SRTP_EKT_H
// left in commented out as reminder to not include private headers
//#include "srtp_priv.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "srtp_priv.h" #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 EKT_CIPHER_DEFAULT 1 typedef uint16_t srtp_ekt_spi_t;
#define EKT_CIPHER_AES_128_ECB 1
#define EKT_CIPHER_AES_192_KEY_WRAP 2
#define EKT_CIPHER_AES_256_KEY_WRAP 3
typedef uint16_t ekt_spi_t;
unsigned unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt);
ekt_octets_after_base_tag(ekt_stream_t ekt);
/* /*
* an srtp_policy_t structure can contain a pointer to an * an srtp_policy_t structure can contain a pointer to an
* ekt_policy_t structure * srtp_ekt_policy_t structure
* *
* this structure holds all of the high level EKT information, and it * this structure holds all of the high level EKT information, and it
* is passed into libsrtp to indicate what policy should be in effect * is passed into libsrtp to indicate what policy should be in effect
*/ */
typedef struct ekt_policy_ctx_t { typedef struct srtp_ekt_policy_ctx_t {
ekt_spi_t spi; /* security parameter index */ srtp_ekt_spi_t spi; /* security parameter index */
uint8_t ekt_cipher_type; uint8_t ekt_cipher_type;
uint8_t *ekt_key; uint8_t *ekt_key;
struct ekt_policy_ctx_t *next_ekt_policy; struct srtp_ekt_policy_ctx_t *next_ekt_policy;
} ekt_policy_ctx_t; } srtp_ekt_policy_ctx_t;
/* /*
* an ekt_data_t structure holds the data corresponding to an ekt key, * an srtp_ekt_data_t structure holds the data corresponding to an ekt key,
* spi, and so on * spi, and so on
*/ */
typedef struct ekt_data_t { typedef struct srtp_ekt_data_t {
ekt_spi_t spi; srtp_ekt_spi_t spi;
uint8_t ekt_cipher_type; uint8_t ekt_cipher_type;
aes_expanded_key_t ekt_enc_key; srtp_aes_expanded_key_t ekt_enc_key;
aes_expanded_key_t ekt_dec_key; srtp_aes_expanded_key_t ekt_dec_key;
struct ekt_data_t *next_ekt_data; struct ekt_data_t *next_ekt_data;
} ekt_data_t; } srtp_ekt_data_t;
/* /*
* an srtp_stream_ctx_t can contain an ekt_stream_ctx_t * an srtp_stream_ctx_t can contain an srtp_ekt_stream_ctx_t
* *
* an ekt_stream_ctx_t structure holds all of the EKT information for * an srtp_ekt_stream_ctx_t structure holds all of the EKT information for
* a specific SRTP stream * a specific SRTP stream
*/ */
typedef struct ekt_stream_ctx_t { typedef struct srtp_ekt_stream_ctx_t {
ekt_data_t *data; srtp_ekt_data_t *data;
uint16_t isn; /* initial sequence number */ uint16_t isn; /* initial sequence number */
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN]; uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
} ekt_stream_ctx_t; } srtp_ekt_stream_ctx_t;
err_status_t srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data, srtp_ekt_policy_t policy);
ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy);
err_status_t 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);
ekt_stream_init(ekt_stream_t e,
ekt_spi_t spi,
void *ekt_key,
unsigned ekt_cipher_type);
err_status_t srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t e, srtp_ekt_policy_t p);
ekt_stream_init_from_policy(ekt_stream_t e, ekt_policy_t p);
err_status_t srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream, const void *srtcp_hdr, unsigned pkt_octet_len);
srtp_stream_init_from_ekt(srtp_stream_t stream,
const void *srtcp_hdr,
unsigned pkt_octet_len);
void 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);
ekt_write_data(ekt_stream_t ekt,
uint8_t *base_tag,
unsigned base_tag_len,
int *packet_len,
xtd_seq_num_t pkt_index);
/* /*
* We handle EKT by performing some additional steps before * We handle EKT by performing some additional steps before
@ -158,16 +144,9 @@ ekt_write_data(ekt_stream_t ekt,
* With EKT, the tag_len parameter is actually the base tag * With EKT, the tag_len parameter is actually the base tag
* length * length
*/ */
srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag, uint8_t *pkt_tag_copy, unsigned tag_len);
err_status_t srtp_err_status_t srtp_ekt_tag_verification_postproces(uint8_t *pkt_tag, uint8_t *pkt_tag_copy, unsigned tag_len);
ekt_tag_verification_preproces(uint8_t *pkt_tag,
uint8_t *pkt_tag_copy,
unsigned tag_len);
err_status_t
ekt_tag_verification_postproces(uint8_t *pkt_tag,
uint8_t *pkt_tag_copy,
unsigned tag_len);
/* /*
@ -182,20 +161,14 @@ ekt_tag_verification_postproces(uint8_t *pkt_tag,
* When EKT is not used, this function is a no-op. * 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);
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 */ /* it's not clear that a tag_generation_postprocess function is needed */
srtp_err_status_t srtcp_auth_tag_generation_postprocess(void);
err_status_t
srtcp_auth_tag_generation_postprocess(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* EKT_H */ #endif /* SRTP_EKT_H */

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -45,6 +45,10 @@
#ifndef GETOPT_S_H #ifndef GETOPT_S_H
#define GETOPT_S_H #define GETOPT_S_H
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* getopt_s(), optarg_s, and optind_s are small, locally defined * getopt_s(), optarg_s, and optind_s are small, locally defined
* versions of the POSIX standard getopt() interface. * versions of the POSIX standard getopt() interface.
@ -57,4 +61,8 @@ extern char *optarg_s; /* defined in getopt.c */
extern int optind_s; /* defined in getopt.c */ extern int optind_s; /* defined in getopt.c */
#ifdef __cplusplus
}
#endif
#endif /* GETOPT_S_H */ #endif /* GETOPT_S_H */

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*/ */
/* /*
* *
* Copyright (c) 2001-2006 Cisco Systems, Inc. * Copyright (c) 2001-2017 Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -45,117 +45,28 @@
#ifndef SRTP_PRIV_H #ifndef SRTP_PRIV_H
#define SRTP_PRIV_H #define SRTP_PRIV_H
// Leave this as the top level import. Ensures the existence of defines
#include "config.h"
#include "srtp.h" #include "srtp.h"
#include "rdbx.h" #include "rdbx.h"
#include "rdb.h" #include "rdb.h"
#include "integers.h" #include "integers.h"
#include "cipher.h"
#include "auth.h"
#include "aes.h"
#include "key.h"
#include "crypto_kernel.h"
/* #ifdef __cplusplus
* an srtp_hdr_t represents the srtp header extern "C" {
*
* in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
*
* (note that this definition follows that of RFC 1889 Appendix A, but
* is not identical)
*/
#ifndef WORDS_BIGENDIAN
/*
* srtp_hdr_t represents an RTP or SRTP header. The bit-fields in
* this structure should be declared "unsigned int" instead of
* "unsigned char", but doing so causes the MS compiler to not
* fully pack the bit fields.
*/
typedef struct {
unsigned cc:4; /* CSRC count */
unsigned x:1; /* header extension flag */
unsigned p:1; /* padding flag */
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 */
} srtp_hdr_t;
#else /* BIG_ENDIAN */
typedef struct {
unsigned version:2; /* protocol version */
unsigned p:1; /* padding flag */
unsigned x:1; /* header extension flag */
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 */
} srtp_hdr_t;
#endif #endif
typedef struct { #define SRTP_VER_STRING PACKAGE_STRING
uint16_t profile_specific; /* profile-specific info */ #define SRTP_VERSION PACKAGE_VERSION
uint16_t length; /* number of 32-bit words in extension */
} srtp_hdr_xtnd_t;
/*
* srtcp_hdr_t represents a secure rtcp header
*
* in this implementation, an srtcp header is assumed to be 32-bit
* alinged
*/
#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 */
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 */
} 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 */
uint16_t len; /* length */
uint32_t ssrc; /* synchronization source */
} srtcp_hdr_t;
typedef struct {
unsigned int version:2; /* protocol version */
unsigned int p:1; /* padding flag */
unsigned int count:5; /* varies by packet type */
unsigned int pt:8; /* payload type */
uint16_t length; /* len of uint32s of packet less header */
} rtcp_common_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 */
} srtcp_trailer_t;
#endif
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
@ -165,27 +76,31 @@ typedef struct {
* srtp_get_stream(ssrc) returns a pointer to the stream corresponding * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
* to ssrc, or NULL if no stream exists for that ssrc * to ssrc, or NULL if no stream exists for that ssrc
*/ */
srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
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 * 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. * deriving all of the needed keys using the KDF and the key k.
*/ */
srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
srtp_master_key_t *master_key,
const unsigned int current_mki_index);
/*
err_status_t * srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s by
srtp_stream_init_keys(srtp_stream_t srtp, const void *key); * 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_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 * use the policy at the location p
*/ */
err_status_t srtp_err_status_t srtp_stream_init(srtp_stream_t srtp, const srtp_policy_t *p);
srtp_stream_init(srtp_stream_t srtp,
const srtp_policy_t *p);
/* /*
@ -198,44 +113,162 @@ typedef enum direction_t {
dir_srtp_receiver = 2 dir_srtp_receiver = 2
} direction_t; } direction_t;
/*
* srtp_session_keys_t will contain the encryption, hmac, salt keys
* for both SRTP and SRTCP. The session keys will also contain the
* 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_session_keys_t;
/* /*
* an srtp_stream_t has its own SSRC, encryption key, authentication * an srtp_stream_t has its own SSRC, encryption key, authentication
* key, sequence number, and replay database * key, sequence number, and replay database
* *
* note that the keys might not actually be unique, in which case the * note that the keys might not actually be unique, in which case the
* cipher_t and auth_t pointers will point to the same structures * srtp_cipher_t and srtp_auth_t pointers will point to the same structures
*/ */
typedef struct srtp_stream_ctx_t { typedef struct srtp_stream_ctx_t_ {
uint32_t ssrc; uint32_t ssrc;
cipher_t *rtp_cipher; srtp_session_keys_t *session_keys;
auth_t *rtp_auth; unsigned int num_master_keys;
rdbx_t rtp_rdbx; srtp_rdbx_t rtp_rdbx;
sec_serv_t rtp_services; srtp_sec_serv_t rtp_services;
cipher_t *rtcp_cipher; srtp_rdb_t rtcp_rdb;
auth_t *rtcp_auth; srtp_sec_serv_t rtcp_services;
rdb_t rtcp_rdb;
sec_serv_t rtcp_services;
key_limit_ctx_t *limit;
direction_t direction; direction_t direction;
int allow_repeat_tx; int allow_repeat_tx;
ekt_stream_t ekt; srtp_ekt_stream_t ekt;
uint8_t salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTP */ int *enc_xtn_hdr;
uint8_t c_salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTCP */ int enc_xtn_hdr_count;
struct srtp_stream_ctx_t *next; /* linked list of streams */ uint32_t pending_roc;
} srtp_stream_ctx_t; 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 * an srtp_ctx_t holds a stream list and a service description
*/ */
typedef struct srtp_ctx_t { typedef struct srtp_ctx_t_ {
srtp_stream_ctx_t *stream_list; /* linked list of streams */ struct srtp_stream_ctx_t_ *stream_list; /* linked list of streams */
srtp_stream_ctx_t *stream_template; /* act as template for other streams */ struct srtp_stream_ctx_t_ *stream_template; /* act as template for other streams */
} srtp_ctx_t; 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
* "unsigned char", but doing so causes the MS compiler to not
* fully pack the bit fields.
*
* In this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
*
* (note that this definition follows that of RFC 1889 Appendix A, but
* is not identical)
*/
#ifdef _MSC_VER
#pragma pack(push, r1, 1)
#endif
#ifndef WORDS_BIGENDIAN
typedef struct {
unsigned cc : 4; /* CSRC count */
unsigned x : 1; /* header extension flag */
unsigned p : 1; /* padding flag */
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 */
} srtp_hdr_t;
#else /* BIG_ENDIAN */
typedef struct {
unsigned version : 2; /* protocol version */
unsigned p : 1; /* padding flag */
unsigned x : 1; /* header extension flag */
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 */
} srtp_hdr_t;
#endif
typedef struct {
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
*
* in this implementation, an srtcp header is assumed to be 32-bit
* alinged
*/
#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 */
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 */
} 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 */
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 */
} srtcp_trailer_t;
#endif
#ifdef _MSC_VER
#pragma pack(pop, r1)
#endif
/* /*
* srtp_handle_event(srtp, srtm, evnt) calls the event handling * srtp_handle_event(srtp, srtm, evnt) calls the event handling
@ -249,10 +282,13 @@ typedef struct srtp_ctx_t {
if(srtp_event_handler) { \ if(srtp_event_handler) { \
srtp_event_data_t data; \ srtp_event_data_t data; \
data.session = srtp; \ data.session = srtp; \
data.stream = strm; \ data.ssrc = ntohl(strm->ssrc); \
data.event = evnt; \ data.event = evnt; \
srtp_event_handler(&data); \ srtp_event_handler(&data); \
} }
#ifdef __cplusplus
}
#endif
#endif /* SRTP_PRIV_H */ #endif /* SRTP_PRIV_H */

View File

@ -10,7 +10,7 @@
/* /*
* *
* Copyright (c) 2001-2006, Cisco Systems, Inc. * Copyright (c) 2001-2017, Cisco Systems, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -51,6 +51,10 @@
#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 { typedef struct {
@ -76,5 +80,8 @@ ut_init(ut_connection *utc);
uint32_t uint32_t
ut_next_index(ut_connection *utc); ut_next_index(ut_connection *utc);
#ifdef __cplusplus
}
#endif
#endif /* UT_SIM_H */ #endif /* UT_SIM_H */

35
libs/srtp/install-win.bat Normal file
View File

@ -0,0 +1,35 @@
:: Installs from srtp windows build directory to directory specified on
:: command line
@if "%1"=="" (
echo "Usage: %~nx0 destdir"
exit /b 1
) else (
set destdir=%1
)
@if not exist %destdir% (
echo %destdir% not found
exit /b 1
)
@for %%d in (include\srtp.h crypto\include\cipher.h Debug\srtp2.lib Release\srtp2.lib x64\Debug\srtp2.lib x64\Release\srtp2.lib) do (
if not exist "%%d" (
echo "%%d not found: are you in the right directory?"
exit /b 1
)
)
mkdir %destdir%\include
mkdir %destdir%\include\srtp2
mkdir %destdir%\lib
mkdir %destdir%\lib\x64
@for %%d in (include\srtp.h include\ekt.h crypto\include\cipher.h crypto\include\auth.h crypto\include\crypto_types.h) do (
copy %%d %destdir%\include\srtp2
)
copy Release\srtp2.lib %destdir%\lib\srtp2.lib
copy Debug\srtp2.lib %destdir%\lib\srtp2d.lib
copy x64\Release\srtp2.lib %destdir%\lib\x64\srtp2.lib
copy x64\Debug\srtp2.lib %destdir%\lib\x64\srtp2d.lib

View File

@ -1,907 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="libsrtp"
ProjectGUID="{EEF031CB-FED8-451E-A471-91EC8D4F6750}"
RootNamespace="libsrtp"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug Dll|Win32"
OutputDirectory="$(SolutionDir)Debug"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
OptimizeReferences="1"
EnableCOMDATFolding="1"
OptimizeForWindows98="1"
LinkTimeCodeGeneration="0"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug Dll|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
OptimizeReferences="1"
EnableCOMDATFolding="1"
OptimizeForWindows98="1"
LinkTimeCodeGeneration="0"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release Dll|Win32"
OutputDirectory="$(SolutionDir)Release"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release Dll|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\srtp\srtp.c"
>
</File>
<Filter
Name="Kernel"
>
<File
RelativePath=".\crypto\kernel\alloc.c"
>
</File>
<File
RelativePath=".\crypto\kernel\crypto_kernel.c"
>
</File>
<File
RelativePath=".\crypto\rng\ctr_prng.c"
>
</File>
<File
RelativePath=".\crypto\kernel\err.c"
>
</File>
<File
RelativePath=".\crypto\kernel\key.c"
>
</File>
<File
RelativePath=".\crypto\rng\prng.c"
>
</File>
<File
RelativePath=".\crypto\rng\rand_source.c"
>
</File>
</Filter>
<Filter
Name="Ciphers"
>
<File
RelativePath=".\crypto\cipher\aes.c"
>
<FileConfiguration
Name="Debug Dll|Win32"
>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="0"
EnableIntrinsicFunctions="false"
EnableFunctionLevelLinking="false"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dll|x64"
>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="0"
EnableIntrinsicFunctions="false"
EnableFunctionLevelLinking="false"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\crypto\cipher\aes_cbc.c"
>
</File>
<File
RelativePath=".\crypto\cipher\aes_icm.c"
>
</File>
<File
RelativePath=".\crypto\cipher\cipher.c"
>
</File>
<File
RelativePath=".\crypto\cipher\null_cipher.c"
>
</File>
</Filter>
<Filter
Name="Hashes"
>
<File
RelativePath=".\crypto\hash\auth.c"
>
</File>
<File
RelativePath=".\crypto\hash\hmac.c"
>
</File>
<File
RelativePath=".\crypto\hash\null_auth.c"
>
</File>
<File
RelativePath=".\crypto\hash\sha1.c"
>
</File>
</Filter>
<Filter
Name="Replay"
>
<File
RelativePath=".\crypto\replay\rdb.c"
>
</File>
<File
RelativePath=".\crypto\replay\rdbx.c"
>
</File>
<File
RelativePath=".\crypto\replay\ut_sim.c"
>
</File>
</Filter>
<Filter
Name="Math"
>
<File
RelativePath=".\crypto\math\datatypes.c"
>
</File>
<File
RelativePath=".\crypto\math\stat.c"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\crypto\include\aes.h"
>
</File>
<File
RelativePath=".\crypto\include\aes_cbc.h"
>
</File>
<File
RelativePath=".\crypto\include\aes_icm.h"
>
</File>
<File
RelativePath=".\crypto\include\alloc.h"
>
</File>
<File
RelativePath=".\crypto\include\auth.h"
>
</File>
<File
RelativePath=".\crypto\include\cipher.h"
>
</File>
<File
RelativePath=".\crypto\include\config.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_kernel.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_math.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_types.h"
>
</File>
<File
RelativePath=".\crypto\include\cryptoalg.h"
>
</File>
<File
RelativePath=".\crypto\include\datatypes.h"
>
</File>
<File
RelativePath=".\crypto\include\err.h"
>
</File>
<File
RelativePath=".\crypto\include\gf2_8.h"
>
</File>
<File
RelativePath=".\crypto\include\hmac.h"
>
</File>
<File
RelativePath=".\crypto\include\integers.h"
>
</File>
<File
RelativePath=".\crypto\include\kernel_compat.h"
>
</File>
<File
RelativePath=".\crypto\include\key.h"
>
</File>
<File
RelativePath=".\crypto\include\null_auth.h"
>
</File>
<File
RelativePath=".\crypto\include\null_cipher.h"
>
</File>
<File
RelativePath=".\crypto\include\prng.h"
>
</File>
<File
RelativePath=".\crypto\include\rand_source.h"
>
</File>
<File
RelativePath=".\crypto\include\rdb.h"
>
</File>
<File
RelativePath=".\crypto\include\rdbx.h"
>
</File>
<File
RelativePath=".\include\rtp.h"
>
</File>
<File
RelativePath=".\crypto\include\sha1.h"
>
</File>
<File
RelativePath=".\include\srtp.h"
>
</File>
<File
RelativePath=".\crypto\include\stat.h"
>
</File>
<File
RelativePath=".\include\ut_sim.h"
>
</File>
<File
RelativePath=".\crypto\include\xfm.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\srtp.def"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug Dll|Win32"> <ProjectConfiguration Include="Debug Dll|Win32">
@ -367,11 +367,8 @@
<ClCompile Include="srtp\srtp.c" /> <ClCompile Include="srtp\srtp.c" />
<ClCompile Include="crypto\kernel\alloc.c" /> <ClCompile Include="crypto\kernel\alloc.c" />
<ClCompile Include="crypto\kernel\crypto_kernel.c" /> <ClCompile Include="crypto\kernel\crypto_kernel.c" />
<ClCompile Include="crypto\rng\ctr_prng.c" />
<ClCompile Include="crypto\kernel\err.c" /> <ClCompile Include="crypto\kernel\err.c" />
<ClCompile Include="crypto\kernel\key.c" /> <ClCompile Include="crypto\kernel\key.c" />
<ClCompile Include="crypto\rng\prng.c" />
<ClCompile Include="crypto\rng\rand_source.c" />
<ClCompile Include="crypto\cipher\aes.c"> <ClCompile Include="crypto\cipher\aes.c">
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">Default</InlineFunctionExpansion> <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">Default</InlineFunctionExpansion>
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</IntrinsicFunctions> <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</IntrinsicFunctions>
@ -380,7 +377,6 @@
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</IntrinsicFunctions> <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</IntrinsicFunctions>
<FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</FunctionLevelLinking> <FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</FunctionLevelLinking>
</ClCompile> </ClCompile>
<ClCompile Include="crypto\cipher\aes_cbc.c" />
<ClCompile Include="crypto\cipher\cipher.c" /> <ClCompile Include="crypto\cipher\cipher.c" />
<ClCompile Include="crypto\cipher\null_cipher.c" /> <ClCompile Include="crypto\cipher\null_cipher.c" />
<ClCompile Include="crypto\hash\auth.c" /> <ClCompile Include="crypto\hash\auth.c" />
@ -393,7 +389,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="crypto\include\aes.h" /> <ClInclude Include="crypto\include\aes.h" />
<ClInclude Include="crypto\include\aes_cbc.h" />
<ClInclude Include="crypto\include\aes_gcm_ossl.h" /> <ClInclude Include="crypto\include\aes_gcm_ossl.h" />
<ClInclude Include="crypto\include\aes_icm.h" /> <ClInclude Include="crypto\include\aes_icm.h" />
<ClInclude Include="crypto\include\aes_icm_ossl.h" /> <ClInclude Include="crypto\include\aes_icm_ossl.h" />
@ -401,22 +396,15 @@
<ClInclude Include="crypto\include\auth.h" /> <ClInclude Include="crypto\include\auth.h" />
<ClInclude Include="crypto\include\cipher.h" /> <ClInclude Include="crypto\include\cipher.h" />
<ClInclude Include="crypto\include\config.h" /> <ClInclude Include="crypto\include\config.h" />
<ClInclude Include="crypto\include\crypto.h" />
<ClInclude Include="crypto\include\crypto_kernel.h" /> <ClInclude Include="crypto\include\crypto_kernel.h" />
<ClInclude Include="crypto\include\crypto_math.h" />
<ClInclude Include="crypto\include\crypto_types.h" /> <ClInclude Include="crypto\include\crypto_types.h" />
<ClInclude Include="crypto\include\cryptoalg.h" />
<ClInclude Include="crypto\include\datatypes.h" /> <ClInclude Include="crypto\include\datatypes.h" />
<ClInclude Include="crypto\include\err.h" /> <ClInclude Include="crypto\include\err.h" />
<ClInclude Include="crypto\include\gf2_8.h" />
<ClInclude Include="crypto\include\hmac.h" /> <ClInclude Include="crypto\include\hmac.h" />
<ClInclude Include="crypto\include\integers.h" /> <ClInclude Include="crypto\include\integers.h" />
<ClInclude Include="crypto\include\kernel_compat.h" />
<ClInclude Include="crypto\include\key.h" /> <ClInclude Include="crypto\include\key.h" />
<ClInclude Include="crypto\include\null_auth.h" /> <ClInclude Include="crypto\include\null_auth.h" />
<ClInclude Include="crypto\include\null_cipher.h" /> <ClInclude Include="crypto\include\null_cipher.h" />
<ClInclude Include="crypto\include\prng.h" />
<ClInclude Include="crypto\include\rand_source.h" />
<ClInclude Include="crypto\include\rdb.h" /> <ClInclude Include="crypto\include\rdb.h" />
<ClInclude Include="crypto\include\rdbx.h" /> <ClInclude Include="crypto\include\rdbx.h" />
<ClInclude Include="include\rtp.h" /> <ClInclude Include="include\rtp.h" />
@ -424,7 +412,6 @@
<ClInclude Include="include\srtp.h" /> <ClInclude Include="include\srtp.h" />
<ClInclude Include="crypto\include\stat.h" /> <ClInclude Include="crypto\include\stat.h" />
<ClInclude Include="include\ut_sim.h" /> <ClInclude Include="include\ut_sim.h" />
<ClInclude Include="crypto\include\xfm.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="srtp.def" /> <None Include="srtp.def" />
@ -437,4 +424,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -1,592 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="libsrtp"
ProjectGUID="{EEF031CB-FED8-451E-A471-91EC8D4F6750}"
RootNamespace="libsrtp"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug Dll|Win32"
OutputDirectory="$(SolutionDir)Debug"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;HAVE_CONFIG_H"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
OptimizeReferences="1"
EnableCOMDATFolding="1"
OptimizeForWindows98="1"
LinkTimeCodeGeneration="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release Dll|Win32"
OutputDirectory="$(SolutionDir)Release"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Creating config.h from config.hw"
CommandLine="copy /Y &quot;$(InputDir)config.hw&quot; &quot;$(InputDir)crypto\include\config.h&quot; &gt; NUL"
/>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="crypto/include;include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_CONFIG_H"
RuntimeLibrary="2"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Ws2_32.lib"
ModuleDefinitionFile="srtp.def"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\srtp\srtp.c"
>
</File>
<Filter
Name="Kernel"
>
<File
RelativePath=".\crypto\kernel\alloc.c"
>
</File>
<File
RelativePath=".\crypto\kernel\crypto_kernel.c"
>
</File>
<File
RelativePath=".\crypto\rng\ctr_prng.c"
>
</File>
<File
RelativePath=".\crypto\kernel\err.c"
>
</File>
<File
RelativePath=".\crypto\kernel\key.c"
>
</File>
<File
RelativePath=".\crypto\rng\prng.c"
>
</File>
<File
RelativePath=".\crypto\rng\rand_source.c"
>
</File>
</Filter>
<Filter
Name="Ciphers"
>
<File
RelativePath=".\crypto\cipher\aes.c"
>
<FileConfiguration
Name="Debug Dll|Win32"
>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="0"
EnableIntrinsicFunctions="false"
EnableFunctionLevelLinking="false"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\crypto\cipher\aes_cbc.c"
>
</File>
<File
RelativePath=".\crypto\cipher\aes_icm.c"
>
</File>
<File
RelativePath=".\crypto\cipher\cipher.c"
>
</File>
<File
RelativePath=".\crypto\cipher\null_cipher.c"
>
</File>
</Filter>
<Filter
Name="Hashes"
>
<File
RelativePath=".\crypto\hash\auth.c"
>
</File>
<File
RelativePath=".\crypto\hash\hmac.c"
>
</File>
<File
RelativePath=".\crypto\hash\null_auth.c"
>
</File>
<File
RelativePath=".\crypto\hash\sha1.c"
>
</File>
</Filter>
<Filter
Name="Replay"
>
<File
RelativePath=".\crypto\replay\rdb.c"
>
</File>
<File
RelativePath=".\crypto\replay\rdbx.c"
>
</File>
<File
RelativePath=".\crypto\replay\ut_sim.c"
>
</File>
</Filter>
<Filter
Name="Math"
>
<File
RelativePath=".\crypto\math\datatypes.c"
>
</File>
<File
RelativePath=".\crypto\math\stat.c"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\crypto\include\aes.h"
>
</File>
<File
RelativePath=".\crypto\include\aes_cbc.h"
>
</File>
<File
RelativePath=".\crypto\include\aes_icm.h"
>
</File>
<File
RelativePath=".\crypto\include\alloc.h"
>
</File>
<File
RelativePath=".\crypto\include\auth.h"
>
</File>
<File
RelativePath=".\crypto\include\cipher.h"
>
</File>
<File
RelativePath=".\crypto\include\config.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_kernel.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_math.h"
>
</File>
<File
RelativePath=".\crypto\include\crypto_types.h"
>
</File>
<File
RelativePath=".\crypto\include\cryptoalg.h"
>
</File>
<File
RelativePath=".\crypto\include\datatypes.h"
>
</File>
<File
RelativePath=".\crypto\include\err.h"
>
</File>
<File
RelativePath=".\crypto\include\gf2_8.h"
>
</File>
<File
RelativePath=".\crypto\include\hmac.h"
>
</File>
<File
RelativePath=".\crypto\include\integers.h"
>
</File>
<File
RelativePath=".\crypto\include\kernel_compat.h"
>
</File>
<File
RelativePath=".\crypto\include\key.h"
>
</File>
<File
RelativePath=".\crypto\include\null_auth.h"
>
</File>
<File
RelativePath=".\crypto\include\null_cipher.h"
>
</File>
<File
RelativePath=".\crypto\include\prng.h"
>
</File>
<File
RelativePath=".\crypto\include\rand_source.h"
>
</File>
<File
RelativePath=".\crypto\include\rdb.h"
>
</File>
<File
RelativePath=".\crypto\include\rdbx.h"
>
</File>
<File
RelativePath=".\include\rtp.h"
>
</File>
<File
RelativePath=".\crypto\include\sha1.h"
>
</File>
<File
RelativePath=".\include\srtp.h"
>
</File>
<File
RelativePath=".\crypto\include\stat.h"
>
</File>
<File
RelativePath=".\include\ut_sim.h"
>
</File>
<File
RelativePath=".\crypto\include\xfm.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\srtp.def"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

11
libs/srtp/libsrtp2.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@prefix@
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Version: @PACKAGE_VERSION@
Description: Library for SRTP (Secure Realtime Transport Protocol)
Libs: -L${libdir} -lsrtp2 @LIBS@
Cflags: -I${includedir}

View File

@ -1,91 +1,65 @@
EXPORTS EXPORTS
srtp_init srtp_init
srtp_shutdown
srtp_protect srtp_protect
srtp_unprotect srtp_unprotect
srtp_create srtp_create
srtp_add_stream srtp_add_stream
srtp_remove_stream srtp_remove_stream
crypto_policy_set_rtp_default srtp_update
crypto_policy_set_rtcp_default srtp_update_stream
crypto_policy_set_aes_cm_128_hmac_sha1_32 srtp_crypto_policy_set_rtp_default
crypto_policy_set_aes_cm_128_null_auth srtp_crypto_policy_set_rtcp_default
crypto_policy_set_null_cipher_hmac_sha1_80 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32
srtp_crypto_policy_set_aes_cm_128_null_auth
srtp_crypto_policy_set_null_cipher_hmac_sha1_80
srtp_crypto_policy_set_null_cipher_hmac_null
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32
srtp_crypto_policy_set_aes_cm_256_null_auth
; TODO - GCM module not yet supported on Win32
; srtp_crypto_policy_set_aes_gcm_128_8_auth
; srtp_crypto_policy_set_aes_gcm_256_8_auth
; srtp_crypto_policy_set_aes_gcm_128_8_only_auth
; srtp_crypto_policy_set_aes_gcm_256_8_only_auth
; srtp_crypto_policy_set_aes_gcm_128_16_auth
; srtp_crypto_policy_set_aes_gcm_256_16_auth
srtp_dealloc srtp_dealloc
srtp_get_stream srtp_crypto_policy_set_from_profile_for_rtp
srtp_crypto_policy_set_from_profile_for_rtcp
srtp_profile_get_master_key_length
srtp_profile_get_master_salt_length
srtp_append_salt_to_key
srtp_protect_rtcp srtp_protect_rtcp
srtp_unprotect_rtcp srtp_unprotect_rtcp
srtp_set_user_data
srtp_get_user_data
srtp_install_event_handler srtp_install_event_handler
crypto_kernel_init srtp_get_version_string
crypto_kernel_shutdown srtp_get_version
crypto_kernel_status srtp_set_debug_module
crypto_kernel_list_debug_modules srtp_list_debug_modules
crypto_kernel_load_cipher_type srtp_ekt_octets_after_base_tag
crypto_kernel_load_auth_type srtp_ekt_alloc
crypto_kernel_load_debug_module srtp_ekt_stream_init_from_policy
crypto_kernel_alloc_cipher srtp_ekt_write_data
crypto_kernel_alloc_auth srtp_cipher_get_key_length
crypto_kernel_set_debug_module srtp_cipher_type_self_test
crypto_get_random srtp_cipher_type_test
rand_source_init srtp_cipher_bits_per_second
rand_source_get_octet_string srtp_cipher_type_alloc
rand_source_deinit srtp_cipher_dealloc
x917_prng_init srtp_cipher_init
x917_prng_get_octet_string srtp_cipher_set_iv
ctr_prng_init srtp_cipher_output
ctr_prng_get_octet_string srtp_cipher_encrypt
cipher_output srtp_cipher_decrypt
cipher_get_key_length srtp_cipher_get_tag
cipher_type_self_test srtp_cipher_set_aad
cipher_bits_per_second srtp_replace_cipher_type
auth_get_key_length srtp_auth_get_key_length
auth_get_tag_length srtp_auth_get_tag_length
auth_get_prefix_length srtp_auth_get_prefix_length
auth_type_self_test srtp_auth_type_self_test
auth_type_get_ref_count srtp_auth_type_test
stat_test_monobit srtp_replace_auth_type
stat_test_poker
stat_test_runs
stat_test_rand_source
stat_test_rand_source_with_repetition
err_reporting_init
err_report
key_limit_set
key_limit_clone
key_limit_check
key_limit_update
rdbx_init
rdbx_estimate_index
rdbx_check
rdbx_add_index
index_init
index_advance
index_guess
octet_get_weight
octet_string_hex_string
v128_bit_string
v128_hex_string
nibble_to_hex_char
hex_string_to_octet_string
v128_copy_octet_string
v128_left_shift
v128_right_shift
octet_string_is_eq
octet_string_set_to_zero
rdb_init
rdb_check
rdb_add_index
rdb_increment
rdb_get_value
aes_expand_encryption_key
aes_expand_decryption_key
aes_encrypt
aes_decrypt
aes_icm_context_init
aes_icm_set_iv
aes_icm_encrypt
aes_icm_output
aes_icm_dealloc
aes_icm_encrypt_ismacryp
aes_icm_alloc_ismacryp
crypto_alloc
crypto_free

Some files were not shown because too many files have changed in this diff Show More