FS-9785: upgrade libsrtp to 2.1
This commit is contained in:
parent
19e8621682
commit
3bcf5b7ff8
|
@ -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 \
|
||||
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/hmac.c libs/srtp/crypto/hash/auth.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/key.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/kernel/key.c libs/srtp/crypto/kernel/err.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)
|
||||
|
|
|
@ -1,223 +1,167 @@
|
|||
Changelog
|
||||
|
||||
1.3.20
|
||||
2.1.0
|
||||
|
||||
Lots of changes. Thanks to Jeff Chan for catching a memory leak and
|
||||
helping track down the endian issues with the SSRCs.
|
||||
Compatibility changes
|
||||
|
||||
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
|
||||
and fixed; this means that we can use intel/linux for development again.
|
||||
PR #259 - Sequence number incorrectly masked for AES GCM IV
|
||||
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
|
||||
functions and properly documented the fuctions in the .h files.
|
||||
PR #287 - Fix OOB read in key generation for encrypted headers with GCM ciphers
|
||||
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
|
||||
(observed on both solaris and openbsd) with gcc 2.95. Was unable to
|
||||
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.
|
||||
PR #204 - OpenSSL performance improvements
|
||||
Changed key expansion to occur once per key instead of once per packet.
|
||||
|
||||
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
|
||||
network byte ordering, and is consistent with other arguments.
|
||||
PR #224 - Master Key Identifiers (MKI) Support patch
|
||||
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
|
||||
/dev/urandom; the latter is non-blocking on all known platforms (which
|
||||
corrects some programs that seem to hang) and is actually present on
|
||||
Open BSD (unlike /dev/random, which only works in the presence of
|
||||
hardware supported random number generation).
|
||||
PR #241 & PR #261 - Improved logging API to receive log messages from libSRTP
|
||||
Provides a logging API and the ability to enable logging to stdout and a
|
||||
file, as well as a switch to enable all internal debug modules.
|
||||
|
||||
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
|
||||
policy (including SRTCP).
|
||||
PR #149 - Don't create a symlink if there is no $(SHAREDLIBVERSION)
|
||||
|
||||
This version is *incomplete* and will undergo more changes. It is
|
||||
provided only as a basis for discussion.
|
||||
PR #151 - Make srtp_driver compile for MIPS
|
||||
|
||||
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
|
||||
sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should
|
||||
usually be used rather than that function.
|
||||
PR #169 - Identified merge conflict created by commit 6b71fb9
|
||||
|
||||
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
|
||||
are defined in crypto/kernel/alloc.c and declared in
|
||||
include/alloc.h.
|
||||
PR #175 - Remove 2nd -fPIC
|
||||
|
||||
Added 'output' functions to cipher, in addition to 'encrypt'
|
||||
functions. It is no longer necessary to zeroize a buffer before
|
||||
encrypting in order to get keystream.
|
||||
PR #182 - Add a length check before reading packet data
|
||||
|
||||
Changed octet_string_hex_string() so that "times two" isn't needed
|
||||
in its input.
|
||||
PR #191 - On debug, output correct endianness of SSRC
|
||||
|
||||
Added crypto_kernel_init() prior to command-line parsing, so that
|
||||
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.
|
||||
PR #192 - Replace octet_string_is_eq with a constant-time implementation
|
||||
|
||||
Improved srtp_init_aes_128_prf - wrote key derivation function
|
||||
(srtp_kdf_t).
|
||||
PR #195 - Add missing __cplusplus header guards
|
||||
|
||||
Add the tag_len as an argument to the auth_compute() function, but
|
||||
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.
|
||||
PR #198 - Update sha1_driver.c to avoid memory leaks
|
||||
|
||||
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
|
||||
OS, then it is used.
|
||||
PR #213 - Add cast to `unsigned int` in call to printf in test
|
||||
|
||||
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
|
||||
rtp_sendto() in srtp/rtp.c.
|
||||
PR #231 - Advance version on master in preparation for 2.1 release
|
||||
|
||||
Implemented RIJNDAEL decryption operation, adding the functions
|
||||
rijndael_decrypt() and rijndael_expand_decryption_key(). Also
|
||||
re-named rijndael_expand_key() to rijndael_expand_encryption_key()
|
||||
for consistency.
|
||||
PR #232 - Update Travis, do not build with OpenSSL on OSX
|
||||
|
||||
Implemented random number source using /dev/random, in the files
|
||||
crypto/rng/rand_source.c and include/rand_source.h.
|
||||
PR #233 - crypto/replay/rdbx.c: Return type of srtp_index_guess from int to
|
||||
int32_t
|
||||
|
||||
Added index check to SEAL cipher (only values less than 2^32 are
|
||||
allowed)
|
||||
PR #236 - test/rtp_decoder.c: Removed superfluous conditional
|
||||
|
||||
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
|
||||
cipher throughput. The test is done by the function
|
||||
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.
|
||||
PR #239 - octet_string_set_to_zero() delegates to OPENSSL_cleanse() if
|
||||
available, if not it will use srtp_cleanse() to zero memory
|
||||
|
||||
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()
|
||||
after buffer allocation.
|
||||
PR #246 - test/rtp_decoder: Add missing conditional
|
||||
|
||||
Eliminated references to no-longer-existing variables in debugging
|
||||
code in srtp/srtp.c. This fixes the compilation failure that
|
||||
occured when using PRINT_DEBUG in that file.
|
||||
PR #248 - New README.md that integrates intro, credits and references from
|
||||
/doc/ and is used to generate documentation
|
||||
|
||||
Corrected spelling of Richard Priestley's name in credits. Sorry
|
||||
Richard!
|
||||
PR #249 - Remove support for generic aesicm from configure.in
|
||||
|
||||
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
|
||||
more zero octet than it should. This bug caused srtp_protect()
|
||||
and srtp_unprotect() to overwrite the byte that followed the
|
||||
srtp packet.
|
||||
PR #258 - Add AES-GCM to DTLS-SRTP Protection Profiles
|
||||
|
||||
Changed sizeof(uint32_t) to srtp_get_trailer_length() in
|
||||
srtp-driver.c. This is just defensive coding.
|
||||
PR #263 - Cleaning up and removing duplicated and outdated code
|
||||
|
||||
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
|
||||
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.
|
||||
PR #273 - SRTP AEAD SRTCP initialization vector regression tests
|
||||
|
||||
Removed the GDOI interface to the rtpw demo program. This will be
|
||||
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.
|
||||
PR #274 - Update Travis build - add ccache
|
||||
|
||||
Updated tmmhv2_compute() so that it didn't assume any particular
|
||||
alginment of the output tag.
|
||||
PR #276 - Reference and docs updates
|
||||
|
||||
Changed bit field variables in srtp.h to unsigned char from
|
||||
unsigned int in order to avoid a potential endianness issue.
|
||||
PR #278 - Removed crypto/test/auth_driver.c and test/lfsr.c
|
||||
|
||||
Fixed rdbx_estimate_index() to handle all input cases. This solves
|
||||
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.
|
||||
PR #279 - Bump copyright year
|
||||
|
||||
Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed
|
||||
from rijndael_icm_set_segment().
|
||||
PR #283 - Add missing docs in srtp.h
|
||||
|
||||
Added error checking and handling to srtp_sender_init() and
|
||||
srtp_receiver_init().
|
||||
PR #284 - Add strict-prototypes warning if supported
|
||||
|
||||
Changed srtp_alloc() so that it does what you'd expect: allocate an
|
||||
srtp_ctx_t structure. This hides the library internals.
|
||||
PR #291 - Use const char * for srtp_set_debug_module()
|
||||
|
||||
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
|
||||
function checks that the byte-buffering functions used by a cipher
|
||||
are correct.
|
||||
PR #301 - Configure fixes
|
||||
|
||||
Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and
|
||||
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 #302 - Fix warning regarding unused variable
|
||||
|
||||
PR #303 - Makefile.in: Add gnu as match for shared lib suffix
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
AUTOMAKE_OPTIONS = gnu
|
||||
AUTOMAKE_OPTIONS = gnu subdir-objects
|
||||
NAME=srtp
|
||||
|
||||
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.
|
||||
|
||||
HMAC_OBJS = @HMAC_OBJS@
|
||||
RNG_EXTRA_OBJS = @RNG_EXTRA_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 \
|
||||
crypto/hash/null_auth.c crypto/hash/auth.c \
|
||||
crypto/math/datatypes.c crypto/math/stat.c \
|
||||
|
@ -24,39 +23,24 @@ EXTRA_DIST=
|
|||
|
||||
if ENABLE_OPENSSL
|
||||
libsrtp_la_SOURCES += crypto/cipher/aes_icm_ossl.c crypto/cipher/aes_gcm_ossl.c
|
||||
libsrtp_la_SOURCES += crypto/rng/rand_source_ossl.c
|
||||
libsrtp_la_SOURCES += crypto/hash/hmac_ossl.c
|
||||
else
|
||||
libsrtp_la_SOURCES += crypto/hash/sha1.c crypto/hash/hmac.c
|
||||
libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c crypto/cipher/aes_cbc.c
|
||||
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
|
||||
libsrtp_la_SOURCES += crypto/cipher/aes_icm.c crypto/cipher/aes.c
|
||||
endif
|
||||
|
||||
if GDOI
|
||||
libsrtp_la_SOURCES += gdoi/srtp+gdoi.c
|
||||
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_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/include/aes_cbc.h crypto/include/auth.h \
|
||||
crypto/include/crypto_math.h crypto/include/datatypes.h crypto/include/integers.h crypto/include/null_cipher.h \
|
||||
library_include_HEADERS = include/rtp.h include/srtp.h include/ut_sim.h crypto/include/auth.h \
|
||||
crypto/include/datatypes.h crypto/include/integers.h crypto/include/null_cipher.h \
|
||||
crypto/include/rdbx.h crypto/include/aes_icm.h crypto/include/cipher.h crypto/include/crypto_types.h \
|
||||
crypto/include/err.h crypto/include/kernel_compat.h crypto/include/prng.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/rand_source.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
|
||||
|
||||
noinst_PROGRAMS = aes_tables
|
||||
aes_tables_SOURCES = tables/aes_tables.c
|
||||
aes_tables_LDADD = libcryptomath.la
|
||||
crypto/include/err.h crypto/include/sha1.h \
|
||||
crypto/include/aes.h crypto/include/config.h crypto/include/key.h \
|
||||
crypto/include/stat.h crypto/include/alloc.h crypto/include/crypto_kernel.h \
|
||||
crypto/include/hmac.h crypto/include/null_auth.h crypto/include/rdb.h
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = srtp-1.42.pc
|
||||
|
|
|
@ -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)
|
|
@ -1 +1 @@
|
|||
1.4.5
|
||||
2.1.0-pre
|
||||
|
|
|
@ -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
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#if (_MSC_VER >= 1400)
|
||||
# define HAVE_RAND_S 1
|
||||
# define _CRT_RAND_S
|
||||
#endif
|
||||
|
||||
/* 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). */
|
||||
/* #undef CPU_RISC */
|
||||
|
||||
/* Path to random device */
|
||||
/* #define DEV_URANDOM "/dev/urandom" */
|
||||
/* Define to enabled debug logging for all mudules. */
|
||||
#undef ENABLE_DEBUG_LOGGING
|
||||
|
||||
/* Define to compile in dynamic debugging system. */
|
||||
#define ENABLE_DEBUGGING 1
|
||||
|
||||
/* Report errors to this file. */
|
||||
/* Logging statments will be writen to this file. */
|
||||
/* #undef ERR_REPORTING_FILE */
|
||||
|
||||
/* Define to use logging to stdout. */
|
||||
#define ERR_REPORTING_STDOUT 1
|
||||
|
||||
/* Define this to use ISMAcryp code. */
|
||||
/* #undef GENERIC_AESICM */
|
||||
/* 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 */
|
||||
|
@ -74,9 +69,6 @@
|
|||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#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. */
|
||||
/* #undef HAVE_SYS_INT_TYPES_H */
|
||||
|
||||
|
@ -152,12 +144,6 @@
|
|||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#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
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
|
|
@ -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
|
|
@ -266,7 +266,6 @@ if test "$enable_openssl" = "yes"; then
|
|||
[AC_MSG_FAILURE([can't find openssl >1.0.1 crypto lib])])
|
||||
AC_DEFINE(OPENSSL, 1, [Define this to use OpenSSL crypto.])
|
||||
AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o"
|
||||
RNG_OBJS=rand_source_ossl.o
|
||||
HMAC_OBJS=crypto/hash/hmac_ossl.o
|
||||
USE_OPENSSL=1
|
||||
AC_SUBST(USE_OPENSSL)
|
||||
|
@ -275,10 +274,8 @@ else
|
|||
AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o crypto/cipher/aes_cbc.o"
|
||||
AC_MSG_CHECKING(which random device to use)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
RNG_OBJS=rand_linux_kernel.o
|
||||
AC_MSG_RESULT([Linux kernel builtin])
|
||||
else
|
||||
RNG_OBJS=rand_source.o
|
||||
if test -n "$DEV_URANDOM"; then
|
||||
AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device])
|
||||
AC_MSG_RESULT([$DEV_URANDOM])
|
||||
|
@ -286,15 +283,11 @@ else
|
|||
AC_MSG_RESULT([standard rand() function...])
|
||||
fi
|
||||
fi
|
||||
RNG_EXTRA_OBJS="crypto/rng/prng.o crypto/rng/ctr_prng.o"
|
||||
HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
|
||||
fi
|
||||
AM_CONDITIONAL([ENABLE_OPENSSL],[test "${enable_openssl}" = "yes"])
|
||||
AM_CONDITIONAL([RNG_OBJS_LINUX], test x$enable_kernel_linux = xyes)
|
||||
|
||||
AC_SUBST(AES_ICM_OBJS)
|
||||
AC_SUBST(RNG_OBJS)
|
||||
AC_SUBST(RNG_EXTRA_OBJS)
|
||||
AC_SUBST(HMAC_OBJS)
|
||||
AC_MSG_RESULT($enable_openssl)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
# This is needed when building outside the source dir.
|
||||
AS_MKDIR_P(crypto/ae_xfm)
|
||||
AS_MKDIR_P(crypto/cipher)
|
||||
AS_MKDIR_P(crypto/hash)
|
||||
AS_MKDIR_P(crypto/kernel)
|
||||
AS_MKDIR_P(crypto/math)
|
||||
AS_MKDIR_P(crypto/replay)
|
||||
AS_MKDIR_P(crypto/rng)
|
||||
AS_MKDIR_P(crypto/test)
|
||||
AS_MKDIR_P(doc)
|
||||
AS_MKDIR_P(srtp)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Makefile
|
|
@ -1 +0,0 @@
|
|||
1.0.0
|
|
@ -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
|
@ -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
|
||||
};
|
||||
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2013, Cisco Systems, Inc.
|
||||
* Copyright (c) 2013-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 "aes_icm_ossl.h"
|
||||
#include "aes_gcm_ossl.h"
|
||||
#include "alloc.h"
|
||||
#include "err.h" /* for srtp_debug */
|
||||
#include "crypto_types.h"
|
||||
|
||||
|
||||
debug_module_t mod_aes_gcm = {
|
||||
srtp_debug_module_t srtp_mod_aes_gcm = {
|
||||
0, /* debugging is off by default */
|
||||
"aes gcm" /* printable module name */
|
||||
};
|
||||
|
@ -60,12 +65,12 @@ debug_module_t mod_aes_gcm = {
|
|||
* The following are the global singleton instances for the
|
||||
* 128-bit and 256-bit GCM ciphers.
|
||||
*/
|
||||
extern cipher_type_t aes_gcm_128_openssl;
|
||||
extern cipher_type_t aes_gcm_256_openssl;
|
||||
extern const srtp_cipher_type_t srtp_aes_gcm_128_openssl;
|
||||
extern const srtp_cipher_type_t srtp_aes_gcm_256_openssl;
|
||||
|
||||
/*
|
||||
* For now we only support 8 and 16 octet tags. The spec allows for
|
||||
* optional 12 byte tag, which may be supported in the future.
|
||||
* optional 12 byte tag, which may be supported in the future.
|
||||
*/
|
||||
#define GCM_AUTH_TAG_LEN 16
|
||||
#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.
|
||||
* 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
|
||||
* 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;
|
||||
int tmp;
|
||||
uint8_t *allptr;
|
||||
srtp_aes_gcm_ctx_t *gcm;
|
||||
|
||||
debug_print(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 key length %d", key_len);
|
||||
debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
|
||||
|
||||
/*
|
||||
* Verify the key_len is valid for one of: AES-128/256
|
||||
*/
|
||||
if (key_len != AES_128_GCM_KEYSIZE_WSALT &&
|
||||
key_len != AES_256_GCM_KEYSIZE_WSALT) {
|
||||
return (err_status_bad_param);
|
||||
if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
|
||||
key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
|
||||
return (srtp_err_status_bad_param);
|
||||
}
|
||||
|
||||
if (tlen != GCM_AUTH_TAG_LEN &&
|
||||
tlen != GCM_AUTH_TAG_LEN_8) {
|
||||
return (err_status_bad_param);
|
||||
tlen != GCM_AUTH_TAG_LEN_8) {
|
||||
return (srtp_err_status_bad_param);
|
||||
}
|
||||
|
||||
/* allocate memory a cipher of type aes_gcm */
|
||||
tmp = sizeof(cipher_t) + sizeof(aes_gcm_ctx_t);
|
||||
allptr = crypto_alloc(tmp);
|
||||
if (allptr == NULL) {
|
||||
return (err_status_alloc_fail);
|
||||
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
|
||||
if (*c == NULL) {
|
||||
return (srtp_err_status_alloc_fail);
|
||||
}
|
||||
memset(*c, 0x0, sizeof(srtp_cipher_t));
|
||||
|
||||
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 */
|
||||
*c = (cipher_t*)allptr;
|
||||
(*c)->state = allptr + sizeof(cipher_t);
|
||||
gcm = (aes_gcm_ctx_t *)(*c)->state;
|
||||
(*c)->state = gcm;
|
||||
|
||||
/* increment ref_count */
|
||||
/* setup cipher attributes */
|
||||
switch (key_len) {
|
||||
case AES_128_GCM_KEYSIZE_WSALT:
|
||||
(*c)->type = &aes_gcm_128_openssl;
|
||||
(*c)->algorithm = AES_128_GCM;
|
||||
aes_gcm_128_openssl.ref_count++;
|
||||
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
|
||||
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
|
||||
case SRTP_AES_GCM_128_KEY_LEN_WSALT:
|
||||
(*c)->type = &srtp_aes_gcm_128_openssl;
|
||||
(*c)->algorithm = SRTP_AES_GCM_128;
|
||||
gcm->key_size = SRTP_AES_128_KEY_LEN;
|
||||
gcm->tag_len = tlen;
|
||||
break;
|
||||
case AES_256_GCM_KEYSIZE_WSALT:
|
||||
(*c)->type = &aes_gcm_256_openssl;
|
||||
(*c)->algorithm = AES_256_GCM;
|
||||
aes_gcm_256_openssl.ref_count++;
|
||||
((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
|
||||
((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen;
|
||||
case SRTP_AES_GCM_256_KEY_LEN_WSALT:
|
||||
(*c)->type = &srtp_aes_gcm_256_openssl;
|
||||
(*c)->algorithm = SRTP_AES_GCM_256;
|
||||
gcm->key_size = SRTP_AES_256_KEY_LEN;
|
||||
gcm->tag_len = tlen;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set key size */
|
||||
(*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) {
|
||||
EVP_CIPHER_CTX_cleanup(&ctx->ctx);
|
||||
/* decrement ref_count for the appropriate engine */
|
||||
switch (ctx->key_size) {
|
||||
case AES_256_KEYSIZE:
|
||||
aes_gcm_256_openssl.ref_count--;
|
||||
break;
|
||||
case AES_128_KEYSIZE:
|
||||
aes_gcm_128_openssl.ref_count--;
|
||||
break;
|
||||
default:
|
||||
return (err_status_dealloc_fail);
|
||||
break;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
/* zeroize the key material */
|
||||
octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
|
||||
srtp_crypto_free(ctx);
|
||||
}
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t*)c, sizeof(cipher_t) + sizeof(aes_gcm_ctx_t));
|
||||
|
||||
/* 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
|
||||
*/
|
||||
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 */
|
||||
v128_copy_octet_string((v128_t*)&c->key, key);
|
||||
c->dir = srtp_direction_any;
|
||||
|
||||
if (c->key_size == AES_256_KEYSIZE) {
|
||||
debug_print(mod_aes_gcm, "Copying last 16 bytes of key: %s",
|
||||
v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
|
||||
v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1,
|
||||
key + AES_128_KEYSIZE);
|
||||
debug_print(srtp_mod_aes_gcm, "key: %s", srtp_octet_string_hex_string(key, c->key_size));
|
||||
|
||||
switch (c->key_size) {
|
||||
case SRTP_AES_256_KEY_LEN:
|
||||
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 (err_status_ok);
|
||||
return (srtp_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
|
||||
* the offset
|
||||
*/
|
||||
err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv,
|
||||
int direction)
|
||||
static srtp_err_status_t srtp_aes_gcm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
|
||||
{
|
||||
const EVP_CIPHER *evp;
|
||||
v128_t *nonce = iv;
|
||||
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
|
||||
|
||||
if (direction != direction_encrypt && direction != direction_decrypt) {
|
||||
return (err_status_bad_param);
|
||||
if (direction != srtp_direction_encrypt && direction != srtp_direction_decrypt) {
|
||||
return (srtp_err_status_bad_param);
|
||||
}
|
||||
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) {
|
||||
case AES_256_KEYSIZE:
|
||||
evp = EVP_aes_256_gcm();
|
||||
break;
|
||||
case AES_128_KEYSIZE:
|
||||
evp = EVP_aes_128_gcm();
|
||||
break;
|
||||
default:
|
||||
return (err_status_bad_param);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8,
|
||||
NULL, (c->dir == direction_encrypt ? 1 : 0))) {
|
||||
return (err_status_init_fail);
|
||||
if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL,
|
||||
NULL, (c->dir == srtp_direction_encrypt ? 1 : 0))) {
|
||||
return (srtp_err_status_init_fail);
|
||||
}
|
||||
|
||||
/* set IV len and the IV value, the followiong 3 calls are required */
|
||||
if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
|
||||
return (err_status_init_fail);
|
||||
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
|
||||
return (srtp_err_status_init_fail);
|
||||
}
|
||||
if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) {
|
||||
return (err_status_init_fail);
|
||||
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, (void*)iv)) {
|
||||
return (srtp_err_status_init_fail);
|
||||
}
|
||||
if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) {
|
||||
return (err_status_init_fail);
|
||||
if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_IV_GEN, 0, (void*)iv)) {
|
||||
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_len length of aad buffer
|
||||
*/
|
||||
err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad,
|
||||
unsigned int aad_len)
|
||||
static srtp_err_status_t srtp_aes_gcm_openssl_set_aad (void *cv, const uint8_t *aad, uint32_t aad_len)
|
||||
{
|
||||
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* Set dummy tag, OpenSSL requires the Tag to be set before
|
||||
* processing AAD
|
||||
*/
|
||||
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad);
|
||||
|
||||
rv = EVP_Cipher(&c->ctx, NULL, aad, aad_len);
|
||||
/*
|
||||
* 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) {
|
||||
return (err_status_algo_fail);
|
||||
return (srtp_err_status_algo_fail);
|
||||
} 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
|
||||
* enc_len length of encrypt buffer
|
||||
*/
|
||||
err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf,
|
||||
unsigned int *enc_len)
|
||||
static srtp_err_status_t srtp_aes_gcm_openssl_encrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
|
||||
{
|
||||
if (c->dir != direction_encrypt && c->dir != direction_decrypt) {
|
||||
return (err_status_bad_param);
|
||||
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
|
||||
if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
|
||||
return (srtp_err_status_bad_param);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 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
|
||||
* 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
|
||||
* len length of encrypt buffer
|
||||
*/
|
||||
err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf,
|
||||
int *len)
|
||||
static srtp_err_status_t srtp_aes_gcm_openssl_get_tag (void *cv, uint8_t *buf, uint32_t *len)
|
||||
{
|
||||
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
|
||||
/*
|
||||
* Calculate the tag
|
||||
*/
|
||||
EVP_Cipher(&c->ctx, NULL, NULL, 0);
|
||||
EVP_Cipher(c->ctx, NULL, NULL, 0);
|
||||
|
||||
/*
|
||||
* Retreive the tag
|
||||
*/
|
||||
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf);
|
||||
EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf);
|
||||
|
||||
/*
|
||||
* Increase encryption length by desired tag size
|
||||
*/
|
||||
*len = c->tag_len;
|
||||
|
||||
return (err_status_ok);
|
||||
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
|
||||
* enc_len length of encrypt buffer
|
||||
*/
|
||||
err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf,
|
||||
unsigned int *enc_len)
|
||||
static srtp_err_status_t srtp_aes_gcm_openssl_decrypt (void *cv, unsigned char *buf, unsigned int *enc_len)
|
||||
{
|
||||
if (c->dir != direction_encrypt && c->dir != direction_decrypt) {
|
||||
return (err_status_bad_param);
|
||||
srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
|
||||
if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
|
||||
return (srtp_err_status_bad_param);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the tag before decrypting
|
||||
*/
|
||||
EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
|
||||
buf + (*enc_len - c->tag_len));
|
||||
EVP_Cipher(&c->ctx, buf, buf, *enc_len - c->tag_len);
|
||||
EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
|
||||
buf + (*enc_len - c->tag_len));
|
||||
EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len);
|
||||
|
||||
/*
|
||||
* Check the tag
|
||||
*/
|
||||
if (EVP_Cipher(&c->ctx, NULL, NULL, 0)) {
|
||||
return (err_status_auth_fail);
|
||||
if (EVP_Cipher(c->ctx, NULL, NULL, 0)) {
|
||||
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;
|
||||
|
||||
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
|
||||
*/
|
||||
char 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_128_openssl_description[] = "AES-128 GCM using openssl";
|
||||
static const char srtp_aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl";
|
||||
|
||||
|
||||
/*
|
||||
* KAT values for AES self-test. These
|
||||
* values we're derived from independent test code
|
||||
* values we're derived from independent test code
|
||||
* 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,
|
||||
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 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] = {
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88
|
||||
};
|
||||
|
||||
uint8_t aes_gcm_test_case_0_plaintext[60] = {
|
||||
static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] = {
|
||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
|
@ -405,13 +409,13 @@ uint8_t aes_gcm_test_case_0_plaintext[60] = {
|
|||
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,
|
||||
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,
|
||||
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
|
||||
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,
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_0a = {
|
||||
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_gcm_test_case_0_key, /* key */
|
||||
aes_gcm_test_case_0_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
aes_gcm_test_case_0_plaintext, /* plaintext */
|
||||
68, /* octets in ciphertext */
|
||||
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
aes_gcm_test_case_0_aad, /* AAD */
|
||||
static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
|
||||
SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_gcm_test_case_0_key, /* key */
|
||||
srtp_aes_gcm_test_case_0_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
|
||||
68, /* octets in ciphertext */
|
||||
srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
srtp_aes_gcm_test_case_0_aad, /* AAD */
|
||||
GCM_AUTH_TAG_LEN_8,
|
||||
NULL /* pointer to next testcase */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_0 = {
|
||||
AES_128_GCM_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_gcm_test_case_0_key, /* key */
|
||||
aes_gcm_test_case_0_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
aes_gcm_test_case_0_plaintext, /* plaintext */
|
||||
76, /* octets in ciphertext */
|
||||
aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
aes_gcm_test_case_0_aad, /* AAD */
|
||||
static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
|
||||
SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_gcm_test_case_0_key, /* key */
|
||||
srtp_aes_gcm_test_case_0_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
|
||||
76, /* octets in ciphertext */
|
||||
srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
srtp_aes_gcm_test_case_0_aad, /* AAD */
|
||||
GCM_AUTH_TAG_LEN,
|
||||
&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,
|
||||
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,
|
||||
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] = {
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
|
||||
0xde, 0xca, 0xf8, 0x88
|
||||
};
|
||||
|
||||
uint8_t aes_gcm_test_case_1_plaintext[60] = {
|
||||
static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] = {
|
||||
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
|
||||
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
|
||||
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
|
||||
|
@ -479,89 +483,85 @@ uint8_t aes_gcm_test_case_1_plaintext[60] = {
|
|||
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,
|
||||
0xab, 0xad, 0xda, 0xd2
|
||||
};
|
||||
|
||||
uint8_t aes_gcm_test_case_1_ciphertext[76] = {
|
||||
0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
|
||||
0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
|
||||
0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
|
||||
0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
|
||||
0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
|
||||
0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
|
||||
0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
|
||||
0x09, 0xc9, 0x86, 0xc1,
|
||||
static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
|
||||
0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
|
||||
0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
|
||||
0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
|
||||
0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
|
||||
0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
|
||||
0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
|
||||
0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
|
||||
0x09, 0xc9, 0x86, 0xc1,
|
||||
/* the last 16 bytes are the tag */
|
||||
0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
|
||||
0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
|
||||
0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_1a = {
|
||||
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_gcm_test_case_1_key, /* key */
|
||||
aes_gcm_test_case_1_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
aes_gcm_test_case_1_plaintext, /* plaintext */
|
||||
68, /* octets in ciphertext */
|
||||
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
aes_gcm_test_case_1_aad, /* AAD */
|
||||
static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
|
||||
SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_gcm_test_case_1_key, /* key */
|
||||
srtp_aes_gcm_test_case_1_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
|
||||
68, /* octets in ciphertext */
|
||||
srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
srtp_aes_gcm_test_case_1_aad, /* AAD */
|
||||
GCM_AUTH_TAG_LEN_8,
|
||||
NULL /* pointer to next testcase */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_gcm_test_case_1 = {
|
||||
AES_256_GCM_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_gcm_test_case_1_key, /* key */
|
||||
aes_gcm_test_case_1_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
aes_gcm_test_case_1_plaintext, /* plaintext */
|
||||
76, /* octets in ciphertext */
|
||||
aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
aes_gcm_test_case_1_aad, /* AAD */
|
||||
static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
|
||||
SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_gcm_test_case_1_key, /* key */
|
||||
srtp_aes_gcm_test_case_1_iv, /* packet index */
|
||||
60, /* octets in plaintext */
|
||||
srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
|
||||
76, /* octets in ciphertext */
|
||||
srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
|
||||
20, /* octets in AAD */
|
||||
srtp_aes_gcm_test_case_1_aad, /* AAD */
|
||||
GCM_AUTH_TAG_LEN,
|
||||
&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.
|
||||
*/
|
||||
cipher_type_t aes_gcm_128_openssl = {
|
||||
(cipher_alloc_func_t) aes_gcm_openssl_alloc,
|
||||
(cipher_dealloc_func_t) aes_gcm_openssl_dealloc,
|
||||
(cipher_init_func_t) aes_gcm_openssl_context_init,
|
||||
(cipher_set_aad_func_t) aes_gcm_openssl_set_aad,
|
||||
(cipher_encrypt_func_t) aes_gcm_openssl_encrypt,
|
||||
(cipher_decrypt_func_t) aes_gcm_openssl_decrypt,
|
||||
(cipher_set_iv_func_t) aes_gcm_openssl_set_iv,
|
||||
(cipher_get_tag_func_t) aes_gcm_openssl_get_tag,
|
||||
(char*) aes_gcm_128_openssl_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t*) &aes_gcm_test_case_0,
|
||||
(debug_module_t*) &mod_aes_gcm,
|
||||
(cipher_type_id_t) AES_128_GCM
|
||||
const srtp_cipher_type_t srtp_aes_gcm_128_openssl = {
|
||||
srtp_aes_gcm_openssl_alloc,
|
||||
srtp_aes_gcm_openssl_dealloc,
|
||||
srtp_aes_gcm_openssl_context_init,
|
||||
srtp_aes_gcm_openssl_set_aad,
|
||||
srtp_aes_gcm_openssl_encrypt,
|
||||
srtp_aes_gcm_openssl_decrypt,
|
||||
srtp_aes_gcm_openssl_set_iv,
|
||||
srtp_aes_gcm_openssl_get_tag,
|
||||
srtp_aes_gcm_128_openssl_description,
|
||||
&srtp_aes_gcm_test_case_0,
|
||||
SRTP_AES_GCM_128
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the vector function table for this crypto engine.
|
||||
*/
|
||||
cipher_type_t aes_gcm_256_openssl = {
|
||||
(cipher_alloc_func_t) aes_gcm_openssl_alloc,
|
||||
(cipher_dealloc_func_t) aes_gcm_openssl_dealloc,
|
||||
(cipher_init_func_t) aes_gcm_openssl_context_init,
|
||||
(cipher_set_aad_func_t) aes_gcm_openssl_set_aad,
|
||||
(cipher_encrypt_func_t) aes_gcm_openssl_encrypt,
|
||||
(cipher_decrypt_func_t) aes_gcm_openssl_decrypt,
|
||||
(cipher_set_iv_func_t) aes_gcm_openssl_set_iv,
|
||||
(cipher_get_tag_func_t) aes_gcm_openssl_get_tag,
|
||||
(char*) aes_gcm_256_openssl_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t*) &aes_gcm_test_case_1,
|
||||
(debug_module_t*) &mod_aes_gcm,
|
||||
(cipher_type_id_t) AES_256_GCM
|
||||
const srtp_cipher_type_t srtp_aes_gcm_256_openssl = {
|
||||
srtp_aes_gcm_openssl_alloc,
|
||||
srtp_aes_gcm_openssl_dealloc,
|
||||
srtp_aes_gcm_openssl_context_init,
|
||||
srtp_aes_gcm_openssl_set_aad,
|
||||
srtp_aes_gcm_openssl_encrypt,
|
||||
srtp_aes_gcm_openssl_decrypt,
|
||||
srtp_aes_gcm_openssl_set_iv,
|
||||
srtp_aes_gcm_openssl_get_tag,
|
||||
srtp_aes_gcm_256_openssl_description,
|
||||
&srtp_aes_gcm_test_case_1,
|
||||
SRTP_AES_GCM_256
|
||||
};
|
||||
|
||||
|
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,6 +43,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#define ALIGN_32 0
|
||||
|
||||
|
@ -50,17 +53,19 @@
|
|||
#include "alloc.h"
|
||||
|
||||
|
||||
debug_module_t mod_aes_icm = {
|
||||
0, /* debugging is off by default */
|
||||
"aes icm" /* printable module name */
|
||||
srtp_debug_module_t srtp_mod_aes_icm = {
|
||||
0, /* debugging is off by default */
|
||||
"aes icm" /* printable module name */
|
||||
};
|
||||
extern const srtp_cipher_type_t srtp_aes_icm_128;
|
||||
extern const srtp_cipher_type_t srtp_aes_icm_256;
|
||||
|
||||
/*
|
||||
* integer counter mode works as follows:
|
||||
*
|
||||
* 16 bits
|
||||
* <----->
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* | nonce | pakcet index | ctr |---+
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* |
|
||||
|
@ -71,16 +76,16 @@ debug_module_t mod_aes_icm = {
|
|||
* +---------+
|
||||
* | encrypt |
|
||||
* +---------+
|
||||
* |
|
||||
* |
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* | keystream block |<--+
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* | keystream block |<--+
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
*
|
||||
* All fields are big-endian
|
||||
*
|
||||
* ctr is the block counter, which increments from zero for
|
||||
* each packet (16 bits wide)
|
||||
*
|
||||
*
|
||||
* packet index is distinct for each packet (48 bits wide)
|
||||
*
|
||||
* nonce can be distinct across many uses of the same key, or
|
||||
|
@ -89,77 +94,77 @@ debug_module_t mod_aes_icm = {
|
|||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
|
||||
extern cipher_type_t aes_icm;
|
||||
uint8_t *pointer;
|
||||
int tmp;
|
||||
static srtp_err_status_t srtp_aes_icm_alloc (srtp_cipher_t **c, int key_len, int tlen)
|
||||
{
|
||||
srtp_aes_icm_ctx_t *icm;
|
||||
|
||||
debug_print(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);
|
||||
|
||||
/*
|
||||
* Ismacryp, for example, uses 16 byte key + 8 byte
|
||||
* salt so this function is called with key_len = 24.
|
||||
* The check for key_len = 30/38/46 does not apply. Our usage
|
||||
* of aes functions with key_len = values other than 30
|
||||
* has not broken anything. Don't know what would be the
|
||||
* effect of skipping this check for srtp in general.
|
||||
*/
|
||||
if (!(forIsmacryp && key_len > 16 && key_len < 30) &&
|
||||
key_len != 30 && key_len != 38 && key_len != 46)
|
||||
return err_status_bad_param;
|
||||
/*
|
||||
* The check for key_len = 30/46 does not apply. Our usage
|
||||
* of aes functions with key_len = values other than 30
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* allocate memory a cipher of type aes_icm */
|
||||
tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
|
||||
pointer = (uint8_t*)crypto_alloc(tmp);
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
/* allocate memory a cipher of type aes_icm */
|
||||
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
|
||||
if (*c == NULL) {
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
memset(*c, 0x0, sizeof(srtp_cipher_t));
|
||||
|
||||
/* set pointers */
|
||||
*c = (cipher_t *)pointer;
|
||||
switch (key_len) {
|
||||
case 46:
|
||||
(*c)->algorithm = AES_256_ICM;
|
||||
break;
|
||||
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);
|
||||
icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
|
||||
if (icm == NULL) {
|
||||
srtp_crypto_free(*c);
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
memset(icm, 0x0, sizeof(srtp_aes_icm_ctx_t));
|
||||
|
||||
/* increment ref_count */
|
||||
aes_icm.ref_count++;
|
||||
/* set pointers */
|
||||
(*c)->state = icm;
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
switch (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) {
|
||||
return aes_icm_alloc_ismacryp(c, key_len, 0);
|
||||
}
|
||||
static srtp_err_status_t srtp_aes_icm_dealloc (srtp_cipher_t *c)
|
||||
{
|
||||
srtp_aes_icm_ctx_t *ctx;
|
||||
|
||||
err_status_t
|
||||
aes_icm_dealloc(cipher_t *c) {
|
||||
extern cipher_type_t aes_icm;
|
||||
if (c == NULL) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)c,
|
||||
sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
|
||||
ctx = (srtp_aes_icm_ctx_t *)c->state;
|
||||
if (ctx) {
|
||||
/* zeroize the key material */
|
||||
octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
|
||||
srtp_crypto_free(ctx);
|
||||
}
|
||||
|
||||
/* free memory */
|
||||
crypto_free(c);
|
||||
/* free the cipher context */
|
||||
srtp_crypto_free(c);
|
||||
|
||||
/* decrement ref_count */
|
||||
aes_icm.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
@ -167,114 +172,57 @@ aes_icm_dealloc(cipher_t *c) {
|
|||
* aes_icm_context_init(...) initializes the aes_icm_context
|
||||
* 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
|
||||
* randomizes the starting point in the keystream
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) {
|
||||
err_status_t status;
|
||||
int base_key_len, copy_len;
|
||||
static srtp_err_status_t srtp_aes_icm_context_init (void *cv, const uint8_t *key)
|
||||
{
|
||||
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
|
||||
srtp_err_status_t status;
|
||||
int base_key_len, copy_len;
|
||||
|
||||
if (key_len > 16 && key_len < 30) /* Ismacryp */
|
||||
base_key_len = 16;
|
||||
else if (key_len == 30 || key_len == 38 || key_len == 46)
|
||||
base_key_len = key_len - 14;
|
||||
else
|
||||
return err_status_bad_param;
|
||||
if (c->key_size == SRTP_AES_ICM_128_KEY_LEN_WSALT || c->key_size == SRTP_AES_ICM_256_KEY_LEN_WSALT) {
|
||||
base_key_len = c->key_size - SRTP_SALT_LEN;
|
||||
} else{
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/*
|
||||
* set counter and initial values to 'offset' value, being careful not to
|
||||
* go past the end of the key buffer
|
||||
*/
|
||||
v128_set_to_zero(&c->counter);
|
||||
v128_set_to_zero(&c->offset);
|
||||
|
||||
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) {
|
||||
/*
|
||||
* set counter and initial values to 'offset' value, being careful not to
|
||||
* go past the end of the key buffer
|
||||
*/
|
||||
v128_set_to_zero(&c->counter);
|
||||
v128_set_to_zero(&c->offset);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* indicate that the keystream_buffer is empty */
|
||||
c->bytes_in_buffer = 0;
|
||||
copy_len = c->key_size - base_key_len;
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
* aes_icm_set_octet(c, i) sets the counter of the context which it is
|
||||
* passed so that the next octet of keystream that will be generated
|
||||
* is the ith octet
|
||||
*/
|
||||
debug_print(srtp_mod_aes_icm,
|
||||
"key: %s", srtp_octet_string_hex_string(key, base_key_len));
|
||||
debug_print(srtp_mod_aes_icm,
|
||||
"offset: %s", v128_hex_string(&c->offset));
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_octet(aes_icm_ctx_t *c,
|
||||
uint64_t octet_num) {
|
||||
/* expand key */
|
||||
status = srtp_aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
|
||||
if (status) {
|
||||
v128_set_to_zero(&c->counter);
|
||||
v128_set_to_zero(&c->offset);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
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 */
|
||||
/* indicate that the keystream_buffer is empty */
|
||||
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
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) {
|
||||
v128_t nonce;
|
||||
static srtp_err_status_t srtp_aes_icm_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t direction)
|
||||
{
|
||||
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
|
||||
v128_t nonce;
|
||||
|
||||
/* set nonce (for alignment) */
|
||||
v128_copy_octet_string(&nonce, iv);
|
||||
/* set nonce (for alignment) */
|
||||
v128_copy_octet_string(&nonce, iv);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"setting iv: %s", v128_hex_string(&nonce));
|
||||
|
||||
v128_xor(&c->counter, &c->offset, &nonce);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"set_counter: %s", v128_hex_string(&c->counter));
|
||||
debug_print(srtp_mod_aes_icm,
|
||||
"setting iv: %s", v128_hex_string(&nonce));
|
||||
|
||||
/* indicate that the keystream_buffer is empty */
|
||||
c->bytes_in_buffer = 0;
|
||||
v128_xor(&c->counter, &c->offset, &nonce);
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
static inline void
|
||||
aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
|
||||
/* fill buffer with new keystream */
|
||||
v128_copy(&c->keystream_buffer, &c->counter);
|
||||
aes_encrypt(&c->keystream_buffer, &c->expanded_key);
|
||||
c->bytes_in_buffer = sizeof(v128_t);
|
||||
static void srtp_aes_icm_advance (srtp_aes_icm_ctx_t *c)
|
||||
{
|
||||
/* fill buffer with new keystream */
|
||||
v128_copy(&c->keystream_buffer, &c->counter);
|
||||
srtp_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));
|
||||
|
||||
/* clock counter forward */
|
||||
debug_print(srtp_mod_aes_icm, "counter: %s",
|
||||
v128_hex_string(&c->counter));
|
||||
debug_print(srtp_mod_aes_icm, "ciphertext: %s",
|
||||
v128_hex_string(&c->keystream_buffer));
|
||||
|
||||
if (forIsmacryp) {
|
||||
uint32_t temp;
|
||||
//alex's clock counter forward
|
||||
temp = ntohl(c->counter.v32[3]);
|
||||
c->counter.v32[3] = htonl(++temp);
|
||||
} else {
|
||||
if (!++(c->counter.v8[15]))
|
||||
++(c->counter.v8[14]);
|
||||
}
|
||||
/* clock counter forward */
|
||||
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
|
||||
* 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
|
||||
* - loop over blocks, filling keystream_buffer and then
|
||||
* 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
|
||||
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *enc_len,
|
||||
int forIsmacryp) {
|
||||
unsigned int bytes_to_encr = *enc_len;
|
||||
unsigned int i;
|
||||
uint32_t *b;
|
||||
static srtp_err_status_t srtp_aes_icm_encrypt (void *cv,
|
||||
unsigned char *buf, unsigned int *enc_len)
|
||||
{
|
||||
srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t*)cv;
|
||||
unsigned int bytes_to_encr = *enc_len;
|
||||
unsigned int i;
|
||||
uint32_t *b;
|
||||
|
||||
/* check that there's enough segment left but not for ismacryp*/
|
||||
if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
|
||||
return err_status_terminus;
|
||||
/* check that there's enough segment left*/
|
||||
if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
|
||||
return srtp_err_status_terminus;
|
||||
}
|
||||
|
||||
debug_print(mod_aes_icm, "block index: %d",
|
||||
htons(c->counter.v16[7]));
|
||||
if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
|
||||
|
||||
/* deal with odd case of small bytes_to_encr */
|
||||
for (i = (sizeof(v128_t) - c->bytes_in_buffer);
|
||||
i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++)
|
||||
{
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
}
|
||||
debug_print(srtp_mod_aes_icm, "block index: %d",
|
||||
htons(c->counter.v16[7]));
|
||||
if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
|
||||
|
||||
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 */
|
||||
return err_status_ok;
|
||||
c->bytes_in_buffer -= bytes_to_encr;
|
||||
|
||||
} else {
|
||||
|
||||
/* encrypt bytes until the remaining data is 16-byte aligned */
|
||||
for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++)
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
/* return now to avoid the main loop */
|
||||
return srtp_err_status_ok;
|
||||
|
||||
bytes_to_encr -= c->bytes_in_buffer;
|
||||
c->bytes_in_buffer = 0;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
/* now loop over entire 16-byte blocks of keystream */
|
||||
for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
|
||||
/* 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];
|
||||
}
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
aes_icm_advance_ismacryp(c, forIsmacryp);
|
||||
bytes_to_encr -= c->bytes_in_buffer;
|
||||
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
|
||||
b = (uint32_t *)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t *)b;
|
||||
#else
|
||||
if ((((unsigned long) buf) & 0x03) != 0) {
|
||||
*buf++ ^= c->keystream_buffer.v8[0];
|
||||
*buf++ ^= c->keystream_buffer.v8[1];
|
||||
*buf++ ^= c->keystream_buffer.v8[2];
|
||||
*buf++ ^= c->keystream_buffer.v8[3];
|
||||
*buf++ ^= c->keystream_buffer.v8[4];
|
||||
*buf++ ^= c->keystream_buffer.v8[5];
|
||||
*buf++ ^= c->keystream_buffer.v8[6];
|
||||
*buf++ ^= c->keystream_buffer.v8[7];
|
||||
*buf++ ^= c->keystream_buffer.v8[8];
|
||||
*buf++ ^= c->keystream_buffer.v8[9];
|
||||
*buf++ ^= c->keystream_buffer.v8[10];
|
||||
*buf++ ^= c->keystream_buffer.v8[11];
|
||||
*buf++ ^= c->keystream_buffer.v8[12];
|
||||
*buf++ ^= c->keystream_buffer.v8[13];
|
||||
*buf++ ^= c->keystream_buffer.v8[14];
|
||||
*buf++ ^= c->keystream_buffer.v8[15];
|
||||
} else {
|
||||
b = (uint32_t *)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t *)b;
|
||||
b = (uint32_t*)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t*)b;
|
||||
#else
|
||||
if ((((unsigned long)buf) & 0x03) != 0) {
|
||||
*buf++ ^= c->keystream_buffer.v8[0];
|
||||
*buf++ ^= c->keystream_buffer.v8[1];
|
||||
*buf++ ^= c->keystream_buffer.v8[2];
|
||||
*buf++ ^= c->keystream_buffer.v8[3];
|
||||
*buf++ ^= c->keystream_buffer.v8[4];
|
||||
*buf++ ^= c->keystream_buffer.v8[5];
|
||||
*buf++ ^= c->keystream_buffer.v8[6];
|
||||
*buf++ ^= c->keystream_buffer.v8[7];
|
||||
*buf++ ^= c->keystream_buffer.v8[8];
|
||||
*buf++ ^= c->keystream_buffer.v8[9];
|
||||
*buf++ ^= c->keystream_buffer.v8[10];
|
||||
*buf++ ^= c->keystream_buffer.v8[11];
|
||||
*buf++ ^= c->keystream_buffer.v8[12];
|
||||
*buf++ ^= c->keystream_buffer.v8[13];
|
||||
*buf++ ^= c->keystream_buffer.v8[14];
|
||||
*buf++ ^= c->keystream_buffer.v8[15];
|
||||
} else {
|
||||
b = (uint32_t*)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t*)b;
|
||||
}
|
||||
#endif /* #if ALIGN_32 */
|
||||
|
||||
}
|
||||
#endif /* #if ALIGN_32 */
|
||||
|
||||
}
|
||||
|
||||
/* if there is a tail end of the data, process it */
|
||||
if ((bytes_to_encr & 0xf) != 0) {
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
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 {
|
||||
/* if there is a tail end of the data, process it */
|
||||
if ((bytes_to_encr & 0xf) != 0) {
|
||||
|
||||
/* no tail, so just reset the keystream buffer size to zero */
|
||||
c->bytes_in_buffer = 0;
|
||||
/* fill buffer with new keystream */
|
||||
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
|
||||
aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
|
||||
return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
|
||||
}
|
||||
static const char srtp_aes_icm_128_description[] = "AES-128 integer counter mode";
|
||||
static const char srtp_aes_icm_256_description[] = "AES-256 integer counter mode";
|
||||
|
||||
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_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
|
||||
static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_0_nonce[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
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
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_0_plaintext[32] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
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,
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_0_ciphertext[32] = {
|
||||
0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
|
||||
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
|
||||
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
|
||||
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
|
||||
static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
|
||||
0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
|
||||
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
|
||||
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
|
||||
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_test_case_0 = {
|
||||
30, /* octets in key */
|
||||
aes_icm_test_case_0_key, /* key */
|
||||
aes_icm_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL /* pointer to next testcase */
|
||||
static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
|
||||
SRTP_AES_ICM_128_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_icm_128_test_case_0_key, /* key */
|
||||
srtp_aes_icm_128_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_key[46] = {
|
||||
0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
|
||||
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
|
||||
0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
|
||||
0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
|
||||
static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
|
||||
0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
|
||||
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
|
||||
0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
|
||||
0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_nonce[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
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
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_plaintext[32] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
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,
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_ciphertext[32] = {
|
||||
0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
|
||||
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
|
||||
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
|
||||
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
|
||||
static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
|
||||
0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
|
||||
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
|
||||
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
|
||||
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_test_case_1 = {
|
||||
46, /* octets in key */
|
||||
aes_icm_test_case_1_key, /* key */
|
||||
aes_icm_test_case_1_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_test_case_1_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_1_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
&aes_icm_test_case_0 /* pointer to next testcase */
|
||||
static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
|
||||
SRTP_AES_ICM_256_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_icm_256_test_case_0_key, /* key */
|
||||
srtp_aes_icm_256_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL, /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
|
@ -575,19 +492,30 @@ cipher_test_case_t aes_icm_test_case_1 = {
|
|||
* note: the encrypt function is identical to the decrypt function
|
||||
*/
|
||||
|
||||
cipher_type_t aes_icm = {
|
||||
(cipher_alloc_func_t) aes_icm_alloc,
|
||||
(cipher_dealloc_func_t) aes_icm_dealloc,
|
||||
(cipher_init_func_t) aes_icm_context_init,
|
||||
(cipher_set_aad_func_t) 0,
|
||||
(cipher_encrypt_func_t) aes_icm_encrypt,
|
||||
(cipher_decrypt_func_t) aes_icm_encrypt,
|
||||
(cipher_set_iv_func_t) aes_icm_set_iv,
|
||||
(cipher_get_tag_func_t) 0,
|
||||
(char *) aes_icm_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t *) &aes_icm_test_case_1,
|
||||
(debug_module_t *) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_ICM
|
||||
const srtp_cipher_type_t srtp_aes_icm_128 = {
|
||||
srtp_aes_icm_alloc,
|
||||
srtp_aes_icm_dealloc,
|
||||
srtp_aes_icm_context_init,
|
||||
0, /* set_aad */
|
||||
srtp_aes_icm_encrypt,
|
||||
srtp_aes_icm_encrypt,
|
||||
srtp_aes_icm_set_iv,
|
||||
0, /* get_tag */
|
||||
srtp_aes_icm_128_description,
|
||||
&srtp_aes_icm_128_test_case_0,
|
||||
SRTP_AES_ICM_128
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2013, Cisco Systems, Inc.
|
||||
* Copyright (c) 2013-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 "aes_icm_ossl.h"
|
||||
#include "crypto_types.h"
|
||||
#include "err.h" /* for srtp_debug */
|
||||
#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 */
|
||||
"aes icm ossl" /* printable module name */
|
||||
};
|
||||
extern cipher_test_case_t aes_icm_test_case_0;
|
||||
extern cipher_type_t aes_icm;
|
||||
extern cipher_type_t aes_icm_192;
|
||||
extern cipher_type_t aes_icm_256;
|
||||
extern const srtp_cipher_type_t srtp_aes_icm_128;
|
||||
extern const srtp_cipher_type_t srtp_aes_icm_192;
|
||||
extern const srtp_cipher_type_t srtp_aes_icm_256;
|
||||
|
||||
/*
|
||||
* integer counter mode works as follows:
|
||||
|
@ -70,7 +73,7 @@ extern cipher_type_t aes_icm_256;
|
|||
* 16 bits
|
||||
* <----->
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* | nonce | pakcet index | ctr |---+
|
||||
* | nonce | packet index | ctr |---+
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* |
|
||||
* +------+------+------+------+------+------+------+------+ v
|
||||
|
@ -106,106 +109,98 @@ extern cipher_type_t aes_icm_256;
|
|||
* value. The tlen argument is for the AEAD tag length, which
|
||||
* 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;
|
||||
int tmp;
|
||||
uint8_t *allptr;
|
||||
srtp_aes_icm_ctx_t *icm;
|
||||
|
||||
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
|
||||
*/
|
||||
if (key_len != AES_128_KEYSIZE_WSALT && key_len != AES_192_KEYSIZE_WSALT &&
|
||||
key_len != AES_256_KEYSIZE_WSALT) {
|
||||
return err_status_bad_param;
|
||||
if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT && key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
|
||||
key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/* allocate memory a cipher of type aes_icm */
|
||||
tmp = sizeof(cipher_t) + sizeof(aes_icm_ctx_t);
|
||||
allptr = (uint8_t*)crypto_alloc(tmp);
|
||||
if (allptr == NULL) {
|
||||
return err_status_alloc_fail;
|
||||
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
|
||||
if (*c == NULL) {
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
memset(*c, 0x0, sizeof(srtp_cipher_t));
|
||||
|
||||
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 */
|
||||
*c = (cipher_t*)allptr;
|
||||
(*c)->state = allptr + sizeof(cipher_t);
|
||||
icm = (aes_icm_ctx_t*)(*c)->state;
|
||||
(*c)->state = icm;
|
||||
|
||||
/* increment ref_count */
|
||||
/* setup cipher parameters */
|
||||
switch (key_len) {
|
||||
case AES_128_KEYSIZE_WSALT:
|
||||
(*c)->algorithm = AES_128_ICM;
|
||||
(*c)->type = &aes_icm;
|
||||
aes_icm.ref_count++;
|
||||
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE;
|
||||
case SRTP_AES_ICM_128_KEY_LEN_WSALT:
|
||||
(*c)->algorithm = SRTP_AES_ICM_128;
|
||||
(*c)->type = &srtp_aes_icm_128;
|
||||
icm->key_size = SRTP_AES_128_KEY_LEN;
|
||||
break;
|
||||
case AES_192_KEYSIZE_WSALT:
|
||||
(*c)->algorithm = AES_192_ICM;
|
||||
(*c)->type = &aes_icm_192;
|
||||
aes_icm_192.ref_count++;
|
||||
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_192_KEYSIZE;
|
||||
case SRTP_AES_ICM_192_KEY_LEN_WSALT:
|
||||
(*c)->algorithm = SRTP_AES_ICM_192;
|
||||
(*c)->type = &srtp_aes_icm_192;
|
||||
icm->key_size = SRTP_AES_192_KEY_LEN;
|
||||
break;
|
||||
case AES_256_KEYSIZE_WSALT:
|
||||
(*c)->algorithm = AES_256_ICM;
|
||||
(*c)->type = &aes_icm_256;
|
||||
aes_icm_256.ref_count++;
|
||||
((aes_icm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE;
|
||||
case SRTP_AES_ICM_256_KEY_LEN_WSALT:
|
||||
(*c)->algorithm = SRTP_AES_ICM_256;
|
||||
(*c)->type = &srtp_aes_icm_256;
|
||||
icm->key_size = SRTP_AES_256_KEY_LEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
EVP_CIPHER_CTX_init(&icm->ctx);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
return err_status_bad_param;
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the EVP context
|
||||
*/
|
||||
ctx = (aes_icm_ctx_t*)c->state;
|
||||
ctx = (srtp_aes_icm_ctx_t*)c->state;
|
||||
if (ctx != NULL) {
|
||||
EVP_CIPHER_CTX_cleanup(&ctx->ctx);
|
||||
/* decrement ref_count for the appropriate engine */
|
||||
switch (ctx->key_size) {
|
||||
case AES_256_KEYSIZE:
|
||||
aes_icm_256.ref_count--;
|
||||
break;
|
||||
case AES_192_KEYSIZE:
|
||||
aes_icm_192.ref_count--;
|
||||
break;
|
||||
case AES_128_KEYSIZE:
|
||||
aes_icm.ref_count--;
|
||||
break;
|
||||
default:
|
||||
return err_status_dealloc_fail;
|
||||
break;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
/* zeroize the key material */
|
||||
octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
|
||||
srtp_crypto_free(ctx);
|
||||
}
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t*)c,
|
||||
sizeof(cipher_t) + sizeof(aes_icm_ctx_t));
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
* go past the end of the key buffer
|
||||
*/
|
||||
v128_set_to_zero(&c->counter);
|
||||
v128_set_to_zero(&c->offset);
|
||||
memcpy(&c->counter, key + c->key_size, SALT_SIZE);
|
||||
memcpy(&c->offset, key + c->key_size, SALT_SIZE);
|
||||
memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
|
||||
memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
|
||||
|
||||
/* force last two octets of the offset to zero (for srtp compatibility) */
|
||||
c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0;
|
||||
c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0;
|
||||
c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
|
||||
c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
|
||||
|
||||
/* copy key to be used later when CiscoSSL crypto context is created */
|
||||
v128_copy_octet_string((v128_t*)&c->key, key);
|
||||
debug_print(srtp_mod_aes_icm, "key: %s", srtp_octet_string_hex_string(key, c->key_size));
|
||||
debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
|
||||
|
||||
/* if the key is greater than 16 bytes, copy the second
|
||||
* half. Note, we treat AES-192 and AES-256 the same here
|
||||
* for simplicity. The storage location receiving the
|
||||
* key is statically allocated to handle a full 32 byte key
|
||||
* regardless of the cipher in use.
|
||||
*/
|
||||
if (c->key_size == AES_256_KEYSIZE || c->key_size == AES_192_KEYSIZE) {
|
||||
debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s",
|
||||
v128_hex_string((v128_t*)(key + AES_128_KEYSIZE)));
|
||||
v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE);
|
||||
switch (c->key_size) {
|
||||
case SRTP_AES_256_KEY_LEN:
|
||||
evp = EVP_aes_256_ctr();
|
||||
break;
|
||||
case SRTP_AES_192_KEY_LEN:
|
||||
evp = EVP_aes_192_ctr();
|
||||
break;
|
||||
case SRTP_AES_128_KEY_LEN:
|
||||
evp = EVP_aes_128_ctr();
|
||||
break;
|
||||
default:
|
||||
return srtp_err_status_bad_param;
|
||||
break;
|
||||
}
|
||||
|
||||
debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key));
|
||||
debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
|
||||
if (!EVP_EncryptInit_ex(c->ctx, evp,
|
||||
NULL, key, NULL)) {
|
||||
return srtp_err_status_fail;
|
||||
} else {
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&c->ctx);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_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
|
||||
* 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;
|
||||
|
||||
/* set nonce (for alignment) */
|
||||
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);
|
||||
|
||||
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) {
|
||||
case AES_256_KEYSIZE:
|
||||
evp = EVP_aes_256_ctr();
|
||||
break;
|
||||
case AES_192_KEYSIZE:
|
||||
evp = EVP_aes_192_ctr();
|
||||
break;
|
||||
case AES_128_KEYSIZE:
|
||||
evp = EVP_aes_128_ctr();
|
||||
break;
|
||||
default:
|
||||
return err_status_bad_param;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!EVP_EncryptInit_ex(&c->ctx, evp,
|
||||
NULL, c->key.v8, c->counter.v8)) {
|
||||
return err_status_fail;
|
||||
if (!EVP_EncryptInit_ex(c->ctx, NULL,
|
||||
NULL, NULL, c->counter.v8)) {
|
||||
return srtp_err_status_fail;
|
||||
} 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
|
||||
* 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;
|
||||
|
||||
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)) {
|
||||
return err_status_cipher_fail;
|
||||
if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
|
||||
return srtp_err_status_cipher_fail;
|
||||
}
|
||||
*enc_len = len;
|
||||
|
||||
if (!EVP_EncryptFinal_ex(&c->ctx, buf, (int*)&len)) {
|
||||
return err_status_cipher_fail;
|
||||
if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
|
||||
return srtp_err_status_cipher_fail;
|
||||
}
|
||||
*enc_len += len;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abstraction layer for encrypt.
|
||||
*/
|
||||
err_status_t aes_icm_output (aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output)
|
||||
{
|
||||
unsigned int len = num_octets_to_output;
|
||||
|
||||
/* zeroize the buffer */
|
||||
octet_string_set_to_zero(buffer, num_octets_to_output);
|
||||
|
||||
/* exor keystream into buffer */
|
||||
return aes_icm_openssl_encrypt(c, buffer, &len);
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Name of this crypto engine
|
||||
*/
|
||||
char aes_icm_openssl_description[] = "AES-128 counter mode using openssl";
|
||||
char aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
|
||||
char aes_icm_256_openssl_description[] = "AES-256 counter mode using openssl";
|
||||
static const char srtp_aes_icm_128_openssl_description[] = "AES-128 counter mode using openssl";
|
||||
static const char srtp_aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl";
|
||||
static const char srtp_aes_icm_256_openssl_description[] = "AES-256 counter mode using openssl";
|
||||
|
||||
|
||||
/*
|
||||
* KAT values for AES self-test. These
|
||||
* values came from the legacy libsrtp code.
|
||||
*/
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
|
||||
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
|
||||
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_test_case_0 = {
|
||||
AES_128_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_icm_test_case_0_key, /* key */
|
||||
aes_icm_test_case_0_nonce, /* packet index */
|
||||
static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
|
||||
SRTP_AES_ICM_128_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_icm_128_test_case_0_key, /* key */
|
||||
srtp_aes_icm_128_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_test_case_0_plaintext, /* plaintext */
|
||||
srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_0_ciphertext, /* ciphertext */
|
||||
srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -394,7 +369,7 @@ cipher_test_case_t aes_icm_test_case_0 = {
|
|||
* KAT values for AES-192-CTR self-test. These
|
||||
* values came from section 7 of RFC 6188.
|
||||
*/
|
||||
uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = {
|
||||
static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_WSALT] = {
|
||||
0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
|
||||
0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
|
||||
0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
|
||||
|
@ -402,45 +377,44 @@ uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = {
|
|||
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
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
|
||||
0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
|
||||
0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_192_test_case_1 = {
|
||||
AES_192_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_icm_192_test_case_1_key, /* key */
|
||||
aes_icm_192_test_case_1_nonce, /* packet index */
|
||||
static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
|
||||
SRTP_AES_ICM_192_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_icm_192_test_case_0_key, /* key */
|
||||
srtp_aes_icm_192_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_192_test_case_1_plaintext, /* plaintext */
|
||||
srtp_aes_icm_192_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_192_test_case_1_ciphertext, /* ciphertext */
|
||||
srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* KAT values for AES-256-CTR self-test. These
|
||||
* values came from section 7 of RFC 6188.
|
||||
*/
|
||||
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,
|
||||
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
|
||||
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
|
||||
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_256_test_case_2 = {
|
||||
AES_256_KEYSIZE_WSALT, /* octets in key */
|
||||
aes_icm_256_test_case_2_key, /* key */
|
||||
aes_icm_256_test_case_2_nonce, /* packet index */
|
||||
static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
|
||||
SRTP_AES_ICM_256_KEY_LEN_WSALT, /* octets in key */
|
||||
srtp_aes_icm_256_test_case_0_key, /* key */
|
||||
srtp_aes_icm_256_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_256_test_case_2_plaintext, /* plaintext */
|
||||
srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_256_test_case_2_ciphertext, /* ciphertext */
|
||||
srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -486,59 +460,53 @@ cipher_test_case_t aes_icm_256_test_case_2 = {
|
|||
* This is the function table for this crypto engine.
|
||||
* note: the encrypt function is identical to the decrypt function
|
||||
*/
|
||||
cipher_type_t aes_icm = {
|
||||
(cipher_alloc_func_t) aes_icm_openssl_alloc,
|
||||
(cipher_dealloc_func_t) aes_icm_openssl_dealloc,
|
||||
(cipher_init_func_t) aes_icm_openssl_context_init,
|
||||
(cipher_set_aad_func_t) 0,
|
||||
(cipher_encrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_decrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_set_iv_func_t) aes_icm_openssl_set_iv,
|
||||
(cipher_get_tag_func_t) 0,
|
||||
(char*) aes_icm_openssl_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t*) &aes_icm_test_case_0,
|
||||
(debug_module_t*) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_ICM
|
||||
const srtp_cipher_type_t srtp_aes_icm_128 = {
|
||||
srtp_aes_icm_openssl_alloc,
|
||||
srtp_aes_icm_openssl_dealloc,
|
||||
srtp_aes_icm_openssl_context_init,
|
||||
0, /* set_aad */
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_set_iv,
|
||||
0, /* get_tag */
|
||||
srtp_aes_icm_128_openssl_description,
|
||||
&srtp_aes_icm_128_test_case_0,
|
||||
SRTP_AES_ICM_128
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the function table for this crypto engine.
|
||||
* note: the encrypt function is identical to the decrypt function
|
||||
*/
|
||||
cipher_type_t aes_icm_192 = {
|
||||
(cipher_alloc_func_t) aes_icm_openssl_alloc,
|
||||
(cipher_dealloc_func_t) aes_icm_openssl_dealloc,
|
||||
(cipher_init_func_t) aes_icm_openssl_context_init,
|
||||
(cipher_set_aad_func_t) 0,
|
||||
(cipher_encrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_decrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_set_iv_func_t) aes_icm_openssl_set_iv,
|
||||
(cipher_get_tag_func_t) 0,
|
||||
(char*) aes_icm_192_openssl_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t*) &aes_icm_192_test_case_1,
|
||||
(debug_module_t*) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_192_ICM
|
||||
const srtp_cipher_type_t srtp_aes_icm_192 = {
|
||||
srtp_aes_icm_openssl_alloc,
|
||||
srtp_aes_icm_openssl_dealloc,
|
||||
srtp_aes_icm_openssl_context_init,
|
||||
0, /* set_aad */
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_set_iv,
|
||||
0, /* get_tag */
|
||||
srtp_aes_icm_192_openssl_description,
|
||||
&srtp_aes_icm_192_test_case_0,
|
||||
SRTP_AES_ICM_192
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the function table for this crypto engine.
|
||||
* note: the encrypt function is identical to the decrypt function
|
||||
*/
|
||||
cipher_type_t aes_icm_256 = {
|
||||
(cipher_alloc_func_t) aes_icm_openssl_alloc,
|
||||
(cipher_dealloc_func_t) aes_icm_openssl_dealloc,
|
||||
(cipher_init_func_t) aes_icm_openssl_context_init,
|
||||
(cipher_set_aad_func_t) 0,
|
||||
(cipher_encrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_decrypt_func_t) aes_icm_openssl_encrypt,
|
||||
(cipher_set_iv_func_t) aes_icm_openssl_set_iv,
|
||||
(cipher_get_tag_func_t) 0,
|
||||
(char*) aes_icm_256_openssl_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t*) &aes_icm_256_test_case_2,
|
||||
(debug_module_t*) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_256_ICM
|
||||
const srtp_cipher_type_t srtp_aes_icm_256 = {
|
||||
srtp_aes_icm_openssl_alloc,
|
||||
srtp_aes_icm_openssl_dealloc,
|
||||
srtp_aes_icm_openssl_context_init,
|
||||
0, /* set_aad */
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_encrypt,
|
||||
srtp_aes_icm_openssl_set_iv,
|
||||
0, /* get_tag */
|
||||
srtp_aes_icm_256_openssl_description,
|
||||
&srtp_aes_icm_256_test_case_0,
|
||||
SRTP_AES_ICM_256
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,26 +9,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -44,96 +44,95 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "null_cipher.h"
|
||||
#include "err.h" /* for srtp_debug */
|
||||
#include "alloc.h"
|
||||
|
||||
/* 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
|
||||
null_cipher_alloc(cipher_t **c, int key_len, int tlen) {
|
||||
extern cipher_type_t null_cipher;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(mod_cipher,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
static srtp_err_status_t srtp_null_cipher_alloc (srtp_cipher_t **c, int key_len, int tlen)
|
||||
{
|
||||
extern const srtp_cipher_type_t srtp_null_cipher;
|
||||
|
||||
/* allocate memory a cipher of type null_cipher */
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
debug_print(srtp_mod_cipher,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
/* set pointers */
|
||||
*c = (cipher_t *)pointer;
|
||||
(*c)->algorithm = NULL_CIPHER;
|
||||
(*c)->type = &null_cipher;
|
||||
(*c)->state = pointer + sizeof(cipher_t);
|
||||
/* allocate memory a cipher of type null_cipher */
|
||||
*c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
|
||||
if (*c == NULL) {
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
memset(*c, 0x0, sizeof(srtp_cipher_t));
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
/* set pointers */
|
||||
(*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
|
||||
null_cipher_dealloc(cipher_t *c) {
|
||||
extern cipher_type_t null_cipher;
|
||||
static srtp_err_status_t srtp_null_cipher_dealloc (srtp_cipher_t *c)
|
||||
{
|
||||
extern const srtp_cipher_type_t srtp_null_cipher;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)c,
|
||||
sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero(c, sizeof(srtp_cipher_t));
|
||||
|
||||
/* free memory of type null_cipher */
|
||||
crypto_free(c);
|
||||
/* free memory of type null_cipher */
|
||||
srtp_crypto_free(c);
|
||||
|
||||
return srtp_err_status_ok;
|
||||
|
||||
/* decrement reference count */
|
||||
null_cipher.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) {
|
||||
static srtp_err_status_t srtp_null_cipher_init (void *cv, const uint8_t *key)
|
||||
{
|
||||
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
|
||||
|
||||
debug_print(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
|
||||
null_cipher_set_iv(null_cipher_ctx_t *c, void *iv) {
|
||||
return err_status_ok;
|
||||
static srtp_err_status_t srtp_null_cipher_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir)
|
||||
{
|
||||
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_encrypt(null_cipher_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *bytes_to_encr) {
|
||||
return err_status_ok;
|
||||
static srtp_err_status_t srtp_null_cipher_encrypt (void *cv,
|
||||
unsigned char *buf, unsigned int *bytes_to_encr)
|
||||
{
|
||||
/* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
char
|
||||
null_cipher_description[] = "null cipher";
|
||||
static const char srtp_null_cipher_description[] = "null cipher";
|
||||
|
||||
cipher_test_case_t
|
||||
null_cipher_test_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* packet index */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* plaintext */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL /* pointer to next testcase */
|
||||
static const srtp_cipher_test_case_t srtp_null_cipher_test_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* packet index */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* plaintext */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* ciphertext */
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
|
@ -141,19 +140,17 @@ null_cipher_test_0 = {
|
|||
* note: the decrypt function is idential to the encrypt function
|
||||
*/
|
||||
|
||||
cipher_type_t null_cipher = {
|
||||
(cipher_alloc_func_t) null_cipher_alloc,
|
||||
(cipher_dealloc_func_t) null_cipher_dealloc,
|
||||
(cipher_init_func_t) null_cipher_init,
|
||||
(cipher_set_aad_func_t) 0,
|
||||
(cipher_encrypt_func_t) null_cipher_encrypt,
|
||||
(cipher_decrypt_func_t) null_cipher_encrypt,
|
||||
(cipher_set_iv_func_t) null_cipher_set_iv,
|
||||
(cipher_get_tag_func_t) 0,
|
||||
(char *) null_cipher_description,
|
||||
(int) 0,
|
||||
(cipher_test_case_t *) &null_cipher_test_0,
|
||||
(debug_module_t *) NULL,
|
||||
(cipher_type_id_t) NULL_CIPHER
|
||||
const srtp_cipher_type_t srtp_null_cipher = {
|
||||
srtp_null_cipher_alloc,
|
||||
srtp_null_cipher_dealloc,
|
||||
srtp_null_cipher_init,
|
||||
0, /* set_aad */
|
||||
srtp_null_cipher_encrypt,
|
||||
srtp_null_cipher_encrypt,
|
||||
srtp_null_cipher_set_iv,
|
||||
0, /* get_tag */
|
||||
srtp_null_cipher_description,
|
||||
&srtp_null_cipher_test_0,
|
||||
SRTP_NULL_CIPHER
|
||||
};
|
||||
|
||||
|
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,38 +43,39 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "auth.h"
|
||||
#include "err.h" /* for srtp_debug */
|
||||
#include "datatypes.h" /* for octet_string */
|
||||
|
||||
/* the debug module for authentiation */
|
||||
|
||||
debug_module_t mod_auth = {
|
||||
0, /* debugging is off by default */
|
||||
"auth func" /* printable name for module */
|
||||
srtp_debug_module_t srtp_mod_auth = {
|
||||
0, /* debugging is off by default */
|
||||
"auth func" /* printable name for module */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
auth_get_key_length(const auth_t *a) {
|
||||
return a->key_len;
|
||||
int srtp_auth_get_key_length (const srtp_auth_t *a)
|
||||
{
|
||||
return a->key_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_get_tag_length(const auth_t *a) {
|
||||
return a->out_len;
|
||||
int srtp_auth_get_tag_length (const srtp_auth_t *a)
|
||||
{
|
||||
return a->out_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_get_prefix_length(const auth_t *a) {
|
||||
return a->prefix_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_type_get_ref_count(const auth_type_t *at) {
|
||||
return at->ref_count;
|
||||
int srtp_auth_get_prefix_length (const srtp_auth_t *a)
|
||||
{
|
||||
return a->prefix_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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 */
|
||||
#define SELF_TEST_TAG_BUF_OCTETS 32
|
||||
|
||||
err_status_t
|
||||
auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) {
|
||||
const auth_test_case_t *test_case = test_data;
|
||||
auth_t *a;
|
||||
err_status_t status;
|
||||
uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
|
||||
int i, case_num = 0;
|
||||
srtp_err_status_t
|
||||
srtp_auth_type_test (const srtp_auth_type_t *at, const srtp_auth_test_case_t *test_data)
|
||||
{
|
||||
const srtp_auth_test_case_t *test_case = test_data;
|
||||
srtp_auth_t *a;
|
||||
srtp_err_status_t status;
|
||||
uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
|
||||
int i, case_num = 0;
|
||||
|
||||
debug_print(mod_auth, "running self-test for auth function %s",
|
||||
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;
|
||||
debug_print(srtp_mod_auth, "running self-test for auth function %s",
|
||||
at->description);
|
||||
|
||||
/* loop over all test cases */
|
||||
while (test_case != NULL) {
|
||||
|
||||
/* check test case parameters */
|
||||
if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* 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;
|
||||
/*
|
||||
* 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 srtp_err_status_cant_check;
|
||||
}
|
||||
|
||||
/* zeroize tag then compute */
|
||||
octet_string_set_to_zero(tag, test_case->tag_length_octets);
|
||||
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));
|
||||
/* loop over all test cases */
|
||||
while (test_case != NULL) {
|
||||
|
||||
/* check the result */
|
||||
status = err_status_ok;
|
||||
for (i=0; i < test_case->tag_length_octets; i++)
|
||||
if (tag[i] != test_case->tag[i]) {
|
||||
status = err_status_algo_fail;
|
||||
debug_print(mod_auth, "test case %d failed", case_num);
|
||||
debug_print(mod_auth, " (mismatch at octet %d)", i);
|
||||
}
|
||||
if (status) {
|
||||
auth_dealloc(a);
|
||||
return err_status_algo_fail;
|
||||
/* check test case parameters */
|
||||
if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/* allocate auth */
|
||||
status = srtp_auth_type_alloc(at, &a, test_case->key_length_octets,
|
||||
test_case->tag_length_octets);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
|
||||
return srtp_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.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
auth_type_self_test(const auth_type_t *at) {
|
||||
return auth_type_test(at, at->test_data);
|
||||
srtp_err_status_t srtp_auth_type_self_test (const srtp_auth_type_t *at)
|
||||
{
|
||||
return srtp_auth_type_test(at, at->test_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/*
|
||||
* hmac.c
|
||||
*
|
||||
* implementation of hmac auth_type_t
|
||||
* implementation of hmac srtp_auth_type_t
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright(c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -42,227 +42,225 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "hmac.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "hmac.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/* the debug module for authentiation */
|
||||
|
||||
debug_module_t mod_hmac = {
|
||||
0, /* debugging is off by default */
|
||||
"hmac sha-1" /* printable name for module */
|
||||
srtp_debug_module_t srtp_mod_hmac = {
|
||||
0, /* debugging is off by default */
|
||||
"hmac sha-1" /* printable name for module */
|
||||
};
|
||||
|
||||
|
||||
err_status_t
|
||||
hmac_alloc(auth_t **a, int key_len, int out_len) {
|
||||
extern auth_type_t hmac;
|
||||
uint8_t *pointer;
|
||||
static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
|
||||
{
|
||||
extern const srtp_auth_type_t srtp_hmac;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(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, "allocating auth func with key length %d", key_len);
|
||||
debug_print(srtp_mod_hmac, " tag length %d", out_len);
|
||||
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* 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
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/*
|
||||
* set values of ipad and opad by exoring the key into the
|
||||
* appropriate constant values
|
||||
*/
|
||||
for (i=0; i < key_len; i++) {
|
||||
ipad[i] = key[i] ^ 0x36;
|
||||
state->opad[i] = key[i] ^ 0x5c;
|
||||
}
|
||||
/* set the rest of ipad, opad to constant values */
|
||||
for ( ; i < 64; i++) {
|
||||
ipad[i] = 0x36;
|
||||
((uint8_t *)state->opad)[i] = 0x5c;
|
||||
}
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
|
||||
|
||||
/* initialize sha1 context */
|
||||
sha1_init(&state->init_ctx);
|
||||
/* check output length - should be less than 20 bytes */
|
||||
if (out_len > 20) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/* hash ipad ^ key */
|
||||
sha1_update(&state->init_ctx, ipad, 64);
|
||||
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
|
||||
/* allocate memory for auth and srtp_hmac_ctx_t structures */
|
||||
pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
|
||||
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
|
||||
hmac_start(hmac_ctx_t *state) {
|
||||
|
||||
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
|
||||
static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
|
||||
{
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero(a, sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
|
||||
|
||||
return err_status_ok;
|
||||
/* free memory */
|
||||
srtp_crypto_free(a);
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {
|
||||
static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
|
||||
{
|
||||
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
|
||||
int i;
|
||||
uint8_t ipad[64];
|
||||
|
||||
debug_print(mod_hmac, "input: %s",
|
||||
octet_string_hex_string(message, msg_octets));
|
||||
|
||||
/* hash message into sha1 context */
|
||||
sha1_update(&state->ctx, message, msg_octets);
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
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
|
||||
hmac_compute(hmac_ctx_t *state, const void *message,
|
||||
int msg_octets, int tag_len, uint8_t *result) {
|
||||
uint32_t hash_value[5];
|
||||
uint32_t H[5];
|
||||
int i;
|
||||
static srtp_err_status_t srtp_hmac_start (void *statev)
|
||||
{
|
||||
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
|
||||
|
||||
/* check tag length, return error if we can't provide the value expected */
|
||||
if (tag_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* hash message, copy output into H */
|
||||
hmac_update(state, (const uint8_t*)message, msg_octets);
|
||||
sha1_final(&state->ctx, H);
|
||||
memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
|
||||
|
||||
/*
|
||||
* 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));
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/* re-initialize hash context */
|
||||
sha1_init(&state->ctx);
|
||||
|
||||
/* hash opad ^ key */
|
||||
sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
|
||||
static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
|
||||
{
|
||||
srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
|
||||
|
||||
/* 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);
|
||||
debug_print(srtp_mod_hmac, "input: %s",
|
||||
srtp_octet_string_hex_string(message, msg_octets));
|
||||
|
||||
/* copy hash_value to *result */
|
||||
for (i=0; i < tag_len; i++)
|
||||
result[i] = ((uint8_t *)hash_value)[i];
|
||||
/* hash message into sha1 context */
|
||||
srtp_sha1_update(&state->ctx, message, msg_octets);
|
||||
|
||||
debug_print(mod_hmac, "output: %s",
|
||||
octet_string_hex_string((uint8_t *)hash_value, tag_len));
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_key[20] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b
|
||||
static const uint8_t srtp_hmac_test_case_0_key[20] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_data[8] = {
|
||||
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
|
||||
static const uint8_t srtp_hmac_test_case_0_data[8] = {
|
||||
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_tag[20] = {
|
||||
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
|
||||
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
|
||||
0xf1, 0x46, 0xbe, 0x00
|
||||
static const uint8_t srtp_hmac_test_case_0_tag[20] = {
|
||||
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
|
||||
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
|
||||
0xf1, 0x46, 0xbe, 0x00
|
||||
};
|
||||
|
||||
auth_test_case_t
|
||||
hmac_test_case_0 = {
|
||||
20, /* octets in key */
|
||||
hmac_test_case_0_key, /* key */
|
||||
8, /* octets in data */
|
||||
hmac_test_case_0_data, /* data */
|
||||
20, /* octets in tag */
|
||||
hmac_test_case_0_tag, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
|
||||
20, /* octets in key */
|
||||
srtp_hmac_test_case_0_key, /* key */
|
||||
8, /* octets in data */
|
||||
srtp_hmac_test_case_0_data, /* data */
|
||||
20, /* octets in tag */
|
||||
srtp_hmac_test_case_0_tag, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/* 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
|
||||
hmac = {
|
||||
(auth_alloc_func) hmac_alloc,
|
||||
(auth_dealloc_func) hmac_dealloc,
|
||||
(auth_init_func) hmac_init,
|
||||
(auth_compute_func) hmac_compute,
|
||||
(auth_update_func) hmac_update,
|
||||
(auth_start_func) hmac_start,
|
||||
(char *) hmac_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &hmac_test_case_0,
|
||||
(debug_module_t *) &mod_hmac,
|
||||
(auth_type_id_t) HMAC_SHA1
|
||||
const srtp_auth_type_t srtp_hmac = {
|
||||
srtp_hmac_alloc,
|
||||
srtp_hmac_dealloc,
|
||||
srtp_hmac_init,
|
||||
srtp_hmac_compute,
|
||||
srtp_hmac_update,
|
||||
srtp_hmac_start,
|
||||
srtp_hmac_description,
|
||||
&srtp_hmac_test_case_0,
|
||||
SRTP_HMAC_SHA1
|
||||
};
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
* 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
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2013, Cisco Systems, Inc.
|
||||
* Copyright(c) 2013-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 "err.h" /* for srtp_debug */
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* the debug module for authentiation */
|
||||
|
||||
debug_module_t mod_hmac = {
|
||||
srtp_debug_module_t srtp_mod_hmac = {
|
||||
0, /* debugging is off by default */
|
||||
"hmac sha-1 openssl" /* printable name for module */
|
||||
};
|
||||
|
||||
|
||||
err_status_t
|
||||
hmac_alloc (auth_t **a, int key_len, int out_len)
|
||||
static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
|
||||
{
|
||||
extern auth_type_t hmac;
|
||||
uint8_t *pointer;
|
||||
hmac_ctx_t *new_hmac_ctx;
|
||||
extern const srtp_auth_type_t srtp_hmac;
|
||||
|
||||
debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
|
||||
debug_print(mod_hmac, " tag length %d", out_len);
|
||||
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20) {
|
||||
return err_status_bad_param;
|
||||
}
|
||||
debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
|
||||
debug_print(srtp_mod_hmac, " tag length %d", out_len);
|
||||
|
||||
/* check output length - should be less than 20 bytes */
|
||||
if (out_len > 20) {
|
||||
return err_status_bad_param;
|
||||
if (out_len > SHA1_DIGEST_SIZE) {
|
||||
return srtp_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;
|
||||
/* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated
|
||||
using HMAC_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
{
|
||||
/* 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 */
|
||||
*a = (auth_t*)pointer;
|
||||
(*a)->type = &hmac;
|
||||
(*a)->state = pointer + sizeof(auth_t);
|
||||
(*a)->type = &srtp_hmac;
|
||||
(*a)->out_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
(*a)->prefix_len = 0;
|
||||
new_hmac_ctx = (hmac_ctx_t*)((*a)->state);
|
||||
memset(new_hmac_ctx, 0, sizeof(hmac_ctx_t));
|
||||
|
||||
/* increment global count of all hmac uses */
|
||||
hmac.ref_count++;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_dealloc (auth_t *a)
|
||||
static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
|
||||
{
|
||||
extern auth_type_t hmac;
|
||||
hmac_ctx_t *hmac_ctx;
|
||||
HMAC_CTX *hmac_ctx;
|
||||
|
||||
hmac_ctx = (hmac_ctx_t*)a->state;
|
||||
if (hmac_ctx->ctx_initialized) {
|
||||
EVP_MD_CTX_cleanup(&hmac_ctx->ctx);
|
||||
}
|
||||
if (hmac_ctx->init_ctx_initialized) {
|
||||
EVP_MD_CTX_cleanup(&hmac_ctx->init_ctx);
|
||||
}
|
||||
hmac_ctx = (HMAC_CTX*)a->state;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
HMAC_CTX_cleanup(hmac_ctx);
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t*)a,
|
||||
sizeof(hmac_ctx_t) + sizeof(auth_t));
|
||||
octet_string_set_to_zero(a, sizeof(HMAC_CTX) + sizeof(srtp_auth_t));
|
||||
|
||||
#else
|
||||
HMAC_CTX_free(hmac_ctx);
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero(a, sizeof(srtp_auth_t));
|
||||
#endif
|
||||
|
||||
/* free memory */
|
||||
crypto_free(a);
|
||||
srtp_crypto_free(a);
|
||||
|
||||
/* decrement global count of all hmac uses */
|
||||
hmac.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_init (hmac_ctx_t *state, const uint8_t *key, int key_len)
|
||||
static srtp_err_status_t srtp_hmac_start (void *statev)
|
||||
{
|
||||
int i;
|
||||
uint8_t ipad[64];
|
||||
HMAC_CTX *state = (HMAC_CTX *)statev;
|
||||
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20) {
|
||||
return err_status_bad_param;
|
||||
}
|
||||
if (HMAC_Init_ex(state, NULL, 0, NULL, NULL) == 0)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
/*
|
||||
* 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));
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_start (hmac_ctx_t *state)
|
||||
static srtp_err_status_t srtp_hmac_init (void *statev, const uint8_t *key, int key_len)
|
||||
{
|
||||
if (state->ctx_initialized) {
|
||||
EVP_MD_CTX_cleanup(&state->ctx);
|
||||
}
|
||||
if (!EVP_MD_CTX_copy(&state->ctx, &state->init_ctx)) {
|
||||
return err_status_auth_fail;
|
||||
} else {
|
||||
state->ctx_initialized = 1;
|
||||
return err_status_ok;
|
||||
}
|
||||
HMAC_CTX *state = (HMAC_CTX *)statev;
|
||||
|
||||
if (HMAC_Init_ex(state, key, key_len, EVP_sha1(), NULL) == 0)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_update (hmac_ctx_t *state, const uint8_t *message, int msg_octets)
|
||||
static srtp_err_status_t srtp_hmac_update (void *statev, const uint8_t *message, int msg_octets)
|
||||
{
|
||||
HMAC_CTX *state = (HMAC_CTX *)statev;
|
||||
|
||||
debug_print(mod_hmac, "input: %s",
|
||||
octet_string_hex_string(message, msg_octets));
|
||||
debug_print(srtp_mod_hmac, "input: %s",
|
||||
srtp_octet_string_hex_string(message, msg_octets));
|
||||
|
||||
/* hash message into sha1 context */
|
||||
sha1_update(&state->ctx, message, msg_octets);
|
||||
if (HMAC_Update(state, message, msg_octets) == 0)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_compute (hmac_ctx_t *state, const void *message,
|
||||
static srtp_err_status_t srtp_hmac_compute (void *statev, const uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result)
|
||||
{
|
||||
uint32_t hash_value[5];
|
||||
uint32_t H[5];
|
||||
HMAC_CTX *state = (HMAC_CTX *)statev;
|
||||
uint8_t hash_value[SHA1_DIGEST_SIZE];
|
||||
int i;
|
||||
unsigned int len;
|
||||
|
||||
/* check tag length, return error if we can't provide the value expected */
|
||||
if (tag_len > 20) {
|
||||
return err_status_bad_param;
|
||||
if (tag_len > SHA1_DIGEST_SIZE) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
|
||||
/* hash message, copy output into H */
|
||||
sha1_update(&state->ctx, message, msg_octets);
|
||||
sha1_final(&state->ctx, H);
|
||||
if (HMAC_Update(state, message, msg_octets) == 0)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
/*
|
||||
* 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));
|
||||
if (HMAC_Final(state, hash_value, &len) == 0)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
/* re-initialize hash context */
|
||||
sha1_init(&state->ctx);
|
||||
|
||||
/* hash opad ^ key */
|
||||
sha1_update(&state->ctx, (uint8_t*)state->opad, 64);
|
||||
|
||||
/* hash the result of the inner hash */
|
||||
sha1_update(&state->ctx, (uint8_t*)H, 20);
|
||||
|
||||
/* the result is returned in the array hash_value[] */
|
||||
sha1_final(&state->ctx, hash_value);
|
||||
if (len < tag_len)
|
||||
return srtp_err_status_auth_fail;
|
||||
|
||||
/* copy hash_value to *result */
|
||||
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",
|
||||
octet_string_hex_string((uint8_t*)hash_value, tag_len));
|
||||
debug_print(srtp_mod_hmac, "output: %s",
|
||||
srtp_octet_string_hex_string(hash_value, tag_len));
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/* begin test case 0 */
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_key[20] = {
|
||||
static const uint8_t srtp_hmac_test_case_0_key[SHA1_DIGEST_SIZE] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_data[8] = {
|
||||
static const uint8_t srtp_hmac_test_case_0_data[8] = {
|
||||
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_tag[20] = {
|
||||
static const uint8_t srtp_hmac_test_case_0_tag[SHA1_DIGEST_SIZE] = {
|
||||
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
|
||||
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
|
||||
0xf1, 0x46, 0xbe, 0x00
|
||||
};
|
||||
|
||||
auth_test_case_t
|
||||
hmac_test_case_0 = {
|
||||
20, /* octets in key */
|
||||
hmac_test_case_0_key, /* key */
|
||||
8, /* octets in data */
|
||||
hmac_test_case_0_data, /* data */
|
||||
20, /* octets in tag */
|
||||
hmac_test_case_0_tag, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
|
||||
sizeof(srtp_hmac_test_case_0_key), /* octets in key */
|
||||
srtp_hmac_test_case_0_key, /* key */
|
||||
sizeof(srtp_hmac_test_case_0_data), /* octets in data */
|
||||
srtp_hmac_test_case_0_data, /* data */
|
||||
sizeof(srtp_hmac_test_case_0_tag), /* octets in tag */
|
||||
srtp_hmac_test_case_0_tag, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/* 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
|
||||
hmac = {
|
||||
(auth_alloc_func) hmac_alloc,
|
||||
(auth_dealloc_func) hmac_dealloc,
|
||||
(auth_init_func) hmac_init,
|
||||
(auth_compute_func) hmac_compute,
|
||||
(auth_update_func) hmac_update,
|
||||
(auth_start_func) hmac_start,
|
||||
(char*) hmac_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t*) &hmac_test_case_0,
|
||||
(debug_module_t*) &mod_hmac,
|
||||
(auth_type_id_t) HMAC_SHA1
|
||||
const srtp_auth_type_t srtp_hmac = {
|
||||
srtp_hmac_alloc,
|
||||
srtp_hmac_dealloc,
|
||||
srtp_hmac_init,
|
||||
srtp_hmac_compute,
|
||||
srtp_hmac_update,
|
||||
srtp_hmac_start,
|
||||
srtp_hmac_description,
|
||||
&srtp_hmac_test_case_0,
|
||||
SRTP_HMAC_SHA1
|
||||
};
|
||||
|
||||
|
|
|
@ -9,26 +9,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -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"
|
||||
|
||||
/* null_auth uses the auth debug module */
|
||||
|
||||
extern debug_module_t mod_auth;
|
||||
extern srtp_debug_module_t srtp_mod_auth;
|
||||
|
||||
err_status_t
|
||||
null_auth_alloc(auth_t **a, int key_len, int out_len) {
|
||||
extern auth_type_t null_auth;
|
||||
uint8_t *pointer;
|
||||
static srtp_err_status_t srtp_null_auth_alloc (srtp_auth_t **a, int key_len, int out_len)
|
||||
{
|
||||
extern const srtp_auth_type_t srtp_null_auth;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(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, "allocating auth func with key length %d", key_len);
|
||||
debug_print(srtp_mod_auth, " tag length %d", out_len);
|
||||
|
||||
/* allocate memory for auth and null_auth_ctx_t structures */
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
/* allocate memory for auth and srtp_null_auth_ctx_t structures */
|
||||
pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
|
||||
if (pointer == NULL) {
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
|
||||
/* set pointers */
|
||||
*a = (auth_t *)pointer;
|
||||
(*a)->type = &null_auth;
|
||||
(*a)->state = pointer + sizeof (auth_t);
|
||||
(*a)->out_len = out_len;
|
||||
(*a)->prefix_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
/* set pointers */
|
||||
*a = (srtp_auth_t*)pointer;
|
||||
(*a)->type = &srtp_null_auth;
|
||||
(*a)->state = pointer + sizeof(srtp_auth_t);
|
||||
(*a)->out_len = out_len;
|
||||
(*a)->prefix_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
|
||||
/* increment global count of all null_auth uses */
|
||||
null_auth.ref_count++;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_dealloc(auth_t *a) {
|
||||
extern auth_type_t null_auth;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)a,
|
||||
sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
static srtp_err_status_t srtp_null_auth_dealloc (srtp_auth_t *a)
|
||||
{
|
||||
extern const srtp_auth_type_t srtp_null_auth;
|
||||
|
||||
/* free memory */
|
||||
crypto_free(a);
|
||||
|
||||
/* decrement global count of all null_auth uses */
|
||||
null_auth.ref_count--;
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) + sizeof(srtp_auth_t));
|
||||
|
||||
return err_status_ok;
|
||||
/* free memory */
|
||||
srtp_crypto_free(a);
|
||||
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len) {
|
||||
static srtp_err_status_t srtp_null_auth_init (void *statev, const uint8_t *key, int key_len)
|
||||
{
|
||||
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
|
||||
/* accept any length of key, and do nothing */
|
||||
|
||||
/* accept any length of key, and do nothing */
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_compute(null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result) {
|
||||
static srtp_err_status_t srtp_null_auth_compute (void *statev, const uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result)
|
||||
{
|
||||
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_update(null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets) {
|
||||
static srtp_err_status_t srtp_null_auth_update (void *statev, const uint8_t *message,
|
||||
int msg_octets)
|
||||
{
|
||||
/* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_start(null_auth_ctx_t *state) {
|
||||
return err_status_ok;
|
||||
static srtp_err_status_t srtp_null_auth_start (void *statev)
|
||||
{
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* begin test case 0 */
|
||||
|
||||
auth_test_case_t
|
||||
null_auth_test_case_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* octets in data */
|
||||
NULL, /* data */
|
||||
0, /* octets in tag */
|
||||
NULL, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
static const srtp_auth_test_case_t srtp_null_auth_test_case_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* octets in data */
|
||||
NULL, /* data */
|
||||
0, /* octets in tag */
|
||||
NULL, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/* end test case 0 */
|
||||
|
||||
char null_auth_description[] = "null authentication function";
|
||||
static const char srtp_null_auth_description[] = "null authentication function";
|
||||
|
||||
auth_type_t
|
||||
null_auth = {
|
||||
(auth_alloc_func) null_auth_alloc,
|
||||
(auth_dealloc_func) null_auth_dealloc,
|
||||
(auth_init_func) null_auth_init,
|
||||
(auth_compute_func) null_auth_compute,
|
||||
(auth_update_func) null_auth_update,
|
||||
(auth_start_func) null_auth_start,
|
||||
(char *) null_auth_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &null_auth_test_case_0,
|
||||
(debug_module_t *) NULL,
|
||||
(auth_type_id_t) NULL_AUTH
|
||||
const srtp_auth_type_t srtp_null_auth = {
|
||||
srtp_null_auth_alloc,
|
||||
srtp_null_auth_dealloc,
|
||||
srtp_null_auth_init,
|
||||
srtp_null_auth_compute,
|
||||
srtp_null_auth_update,
|
||||
srtp_null_auth_start,
|
||||
srtp_null_auth_description,
|
||||
&srtp_null_auth_test_case_0,
|
||||
SRTP_NULL_AUTH
|
||||
};
|
||||
|
||||
|
|
|
@ -9,26 +9,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -44,12 +44,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
debug_module_t mod_sha1 = {
|
||||
0, /* debugging is off by default */
|
||||
"sha-1" /* printable module name */
|
||||
srtp_debug_module_t srtp_mod_sha1 = {
|
||||
0, /* debugging is off by default */
|
||||
"sha-1" /* printable module name */
|
||||
};
|
||||
|
||||
/* SN == Rotate left N bits */
|
||||
|
@ -57,14 +60,14 @@ debug_module_t mod_sha1 = {
|
|||
#define S5(X) ((X << 5) | (X >> 27))
|
||||
#define S30(X) ((X << 30) | (X >> 2))
|
||||
|
||||
#define f0(B,C,D) ((B & C) | (~B & D))
|
||||
#define f1(B,C,D) (B ^ C ^ D)
|
||||
#define f2(B,C,D) ((B & C) | (B & D) | (C & D))
|
||||
#define f3(B,C,D) (B ^ C ^ D)
|
||||
#define f0(B, C, D) ((B & C) | (~B & D))
|
||||
#define f1(B, C, D) (B ^ C ^ D)
|
||||
#define f2(B, C, D) ((B & C) | (B & D) | (C & D))
|
||||
#define f3(B, C, D) (B ^ C ^ D)
|
||||
|
||||
/*
|
||||
* nota bene: the variable K0 appears in the curses library, so we
|
||||
* give longer names to these variables to avoid spurious warnings
|
||||
/*
|
||||
* nota bene: the variable K0 appears in the curses library, so we
|
||||
* give longer names to these variables to avoid spurious warnings
|
||||
* 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_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
|
||||
|
||||
void
|
||||
sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) {
|
||||
sha1_ctx_t ctx;
|
||||
void srtp_sha1 (const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5])
|
||||
{
|
||||
srtp_sha1_ctx_t ctx;
|
||||
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, msg, octets_in_msg);
|
||||
sha1_final(&ctx, hash_value);
|
||||
srtp_sha1_init(&ctx);
|
||||
srtp_sha1_update(&ctx, msg, octets_in_msg);
|
||||
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
|
||||
* 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)
|
||||
*/
|
||||
|
||||
void
|
||||
sha1_core(const uint32_t M[16], uint32_t hash_value[5]) {
|
||||
uint32_t H0;
|
||||
uint32_t H1;
|
||||
uint32_t H2;
|
||||
uint32_t H3;
|
||||
uint32_t H4;
|
||||
uint32_t W[80];
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
int t;
|
||||
void srtp_sha1_core (const uint32_t M[16], uint32_t hash_value[5])
|
||||
{
|
||||
uint32_t H0;
|
||||
uint32_t H1;
|
||||
uint32_t H2;
|
||||
uint32_t H3;
|
||||
uint32_t H4;
|
||||
uint32_t W[80];
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
int t;
|
||||
|
||||
/* copy hash_value into H0, H1, H2, H3, H4 */
|
||||
H0 = hash_value[0];
|
||||
H1 = hash_value[1];
|
||||
H2 = hash_value[2];
|
||||
H3 = hash_value[3];
|
||||
H4 = hash_value[4];
|
||||
/* copy hash_value into H0, H1, H2, H3, H4 */
|
||||
H0 = hash_value[0];
|
||||
H1 = hash_value[1];
|
||||
H2 = hash_value[2];
|
||||
H3 = hash_value[3];
|
||||
H4 = hash_value[4];
|
||||
|
||||
/* copy/xor message into array */
|
||||
/* copy/xor message into array */
|
||||
|
||||
W[0] = be32_to_cpu(M[0]);
|
||||
W[1] = be32_to_cpu(M[1]);
|
||||
W[2] = be32_to_cpu(M[2]);
|
||||
W[3] = be32_to_cpu(M[3]);
|
||||
W[4] = be32_to_cpu(M[4]);
|
||||
W[5] = be32_to_cpu(M[5]);
|
||||
W[6] = be32_to_cpu(M[6]);
|
||||
W[7] = be32_to_cpu(M[7]);
|
||||
W[8] = be32_to_cpu(M[8]);
|
||||
W[9] = be32_to_cpu(M[9]);
|
||||
W[10] = be32_to_cpu(M[10]);
|
||||
W[11] = be32_to_cpu(M[11]);
|
||||
W[12] = be32_to_cpu(M[12]);
|
||||
W[13] = be32_to_cpu(M[13]);
|
||||
W[14] = be32_to_cpu(M[14]);
|
||||
W[15] = be32_to_cpu(M[15]);
|
||||
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP);
|
||||
TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP);
|
||||
TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP);
|
||||
TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP);
|
||||
TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP);
|
||||
TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP);
|
||||
TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP);
|
||||
TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP);
|
||||
TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP);
|
||||
TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP);
|
||||
TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP);
|
||||
TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP);
|
||||
TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP);
|
||||
TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP);
|
||||
TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP);
|
||||
TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);
|
||||
W[0] = be32_to_cpu(M[0]);
|
||||
W[1] = be32_to_cpu(M[1]);
|
||||
W[2] = be32_to_cpu(M[2]);
|
||||
W[3] = be32_to_cpu(M[3]);
|
||||
W[4] = be32_to_cpu(M[4]);
|
||||
W[5] = be32_to_cpu(M[5]);
|
||||
W[6] = be32_to_cpu(M[6]);
|
||||
W[7] = be32_to_cpu(M[7]);
|
||||
W[8] = be32_to_cpu(M[8]);
|
||||
W[9] = be32_to_cpu(M[9]);
|
||||
W[10] = be32_to_cpu(M[10]);
|
||||
W[11] = be32_to_cpu(M[11]);
|
||||
W[12] = be32_to_cpu(M[12]);
|
||||
W[13] = be32_to_cpu(M[13]);
|
||||
W[14] = be32_to_cpu(M[14]);
|
||||
W[15] = be32_to_cpu(M[15]);
|
||||
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP);
|
||||
TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP);
|
||||
TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP);
|
||||
TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP);
|
||||
TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP);
|
||||
TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP);
|
||||
TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP);
|
||||
TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP);
|
||||
TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP);
|
||||
TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP);
|
||||
TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP);
|
||||
TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP);
|
||||
TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP);
|
||||
TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP);
|
||||
TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP);
|
||||
TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);
|
||||
|
||||
/* process the remainder of the array */
|
||||
for (t=32; t < 80; t++) {
|
||||
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
|
||||
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;
|
||||
/* process the remainder of the array */
|
||||
for (t = 32; t < 80; t++) {
|
||||
TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
|
||||
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 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
|
||||
*/
|
||||
|
||||
void
|
||||
sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
uint32_t W[80];
|
||||
int i, t;
|
||||
void srtp_sha1_final (srtp_sha1_ctx_t *ctx, uint32_t *output)
|
||||
{
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
uint32_t W[80];
|
||||
int i, t;
|
||||
|
||||
/*
|
||||
* process the remaining octets_in_buffer, padding and terminating as
|
||||
* 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.
|
||||
/*
|
||||
* process the remaining octets_in_buffer, padding and terminating as
|
||||
* necessary
|
||||
*/
|
||||
if (ctx->octets_in_buffer < 56)
|
||||
W[15] = ctx->num_bits_in_msg;
|
||||
else if (ctx->octets_in_buffer < 60)
|
||||
W[15] = 0x0;
|
||||
{
|
||||
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;
|
||||
} 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];
|
||||
B = ctx->H[1];
|
||||
C = ctx->H[2];
|
||||
D = ctx->H[3];
|
||||
E = ctx->H[4];
|
||||
debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
|
||||
|
||||
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;
|
||||
if (ctx->octets_in_buffer >= 56) {
|
||||
|
||||
debug_print(srtp_mod_sha1, "(final) running srtp_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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
debug_print(mod_sha1, "(final) running sha1_core()", NULL);
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
config.h
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,48 +43,39 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include "config.h"
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "gf2_8.h"
|
||||
#include "err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* aes internals */
|
||||
|
||||
typedef struct {
|
||||
v128_t round[15];
|
||||
int num_rounds;
|
||||
} aes_expanded_key_t;
|
||||
v128_t round[15];
|
||||
int num_rounds;
|
||||
} srtp_aes_expanded_key_t;
|
||||
|
||||
err_status_t
|
||||
aes_expand_encryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key);
|
||||
srtp_err_status_t srtp_aes_expand_encryption_key(
|
||||
const uint8_t *key,
|
||||
int key_len,
|
||||
srtp_aes_expanded_key_t *expanded_key);
|
||||
|
||||
err_status_t
|
||||
aes_expand_decryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key);
|
||||
srtp_err_status_t srtp_aes_expand_decryption_key(
|
||||
const uint8_t *key,
|
||||
int key_len,
|
||||
srtp_aes_expanded_key_t *expanded_key);
|
||||
|
||||
void
|
||||
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
|
||||
|
||||
void
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* internal functions
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
aes_init_sbox(void);
|
||||
|
||||
void
|
||||
aes_compute_tables(void);
|
||||
#endif
|
||||
|
||||
#endif /* _AES_H */
|
||||
#endif /* AES_H */
|
||||
|
|
|
@ -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 */
|
||||
|
|
@ -8,26 +8,26 @@
|
|||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2013, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2013-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -48,16 +48,16 @@
|
|||
|
||||
#include "cipher.h"
|
||||
#include "srtp.h"
|
||||
#include "datatypes.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
typedef struct {
|
||||
v256_t key;
|
||||
int key_size;
|
||||
int tag_len;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
cipher_direction_t dir;
|
||||
} aes_gcm_ctx_t;
|
||||
int key_size;
|
||||
int tag_len;
|
||||
EVP_CIPHER_CTX* ctx;
|
||||
srtp_cipher_direction_t dir;
|
||||
} srtp_aes_gcm_ctx_t;
|
||||
|
||||
#endif /* AES_GCM_OSSL_H */
|
||||
|
||||
|
|
|
@ -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
|
||||
#define AES_ICM_H
|
||||
|
||||
|
@ -15,46 +51,13 @@
|
|||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
v128_t counter; /* holds the counter value */
|
||||
v128_t offset; /* initial offset value */
|
||||
v128_t keystream_buffer; /* buffers bytes of keystream */
|
||||
aes_expanded_key_t expanded_key; /* the cipher key */
|
||||
int bytes_in_buffer; /* number of unused bytes in buffer */
|
||||
} 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);
|
||||
v128_t counter; /* holds the counter value */
|
||||
v128_t offset; /* initial offset value */
|
||||
v128_t keystream_buffer; /* buffers bytes of keystream */
|
||||
srtp_aes_expanded_key_t expanded_key; /* the cipher key */
|
||||
int bytes_in_buffer; /* number of unused bytes in buffer */
|
||||
int key_size; /* AES key size + 14 byte SALT */
|
||||
} srtp_aes_icm_ctx_t;
|
||||
|
||||
#endif /* AES_ICM_H */
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005,2012, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,27 +47,16 @@
|
|||
#define AES_ICM_H
|
||||
|
||||
#include "cipher.h"
|
||||
#include "datatypes.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#define SALT_SIZE 14
|
||||
#define AES_128_KEYSIZE AES_BLOCK_SIZE
|
||||
#define AES_192_KEYSIZE AES_BLOCK_SIZE + AES_BLOCK_SIZE / 2
|
||||
#define AES_256_KEYSIZE AES_BLOCK_SIZE * 2
|
||||
#define AES_128_KEYSIZE_WSALT AES_128_KEYSIZE + SALT_SIZE
|
||||
#define AES_192_KEYSIZE_WSALT AES_192_KEYSIZE + SALT_SIZE
|
||||
#define AES_256_KEYSIZE_WSALT AES_256_KEYSIZE + SALT_SIZE
|
||||
|
||||
typedef struct {
|
||||
v128_t counter; /* holds the counter value */
|
||||
v128_t offset; /* initial offset value */
|
||||
v256_t key;
|
||||
int key_size;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
} aes_icm_ctx_t;
|
||||
|
||||
err_status_t aes_icm_openssl_set_iv(aes_icm_ctx_t *c, void *iv, int dir);
|
||||
|
||||
EVP_CIPHER_CTX* ctx;
|
||||
} srtp_aes_icm_ctx_t;
|
||||
|
||||
#endif /* AES_ICM_H */
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,10 +48,16 @@
|
|||
|
||||
#include "datatypes.h"
|
||||
|
||||
void *
|
||||
crypto_alloc(size_t size);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
crypto_free(void *ptr);
|
||||
void * srtp_crypto_alloc(size_t size);
|
||||
|
||||
void srtp_crypto_free(void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTO_ALLOC_H */
|
||||
|
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,129 +43,124 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef AUTH_H
|
||||
#define AUTH_H
|
||||
#ifndef SRTP_AUTH_H
|
||||
#define SRTP_AUTH_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "err.h" /* error codes */
|
||||
#include "crypto.h" /* for auth_type_id_t */
|
||||
#include "crypto_types.h" /* for values of auth_type_id_t */
|
||||
#include "srtp.h"
|
||||
#include "crypto_types.h" /* for values of auth_type_id_t */
|
||||
|
||||
typedef struct auth_type_t *auth_type_pointer;
|
||||
typedef struct auth_t *auth_pointer_t;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef err_status_t (*auth_alloc_func)
|
||||
(auth_pointer_t *ap, int key_len, int out_len);
|
||||
typedef const struct srtp_auth_type_t *srtp_auth_type_pointer;
|
||||
typedef struct srtp_auth_t *srtp_auth_pointer_t;
|
||||
|
||||
typedef err_status_t (*auth_init_func)
|
||||
(void *state, const uint8_t *key, int key_len);
|
||||
typedef srtp_err_status_t (*srtp_auth_alloc_func)
|
||||
(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)
|
||||
(void *state, uint8_t *buffer, int octets_to_auth,
|
||||
int tag_len, uint8_t *tag);
|
||||
typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap);
|
||||
|
||||
typedef err_status_t (*auth_update_func)
|
||||
(void *state, uint8_t *buffer, int octets_to_auth);
|
||||
typedef srtp_err_status_t (*srtp_auth_compute_func)
|
||||
(void *state, const uint8_t *buffer, int octets_to_auth,
|
||||
int tag_len, uint8_t *tag);
|
||||
|
||||
typedef srtp_err_status_t (*srtp_auth_update_func)
|
||||
(void *state, const uint8_t *buffer, int octets_to_auth);
|
||||
|
||||
typedef srtp_err_status_t (*srtp_auth_start_func)(void *state);
|
||||
|
||||
typedef err_status_t (*auth_start_func)(void *state);
|
||||
|
||||
/* 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) \
|
||||
((at)->alloc((a), (klen), (outlen)))
|
||||
#define srtp_auth_init(a, key) \
|
||||
(((a)->type)->init((a)->state, (key), ((a)->key_len)))
|
||||
|
||||
#define auth_init(a, key) \
|
||||
(((a)->type)->init((a)->state, (key), ((a)->key_len)))
|
||||
#define srtp_auth_compute(a, buf, len, res) \
|
||||
(((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
|
||||
|
||||
#define auth_compute(a, buf, len, res) \
|
||||
(((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
|
||||
#define srtp_auth_update(a, buf, len) \
|
||||
(((a)->type)->update((a)->state, (buf), (len)))
|
||||
|
||||
#define auth_update(a, buf, len) \
|
||||
(((a)->type)->update((a)->state, (buf), (len)))
|
||||
#define srtp_auth_start(a)(((a)->type)->start((a)->state))
|
||||
|
||||
#define auth_start(a)(((a)->type)->start((a)->state))
|
||||
|
||||
#define auth_dealloc(c) (((c)->type)->dealloc(c))
|
||||
#define srtp_auth_dealloc(c) (((c)->type)->dealloc(c))
|
||||
|
||||
/* functions to get information about a particular auth_t */
|
||||
int srtp_auth_get_key_length(const struct srtp_auth_t *a);
|
||||
|
||||
int
|
||||
auth_get_key_length(const struct auth_t *a);
|
||||
int srtp_auth_get_tag_length(const struct srtp_auth_t *a);
|
||||
|
||||
int
|
||||
auth_get_tag_length(const struct auth_t *a);
|
||||
|
||||
int
|
||||
auth_get_prefix_length(const struct auth_t *a);
|
||||
int srtp_auth_get_prefix_length(const struct srtp_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
|
||||
* 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)
|
||||
*/
|
||||
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 {
|
||||
int key_length_octets; /* octets in key */
|
||||
uint8_t *key; /* key */
|
||||
int data_length_octets; /* octets in data */
|
||||
uint8_t *data; /* data */
|
||||
int tag_length_octets; /* octets in tag */
|
||||
uint8_t *tag; /* tag */
|
||||
struct auth_test_case_t *next_test_case; /* pointer to next testcase */
|
||||
} auth_test_case_t;
|
||||
/* srtp_auth_type_t */
|
||||
typedef struct srtp_auth_type_t {
|
||||
srtp_auth_alloc_func alloc;
|
||||
srtp_auth_dealloc_func dealloc;
|
||||
srtp_auth_init_func init;
|
||||
srtp_auth_compute_func compute;
|
||||
srtp_auth_update_func update;
|
||||
srtp_auth_start_func start;
|
||||
const char *description;
|
||||
const srtp_auth_test_case_t *test_data;
|
||||
srtp_auth_type_id_t id;
|
||||
} srtp_auth_type_t;
|
||||
|
||||
/* auth_type_t */
|
||||
|
||||
typedef struct auth_type_t {
|
||||
auth_alloc_func alloc;
|
||||
auth_dealloc_func dealloc;
|
||||
auth_init_func init;
|
||||
auth_compute_func compute;
|
||||
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);
|
||||
typedef struct srtp_auth_t {
|
||||
const srtp_auth_type_t *type;
|
||||
void *state;
|
||||
int out_len; /* length of output tag in octets */
|
||||
int key_len; /* length of key in octets */
|
||||
int prefix_len; /* length of keystream prefix */
|
||||
} srtp_auth_t;
|
||||
|
||||
/*
|
||||
* auth_type_get_ref_count(at) returns the reference count (the number
|
||||
* of instantiations) of the auth_type_t at
|
||||
* srtp_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
|
||||
*/
|
||||
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 */
|
||||
|
|
|
@ -7,26 +7,26 @@
|
|||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,212 +43,180 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
#ifndef SRTP_CIPHER_H
|
||||
#define SRTP_CIPHER_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "rdbx.h" /* for xtd_seq_num_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 */
|
||||
#include "srtp.h"
|
||||
#include "crypto_types.h" /* for values of cipher_type_id_t */
|
||||
|
||||
|
||||
/**
|
||||
* @brief cipher_direction_t defines a particular cipher operation.
|
||||
#ifdef __cplusplus
|
||||
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
|
||||
* distinction does not matter, but for others, it is essential.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
|
||||
direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
|
||||
direction_any /**< encryption or decryption */
|
||||
} cipher_direction_t;
|
||||
typedef enum {
|
||||
srtp_direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
|
||||
srtp_direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
|
||||
srtp_direction_any /**< encryption or decryption */
|
||||
} srtp_cipher_direction_t;
|
||||
|
||||
/*
|
||||
* the cipher_pointer and cipher_type_pointer definitions are needed
|
||||
* as cipher_t and cipher_type_t are not yet defined
|
||||
* the srtp_cipher_pointer_t definition is needed
|
||||
* as srtp_cipher_t is not yet defined
|
||||
*/
|
||||
|
||||
typedef struct cipher_type_t *cipher_type_pointer_t;
|
||||
typedef struct cipher_t *cipher_pointer_t;
|
||||
typedef struct srtp_cipher_t *srtp_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 err_status_t (*cipher_alloc_func_t)
|
||||
(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);
|
||||
typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)
|
||||
(srtp_cipher_pointer_t *cp, int key_len, int tag_len);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
typedef err_status_t (*cipher_get_tag_func_t)
|
||||
(void *state, void *tag, int *len);
|
||||
typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)
|
||||
(void *state, uint8_t *tag, uint32_t *len);
|
||||
|
||||
|
||||
/*
|
||||
* cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t,
|
||||
* plaintext, and ciphertext values that are known to be correct for a
|
||||
* srtp_cipher_test_case_t is a (list of) key, salt, plaintext, ciphertext,
|
||||
* and aad values that are 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 correcness of the implementation.
|
||||
* (see the cipher_type_self_test() function below)
|
||||
* in an on-the-fly self test of the correctness of the implementation.
|
||||
* (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 {
|
||||
int key_length_octets; /* octets in key */
|
||||
uint8_t *key; /* key */
|
||||
uint8_t *idx; /* packet index */
|
||||
int plaintext_length_octets; /* octets in plaintext */
|
||||
uint8_t *plaintext; /* plaintext */
|
||||
int ciphertext_length_octets; /* octets in plaintext */
|
||||
uint8_t *ciphertext; /* ciphertext */
|
||||
int aad_length_octets; /* octets in AAD */
|
||||
uint8_t *aad; /* AAD */
|
||||
int tag_length_octets; /* Length of AEAD tag */
|
||||
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */
|
||||
} cipher_test_case_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;
|
||||
/* srtp_cipher_type_t defines the 'metadata' for a particular cipher type */
|
||||
typedef struct srtp_cipher_type_t {
|
||||
srtp_cipher_alloc_func_t alloc;
|
||||
srtp_cipher_dealloc_func_t dealloc;
|
||||
srtp_cipher_init_func_t init;
|
||||
srtp_cipher_set_aad_func_t set_aad;
|
||||
srtp_cipher_encrypt_func_t encrypt;
|
||||
srtp_cipher_encrypt_func_t decrypt;
|
||||
srtp_cipher_set_iv_func_t set_iv;
|
||||
srtp_cipher_get_tag_func_t get_tag;
|
||||
const char *description;
|
||||
const srtp_cipher_test_case_t *test_data;
|
||||
srtp_cipher_type_id_t id;
|
||||
} srtp_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
|
||||
*/
|
||||
|
||||
typedef struct cipher_t {
|
||||
cipher_type_t *type;
|
||||
void *state;
|
||||
int key_len;
|
||||
int algorithm;
|
||||
} 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);
|
||||
|
||||
typedef struct srtp_cipher_t {
|
||||
const srtp_cipher_type_t *type;
|
||||
void *state;
|
||||
int key_len;
|
||||
int algorithm;
|
||||
} srtp_cipher_t;
|
||||
|
||||
/* some bookkeeping functions */
|
||||
|
||||
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);
|
||||
int srtp_cipher_get_key_length(const srtp_cipher_t *c);
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* the number of trials
|
||||
*
|
||||
* 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
|
||||
cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials);
|
||||
srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct, srtp_cipher_t **c, int key_len, int tlen);
|
||||
srtp_err_status_t srtp_cipher_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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
@ -7,26 +7,26 @@
|
|||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright(c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -46,16 +46,15 @@
|
|||
#ifndef CRYPTO_KERNEL
|
||||
#define CRYPTO_KERNEL
|
||||
|
||||
#include "rand_source.h"
|
||||
#include "prng.h"
|
||||
#include "cipher.h"
|
||||
#include "cipher.h"
|
||||
#include "auth.h"
|
||||
#include "cryptoalg.h"
|
||||
#include "stat.h"
|
||||
#include "err.h"
|
||||
#include "crypto_types.h"
|
||||
#include "key.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* crypto_kernel_state_t defines the possible states:
|
||||
|
@ -63,40 +62,36 @@
|
|||
* insecure - not yet initialized
|
||||
* secure - initialized and passed self-tests
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
crypto_kernel_state_insecure,
|
||||
crypto_kernel_state_secure
|
||||
} 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;
|
||||
srtp_crypto_kernel_state_insecure,
|
||||
srtp_crypto_kernel_state_secure
|
||||
} srtp_crypto_kernel_state_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;
|
||||
struct kernel_debug_module *next;
|
||||
} kernel_debug_module_t;
|
||||
/*
|
||||
* linked list of auth types
|
||||
*/
|
||||
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,
|
||||
* a global variable defined in crypto_kernel.c
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
crypto_kernel_state_t state; /* current state of kernel */
|
||||
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 */
|
||||
kernel_debug_module_t *debug_module_list; /* list of all debug modules */
|
||||
} crypto_kernel_t;
|
||||
srtp_crypto_kernel_state_t state; /* current state of kernel */
|
||||
srtp_kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */
|
||||
srtp_kernel_auth_type_t *auth_type_list; /* list of all auth func types */
|
||||
srtp_kernel_debug_module_t *debug_module_list; /* list of all debug modules */
|
||||
} srtp_crypto_kernel_t;
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
* crypto algorithms. Possible return values are:
|
||||
*
|
||||
* err_status_ok initialization successful
|
||||
* <other> init failure
|
||||
* srtp_err_status_ok initialization successful
|
||||
* <other> init failure
|
||||
*
|
||||
* If any value other than err_status_ok is returned, the
|
||||
* crypto_kernel MUST NOT be used.
|
||||
* If any value other than srtp_err_status_ok is returned, the
|
||||
* crypto_kernel MUST NOT be used.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_init(void);
|
||||
srtp_err_status_t srtp_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
|
||||
* deallocates any dynamically allocated memory. Possible return
|
||||
* values are:
|
||||
*
|
||||
* err_status_ok shutdown successful
|
||||
* <other> shutdown failure
|
||||
* srtp_err_status_ok shutdown successful
|
||||
* <other> shutdown failure
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_shutdown(void);
|
||||
srtp_err_status_t srtp_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
|
||||
* status report. Possible return values are:
|
||||
*
|
||||
* err_status_ok all tests were passed
|
||||
* <other> a test failed
|
||||
* srtp_err_status_ok all tests were passed
|
||||
* <other> a test failed
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_status(void);
|
||||
srtp_err_status_t srtp_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
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_list_debug_modules(void);
|
||||
srtp_err_status_t srtp_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
|
||||
crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
|
||||
srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct, srtp_auth_type_id_t id);
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);
|
||||
srtp_err_status_t srtp_crypto_kernel_load_debug_module(srtp_debug_module_t *new_dm);
|
||||
|
||||
/*
|
||||
* crypto_kernel_replace_cipher_type(ct, id)
|
||||
*
|
||||
* 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);
|
||||
* srtp_crypto_kernel_alloc_cipher(id, cp, key_len);
|
||||
*
|
||||
* allocates a cipher of type id at location *cp, with key length
|
||||
* key_len octets. Return values are:
|
||||
*
|
||||
* err_status_ok no problems
|
||||
* err_status_alloc_fail an allocation failure occured
|
||||
* err_status_fail couldn't find cipher with identifier 'id'
|
||||
*
|
||||
* srtp_err_status_ok no problems
|
||||
* srtp_err_status_alloc_fail an allocation failure occured
|
||||
* srtp_err_status_fail couldn't find cipher with identifier 'id'
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_cipher(cipher_type_id_t id,
|
||||
cipher_pointer_t *cp,
|
||||
int key_len,
|
||||
int tag_len);
|
||||
srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id, srtp_cipher_pointer_t *cp, int key_len, int tag_len);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* length key_len octets and output tag length of tag_len. Return
|
||||
* values are:
|
||||
*
|
||||
* err_status_ok no problems
|
||||
* err_status_alloc_fail an allocation failure occured
|
||||
* err_status_fail couldn't find auth with identifier 'id'
|
||||
*
|
||||
* srtp_err_status_ok no problems
|
||||
* srtp_err_status_alloc_fail an allocation failure occured
|
||||
* srtp_err_status_fail couldn't find auth with identifier 'id'
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_auth(auth_type_id_t id,
|
||||
auth_pointer_t *ap,
|
||||
int key_len,
|
||||
int tag_len);
|
||||
srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id, srtp_auth_pointer_t *ap, int key_len, int tag_len);
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
crypto_kernel_set_debug_module(char *mod_name, int v);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006,2013 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -42,207 +42,75 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_TYPES_H
|
||||
#define CRYPTO_TYPES_H
|
||||
#ifndef SRTP_CRYPTO_TYPES_H
|
||||
#define SRTP_CRYPTO_TYPES_H
|
||||
|
||||
/**
|
||||
* @defgroup Algos Cryptographic Algorithms
|
||||
/*
|
||||
* The null cipher performs no encryption.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
* The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the
|
||||
* encryption and decryption operations. This cipher can be chosen
|
||||
* to indicate that no encryption is to be performed.
|
||||
*/
|
||||
#define 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.
|
||||
* This cipher uses a 16-, 24-, or 32-octet key concatenated with a
|
||||
* AES-128 ICM is the variant of counter mode that is used by
|
||||
* Secure RTP. This cipher uses a 16-octet key concatenated with a
|
||||
* 14-octet offset (or salt) value.
|
||||
*/
|
||||
#define AES_ICM 1
|
||||
#define SRTP_AES_ICM_128 1
|
||||
|
||||
/**
|
||||
* @brief AES-128 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-192 Integer Counter Mode (AES ICM)
|
||||
*
|
||||
* AES CBC is the AES Cipher Block Chaining mode.
|
||||
* This cipher uses a 16-, 24-, or 32-octet key.
|
||||
* AES-128 ICM is the variant of counter mode that is used by
|
||||
* Secure RTP. This cipher uses a 24-octet key concatenated with a
|
||||
* 14-octet offset (or salt) value.
|
||||
*/
|
||||
#define 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.
|
||||
*
|
||||
* 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 Galois Counter Mode (AES GCM)
|
||||
*
|
||||
* AES-128 GCM is the variant of galois counter mode that is used by
|
||||
* Secure RTP. This cipher uses a 16-octet key.
|
||||
*/
|
||||
#define AES_128_GCM 6
|
||||
#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
|
||||
* Secure RTP. This cipher uses a 32-octet key.
|
||||
*/
|
||||
#define AES_256_GCM 7
|
||||
#define SRTP_AES_GCM_256 7
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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 authentication function performs no authentication.
|
||||
*
|
||||
* The NULL_AUTH function does nothing, and can be selected to indicate
|
||||
* 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
|
||||
* 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
|
||||
* SRTP_HMAC_SHA1 implements the Hash-based MAC using the NIST Secure
|
||||
* Hash Algorithm version 1 (SHA1).
|
||||
*/
|
||||
#define HMAC_SHA1 3
|
||||
#define SRTP_HMAC_SHA1 3
|
||||
|
||||
/**
|
||||
* @brief Strongest available authentication function.
|
||||
*
|
||||
* This identifier resolves to the strongest available authentication
|
||||
* function.
|
||||
*/
|
||||
#define STRONGHOLD_AUTH HMAC_SHA1
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* CRYPTO_TYPES_H */
|
||||
#endif /* SRTP_CRYPTO_TYPES_H */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -44,23 +44,25 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef _DATATYPES_H
|
||||
#define _DATATYPES_H
|
||||
#ifndef DATATYPES_H
|
||||
#define DATATYPES_H
|
||||
|
||||
#include "integers.h" /* definitions of uint32_t, et cetera */
|
||||
#include "alloc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef SRTP_KERNEL
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -115,13 +117,10 @@ typedef union {
|
|||
int
|
||||
octet_get_weight(uint8_t octet);
|
||||
|
||||
char *
|
||||
octet_bit_string(uint8_t x);
|
||||
|
||||
#define MAX_PRINT_STRING_LEN 1024
|
||||
|
||||
char *
|
||||
octet_string_hex_string(const void *str, int length);
|
||||
srtp_octet_string_hex_string(const void *str, int length);
|
||||
|
||||
char *
|
||||
v128_bit_string(v128_t *x);
|
||||
|
@ -129,34 +128,6 @@ v128_bit_string(v128_t *x);
|
|||
char *
|
||||
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
|
||||
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) \
|
||||
)
|
||||
|
||||
|
||||
#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 */
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* octet_string_is_eq(a,b, len) returns 1 if the length len strings a
|
||||
* and b are not equal, returns 0 otherwise
|
||||
* octet_string_is_eq(a, b, len) returns 1 if the length len strings a
|
||||
* and b are not equal. It returns 0 otherwise. The running time of the
|
||||
* comparison depends only on len, making this safe to use for (e.g.)
|
||||
* verifying authentication tags.
|
||||
*/
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
|
||||
|
||||
/*
|
||||
* 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
|
||||
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.
|
||||
|
@ -399,7 +338,7 @@ octet_string_set_to_zero(uint8_t *s, int len);
|
|||
# define be64_to_cpu(x) bswap_64((x))
|
||||
#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. */
|
||||
static inline uint32_t be32_to_cpu(uint32_t v) {
|
||||
/* optimized for x86. */
|
||||
|
@ -426,7 +365,7 @@ static inline uint64_t be64_to_cpu(uint64_t v) {
|
|||
return v;
|
||||
}
|
||||
|
||||
#endif /* ! SRTP_KERNEL_LINUX */
|
||||
#endif
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
|
@ -509,4 +448,8 @@ bitvector_left_shift(bitvector_t *x, int index);
|
|||
char *
|
||||
bitvector_bit_string(bitvector_t *x, char* buf, int len);
|
||||
|
||||
#endif /* _DATATYPES_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DATATYPES_H */
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/*
|
||||
* err.h
|
||||
*
|
||||
*
|
||||
* error status codes
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -46,97 +46,58 @@
|
|||
#ifndef 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
|
||||
*
|
||||
* 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 {
|
||||
err_level_emergency = 0,
|
||||
err_level_alert,
|
||||
err_level_critical,
|
||||
err_level_error,
|
||||
err_level_warning,
|
||||
err_level_notice,
|
||||
err_level_info,
|
||||
err_level_debug,
|
||||
err_level_none
|
||||
} err_reporting_level_t;
|
||||
srtp_err_level_error,
|
||||
srtp_err_level_warning,
|
||||
srtp_err_level_info,
|
||||
srtp_err_level_debug
|
||||
} srtp_err_reporting_level_t;
|
||||
|
||||
/*
|
||||
* 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
|
||||
err_reporting_init(char *ident);
|
||||
srtp_err_status_t srtp_err_reporting_init(void);
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
extern err_reporting_level_t err_level;
|
||||
#else
|
||||
typedef void (srtp_err_report_handler_func_t)(srtp_err_reporting_level_t level, const char * msg);
|
||||
|
||||
srtp_err_status_t srtp_install_err_report_handler(srtp_err_report_handler_func_t func);
|
||||
|
||||
/*
|
||||
* keydaemon_report_error reports a 'printf' formatted error
|
||||
* string, followed by a an arg list. The priority argument
|
||||
* is equivalent to that defined for syslog.
|
||||
* srtp_err_report reports a 'printf' formatted error
|
||||
* string, followed by a an arg list. The level argument
|
||||
* is one of srtp_err_reporting_level_t.
|
||||
*
|
||||
* Errors will be reported to ERR_REPORTING_FILE, if defined, and to
|
||||
* syslog, if ERR_REPORTING_SYSLOG is defined.
|
||||
* Errors will be reported to stdout, if ERR_REPORTING_STDOUT
|
||||
* is defined.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
err_report(int priority, char *format, ...);
|
||||
#endif /* ! SRTP_KERNEL_LINUX */
|
||||
srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -144,31 +105,28 @@ err_report(int priority, char *format, ...);
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
int on; /* 1 if debugging is on, 0 if it is off */
|
||||
char *name; /* printable name for debug module */
|
||||
} debug_module_t;
|
||||
int on; /* 1 if debugging is on, 0 if it is off */
|
||||
const char *name; /* printable name for debug module */
|
||||
} 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) \
|
||||
if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg)
|
||||
#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, arg)
|
||||
#define debug_print2(mod, format, arg1, arg2) \
|
||||
srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
|
||||
|
||||
#else
|
||||
|
||||
/* define macros to do nothing */
|
||||
#define debug_print(mod, format, arg)
|
||||
|
||||
#define debug_on(mod)
|
||||
|
||||
#define debug_off(mod)
|
||||
#define debug_print(mod, format, arg) \
|
||||
if (mod.on) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
|
||||
#define debug_print2(mod, format, arg1, arg2) \
|
||||
if (mod.on) srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg1, arg2)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ERR_H */
|
||||
|
|
|
@ -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 */
|
|
@ -1,33 +1,33 @@
|
|||
/*
|
||||
* hmac.h
|
||||
*
|
||||
* interface to hmac auth_type_t
|
||||
* interface to hmac srtp_auth_type_t
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006,2013, 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
|
||||
|
@ -50,33 +50,9 @@
|
|||
#include "sha1.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t opad[64];
|
||||
sha1_ctx_t ctx;
|
||||
sha1_ctx_t init_ctx;
|
||||
#ifdef OPENSSL
|
||||
int ctx_initialized;
|
||||
int init_ctx_initialized;
|
||||
#endif
|
||||
} hmac_ctx_t;
|
||||
|
||||
err_status_t
|
||||
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);
|
||||
|
||||
uint8_t opad[64];
|
||||
srtp_sha1_ctx_t ctx;
|
||||
srtp_sha1_ctx_t init_ctx;
|
||||
} srtp_hmac_ctx_t;
|
||||
|
||||
#endif /* HMAC_H */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,13 +47,6 @@
|
|||
#ifndef 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 */
|
||||
#ifdef HAVE_STDLIB_H
|
||||
|
@ -75,8 +68,12 @@
|
|||
# include <machine/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Can we do 64 bit integers? */
|
||||
#ifndef HAVE_UINT64_T
|
||||
#if !defined(HAVE_UINT64_T)
|
||||
# if SIZEOF_UNSIGNED_LONG == 8
|
||||
typedef unsigned long uint64_t;
|
||||
# elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||
|
@ -97,9 +94,12 @@ typedef unsigned short int uint16_t;
|
|||
#ifndef HAVE_UINT32_T
|
||||
typedef unsigned int uint32_t;
|
||||
#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;
|
||||
/* assert that sizeof(double) == 8 */
|
||||
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);
|
||||
#endif
|
||||
|
||||
#endif /* SRTP_KERNEL */
|
||||
|
||||
/* These macros are to load and store 32-bit values from un-aligned
|
||||
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)))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INTEGERS_H */
|
||||
|
|
|
@ -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 */
|
|
@ -2,31 +2,31 @@
|
|||
* key.h
|
||||
*
|
||||
* key usage limits enforcement
|
||||
*
|
||||
*
|
||||
* David A. Mcgrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -45,38 +45,42 @@
|
|||
#ifndef 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"
|
||||
|
||||
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 {
|
||||
key_event_normal,
|
||||
key_event_soft_limit,
|
||||
key_event_hard_limit
|
||||
} key_event_t;
|
||||
srtp_key_event_normal,
|
||||
srtp_key_event_soft_limit,
|
||||
srtp_key_event_hard_limit
|
||||
} srtp_key_event_t;
|
||||
|
||||
err_status_t
|
||||
key_limit_set(key_limit_t key, const xtd_seq_num_t s);
|
||||
srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key, const srtp_xtd_seq_num_t s);
|
||||
|
||||
err_status_t
|
||||
key_limit_clone(key_limit_t original, key_limit_t *new_key);
|
||||
srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original, srtp_key_limit_t *new_key);
|
||||
|
||||
err_status_t
|
||||
key_limit_check(const key_limit_t key);
|
||||
srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key);
|
||||
|
||||
key_event_t
|
||||
key_limit_update(key_limit_t key);
|
||||
srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key);
|
||||
|
||||
typedef enum {
|
||||
key_state_normal,
|
||||
key_state_past_soft_limit,
|
||||
key_state_expired
|
||||
} key_state_t;
|
||||
typedef enum {
|
||||
srtp_key_state_normal,
|
||||
srtp_key_state_past_soft_limit,
|
||||
srtp_key_state_expired
|
||||
} srtp_key_state_t;
|
||||
|
||||
typedef struct key_limit_ctx_t {
|
||||
xtd_seq_num_t num_left;
|
||||
key_state_t state;
|
||||
} key_limit_ctx_t;
|
||||
typedef struct srtp_key_limit_ctx_t {
|
||||
srtp_xtd_seq_num_t num_left;
|
||||
srtp_key_state_t state;
|
||||
} srtp_key_limit_ctx_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KEY_H */
|
||||
|
|
|
@ -7,26 +7,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -47,22 +47,27 @@
|
|||
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char foo;
|
||||
} null_auth_ctx_t;
|
||||
char foo;
|
||||
} srtp_null_auth_ctx_t;
|
||||
|
||||
err_status_t
|
||||
null_auth_alloc(auth_t **a, int key_len, int out_len);
|
||||
#if 0
|
||||
srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a, int key_len, int out_len);
|
||||
|
||||
err_status_t
|
||||
null_auth_dealloc(auth_t *a);
|
||||
srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a);
|
||||
|
||||
err_status_t
|
||||
null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len);
|
||||
srtp_err_status_t srtp_null_auth_init(srtp_null_auth_ctx_t *state, const uint8_t *key, int key_len);
|
||||
|
||||
err_status_t
|
||||
null_auth_compute (null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NULL_AUTH_H */
|
||||
|
|
|
@ -9,26 +9,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -52,29 +52,7 @@
|
|||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
char foo ;/* empty, for now */
|
||||
} 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);
|
||||
char foo; /* empty, for now */
|
||||
} srtp_null_cipher_ctx_t;
|
||||
|
||||
#endif /* NULL_CIPHER_H */
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
#define REPLAY_DB_H
|
||||
|
||||
#include "integers.h" /* for uint32_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
|
||||
|
@ -21,74 +61,69 @@
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t window_start; /* packet index of the first bit in bitmask */
|
||||
v128_t bitmask;
|
||||
} rdb_t;
|
||||
uint32_t window_start; /* packet index of the first bit in bitmask */
|
||||
v128_t bitmask;
|
||||
} 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
|
||||
*
|
||||
* returns err_status_ok on success, err_status_t_fail otherwise
|
||||
* returns srtp_err_status_ok on success, srtp_err_status_t_fail otherwise
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_init(rdb_t *rdb);
|
||||
srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb);
|
||||
|
||||
|
||||
/*
|
||||
* rdb_check
|
||||
* srtp_rdb_check
|
||||
*
|
||||
* checks to see if index appears in rdb
|
||||
*
|
||||
* returns err_status_fail if the index already appears in rdb,
|
||||
* returns err_status_ok otherwise
|
||||
* returns srtp_err_status_fail if the index already appears in rdb,
|
||||
* returns srtp_err_status_ok otherwise
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_check(const rdb_t *rdb, uint32_t rdb_index);
|
||||
srtp_err_status_t srtp_rdb_check(const srtp_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
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
|
||||
srtp_err_status_t srtp_rdb_add_index(srtp_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
|
||||
* 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
|
||||
*
|
||||
* return values:
|
||||
*
|
||||
* err_status_ok no problem
|
||||
* err_status_key_expired sequence number too high
|
||||
*
|
||||
* srtp_err_status_ok no problem
|
||||
* srtp_err_status_key_expired sequence number too high
|
||||
*
|
||||
*/
|
||||
err_status_t
|
||||
rdb_increment(rdb_t *rdb);
|
||||
srtp_err_status_t srtp_rdb_increment(srtp_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
|
||||
rdb_get_value(const rdb_t *rdb);
|
||||
uint32_t srtp_rdb_get_value(const srtp_rdb_t *rdb);
|
||||
|
||||
|
||||
#endif /* REPLAY_DB_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REPLAY_DB_H */
|
||||
|
|
|
@ -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
|
||||
#define RDBX_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "err.h"
|
||||
|
||||
/* #define ROC_TEST */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* #define ROC_TEST */
|
||||
|
||||
#ifndef ROC_TEST
|
||||
|
||||
typedef uint16_t sequence_number_t; /* 16 bit sequence number */
|
||||
typedef uint32_t rollover_counter_t; /* 32 bit rollover counter */
|
||||
typedef uint16_t srtp_sequence_number_t; /* 16 bit sequence number */
|
||||
typedef uint32_t srtp_rollover_counter_t; /* 32 bit rollover counter */
|
||||
|
||||
#else /* use small seq_num and roc datatypes for testing purposes */
|
||||
|
||||
typedef unsigned char sequence_number_t; /* 8 bit sequence number */
|
||||
typedef uint16_t rollover_counter_t; /* 16 bit rollover counter */
|
||||
typedef unsigned char srtp_sequence_number_t; /* 8 bit sequence number */
|
||||
typedef uint16_t srtp_rollover_counter_t; /* 16 bit rollover counter */
|
||||
|
||||
#endif
|
||||
|
||||
#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1))
|
||||
#define seq_num_max (1 << (8*sizeof(sequence_number_t)))
|
||||
#define seq_num_median (1 << (8 * sizeof(srtp_sequence_number_t) - 1))
|
||||
#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'
|
||||
* sequence number.
|
||||
* An rtp_xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'
|
||||
* sequence number.
|
||||
*/
|
||||
|
||||
typedef uint64_t xtd_seq_num_t;
|
||||
typedef uint64_t srtp_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.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
xtd_seq_num_t index;
|
||||
bitvector_t bitmask;
|
||||
} rdbx_t;
|
||||
srtp_xtd_seq_num_t index;
|
||||
bitvector_t bitmask;
|
||||
} 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,
|
||||
* setting the rollover counter and sequence number to zero
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_init(rdbx_t *rdbx, unsigned long ws);
|
||||
srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws);
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_dealloc(rdbx_ptr)
|
||||
* srtp_rdbx_dealloc(rdbx_ptr)
|
||||
*
|
||||
* frees memory associated with the rdbx
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_dealloc(rdbx_t *rdbx);
|
||||
srtp_err_status_t srtp_rdbx_dealloc(srtp_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),
|
||||
* sets the contents of *guess to contain the best guess of the packet
|
||||
* index to which s corresponds, and returns the difference between
|
||||
* *guess and the locally stored synch info
|
||||
*/
|
||||
|
||||
int
|
||||
rdbx_estimate_index(const rdbx_t *rdbx,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s);
|
||||
int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_check(const rdbx_t *rdbx, int difference);
|
||||
srtp_err_status_t srtp_rdbx_check(const srtp_rdbx_t *rdbx, int difference);
|
||||
|
||||
/*
|
||||
* replay_add_index(rdbx, delta)
|
||||
*
|
||||
* adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db
|
||||
* srtp_replay_add_index(rdbx, delta)
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
* this function should be called *only* after replay_check has
|
||||
* indicated that the index does not appear in the rdbx, and a mutex
|
||||
* should protect the rdbx between these calls if necessary.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_add_index(rdbx_t *rdbx, int delta);
|
||||
srtp_err_status_t srtp_rdbx_add_index(srtp_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
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc);
|
||||
srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc);
|
||||
|
||||
/*
|
||||
* rdbx_get_roc(rdbx) returns the value of the rollover counter for
|
||||
* the rdbx_t pointed to by rdbx
|
||||
*
|
||||
* srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter for
|
||||
* the srtp_rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
xtd_seq_num_t
|
||||
rdbx_get_packet_index(const rdbx_t *rdbx);
|
||||
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_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
|
||||
* api instead!
|
||||
*/
|
||||
|
||||
/*
|
||||
* rdbx_get_ws(rdbx_ptr)
|
||||
* srtp_rdbx_get_ws(rdbx_ptr)
|
||||
*
|
||||
* gets the window size which was used to initialize the rdbx
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
rdbx_get_window_size(const rdbx_t *rdbx);
|
||||
unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx);
|
||||
|
||||
|
||||
/* index_init(&pi) initializes a packet index pi (sets it to zero) */
|
||||
|
||||
void
|
||||
index_init(xtd_seq_num_t *pi);
|
||||
void srtp_index_init(srtp_xtd_seq_num_t *pi);
|
||||
|
||||
/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */
|
||||
|
||||
void
|
||||
index_advance(xtd_seq_num_t *pi, sequence_number_t s);
|
||||
void srtp_index_advance(srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s);
|
||||
|
||||
|
||||
/*
|
||||
* index_guess(local, guess, s)
|
||||
*
|
||||
* given a xtd_seq_num_t local (which represents the highest
|
||||
* srtp_index_guess(local, guess, s)
|
||||
*
|
||||
* 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
|
||||
* arrived packet), sets the contents of *guess to contain the best
|
||||
* guess of the packet index to which s corresponds, and returns the
|
||||
* difference between *guess and *local
|
||||
*/
|
||||
int32_t srtp_index_guess(const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s);
|
||||
|
||||
int
|
||||
index_guess(const xtd_seq_num_t *local,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s);
|
||||
/*
|
||||
* srtp_rdbx_get_roc(rdbx)
|
||||
*
|
||||
* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,26 +9,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -47,19 +47,31 @@
|
|||
#ifndef SHA1_H
|
||||
#define SHA1_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "err.h"
|
||||
#ifdef OPENSSL
|
||||
#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
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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_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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
#include "datatypes.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t H[5]; /* state vector */
|
||||
uint32_t M[16]; /* message buffer */
|
||||
int octets_in_buffer; /* octets of message in buffer */
|
||||
uint32_t num_bits_in_msg; /* total number of bits in message */
|
||||
} sha1_ctx_t;
|
||||
uint32_t H[5]; /* state vector */
|
||||
uint32_t M[16]; /* message buffer */
|
||||
int octets_in_buffer; /* octets of message in buffer */
|
||||
uint32_t num_bits_in_msg; /* total number of bits in message */
|
||||
} srtp_sha1_ctx_t;
|
||||
|
||||
|
||||
/*
|
||||
* sha1(&ctx, msg, len, output) hashes the len octets starting at msg
|
||||
* into the SHA1 context, then writes the result to the 20 octets at
|
||||
* output
|
||||
*
|
||||
*/
|
||||
|
||||
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
|
||||
* srtp_sha1_init(&ctx) initializes the SHA1 context ctx
|
||||
*
|
||||
* srtp_sha1_update(&ctx, msg, len) hashes the len octets starting at msg
|
||||
* into the SHA1 context
|
||||
*
|
||||
* sha1_final(&ctx, output) performs the final processing of the SHA1
|
||||
*
|
||||
* srtp_sha1_final(&ctx, output) performs the final processing of the SHA1
|
||||
* context and writes the result to the 20 octets at output
|
||||
*
|
||||
*/
|
||||
void srtp_sha1_init(srtp_sha1_ctx_t *ctx);
|
||||
|
||||
void
|
||||
sha1_init(sha1_ctx_t *ctx);
|
||||
void srtp_sha1_update(srtp_sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
|
||||
|
||||
void
|
||||
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]);
|
||||
void srtp_sha1_final(srtp_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
|
||||
* 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,
|
||||
* H1, ...}
|
||||
*
|
||||
* this function does not do any of the padding required in the
|
||||
* complete sha1 function
|
||||
*/
|
||||
|
||||
void
|
||||
sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
|
||||
void srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
|
||||
|
||||
#endif /* else OPENSSL */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHA1_H */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,22 +48,20 @@
|
|||
#define STAT_H
|
||||
|
||||
#include "datatypes.h" /* for uint8_t */
|
||||
#include "err.h" /* for err_status_t */
|
||||
#include "rand_source.h" /* for rand_source_func_t definition */
|
||||
#include "err.h" /* for srtp_err_status_t */
|
||||
|
||||
err_status_t
|
||||
stat_test_monobit(uint8_t *data);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_status_t
|
||||
stat_test_poker(uint8_t *data);
|
||||
srtp_err_status_t stat_test_monobit(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_runs(uint8_t *data);
|
||||
srtp_err_status_t stat_test_poker(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source(rand_source_func_t rs);
|
||||
srtp_err_status_t stat_test_runs(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STAT_H */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -42,35 +42,36 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "alloc.h"
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
/* the debug module for memory allocation */
|
||||
|
||||
debug_module_t mod_alloc = {
|
||||
srtp_debug_module_t mod_alloc = {
|
||||
0, /* debugging is off by default */
|
||||
"alloc" /* printable name for module */
|
||||
};
|
||||
|
||||
/*
|
||||
* Nota bene: the debugging statements for crypto_alloc() and
|
||||
* crypto_free() have identical prefixes, which include the addresses
|
||||
* Nota bene: the debugging statements for srtp_crypto_alloc() and
|
||||
* srtp_crypto_free() have identical prefixes, which include the addresses
|
||||
* of the memory locations on which they are operating. This fact can
|
||||
* be used to locate memory leaks, by turning on memory debugging,
|
||||
* grepping for 'alloc', then matching alloc and free calls by
|
||||
* address.
|
||||
*/
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
#if defined(HAVE_STDLIB_H)
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
void *
|
||||
crypto_alloc(size_t size) {
|
||||
void * srtp_crypto_alloc(size_t size) {
|
||||
void *ptr;
|
||||
|
||||
ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
|
||||
ptr = malloc(size);
|
||||
|
||||
if (ptr) {
|
||||
debug_print(mod_alloc, "(location: %p) allocated", ptr);
|
||||
} else {
|
||||
|
@ -80,33 +81,7 @@ crypto_alloc(size_t size) {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
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) {
|
||||
void srtp_crypto_free(void *ptr) {
|
||||
|
||||
debug_print(mod_alloc, "(location: %p) freed", ptr);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,26 +7,26 @@
|
|||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright(c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -42,107 +42,65 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "err.h"
|
||||
#include "datatypes.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ERR_REPORTING_SYSLOG
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
# endif
|
||||
#endif
|
||||
/* srtp_err_file is the FILE to which errors are reported */
|
||||
|
||||
static FILE *srtp_err_file = NULL;
|
||||
|
||||
/* err_level reflects the level of errors that are reported */
|
||||
|
||||
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...
|
||||
*/
|
||||
|
||||
srtp_err_status_t srtp_err_reporting_init ()
|
||||
{
|
||||
#ifdef ERR_REPORTING_STDOUT
|
||||
err_file = stdout;
|
||||
#elif defined(USE_ERR_REPORTING_FILE)
|
||||
/* open file for error reporting */
|
||||
err_file = fopen(ERR_REPORTING_FILE, "w");
|
||||
if (err_file == NULL)
|
||||
return 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"); */
|
||||
srtp_err_file = stdout;
|
||||
#elif defined(ERR_REPORTING_FILE)
|
||||
/* open file for error reporting */
|
||||
srtp_err_file = fopen(ERR_REPORTING_FILE, "w");
|
||||
if (srtp_err_file == NULL) {
|
||||
return srtp_err_status_init_fail;
|
||||
}
|
||||
#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
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
#endif /* SRTP_KERNEL_LINUX */
|
||||
|
||||
void
|
||||
err_reporting_set_level(err_reporting_level_t lvl) {
|
||||
err_level = lvl;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
* key.c
|
||||
*
|
||||
* key usage limits enforcement
|
||||
*
|
||||
*
|
||||
* David A. Mcgrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -42,74 +42,79 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "key.h"
|
||||
|
||||
#define soft_limit 0x10000
|
||||
|
||||
err_status_t
|
||||
key_limit_set(key_limit_t key, const xtd_seq_num_t s) {
|
||||
srtp_err_status_t srtp_key_limit_set (srtp_key_limit_t key, const srtp_xtd_seq_num_t s)
|
||||
{
|
||||
#ifdef NO_64BIT_MATH
|
||||
if (high32(s) == 0 && low32(s) < soft_limit)
|
||||
return err_status_bad_param;
|
||||
if (high32(s) == 0 && low32(s) < soft_limit) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
#else
|
||||
if (s < soft_limit)
|
||||
return err_status_bad_param;
|
||||
if (s < soft_limit) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
#endif
|
||||
key->num_left = s;
|
||||
key->state = key_state_normal;
|
||||
return err_status_ok;
|
||||
key->num_left = s;
|
||||
key->state = srtp_key_state_normal;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
key_limit_clone(key_limit_t original, key_limit_t *new_key) {
|
||||
if (original == NULL)
|
||||
return err_status_bad_param;
|
||||
*new_key = original;
|
||||
return err_status_ok;
|
||||
srtp_err_status_t srtp_key_limit_clone (srtp_key_limit_t original, srtp_key_limit_t *new_key)
|
||||
{
|
||||
if (original == NULL) {
|
||||
return srtp_err_status_bad_param;
|
||||
}
|
||||
*new_key = original;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
key_limit_check(const key_limit_t key) {
|
||||
if (key->state == key_state_expired)
|
||||
return err_status_key_expired;
|
||||
return err_status_ok;
|
||||
srtp_err_status_t srtp_key_limit_check (const srtp_key_limit_t key)
|
||||
{
|
||||
if (key->state == srtp_key_state_expired) {
|
||||
return srtp_err_status_key_expired;
|
||||
}
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
key_event_t
|
||||
key_limit_update(key_limit_t key) {
|
||||
srtp_key_event_t srtp_key_limit_update (srtp_key_limit_t key)
|
||||
{
|
||||
#ifdef NO_64BIT_MATH
|
||||
if (low32(key->num_left) == 0)
|
||||
{
|
||||
// carry
|
||||
key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no carry
|
||||
key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1);
|
||||
}
|
||||
if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {
|
||||
return key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
if (low32(key->num_left) == 0) {
|
||||
// carry
|
||||
key->num_left = make64(high32(key->num_left) - 1, low32(key->num_left) - 1);
|
||||
}else {
|
||||
// no carry
|
||||
key->num_left = make64(high32(key->num_left), low32(key->num_left) - 1);
|
||||
}
|
||||
if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {
|
||||
return srtp_key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
#else
|
||||
key->num_left--;
|
||||
if (key->num_left >= soft_limit) {
|
||||
return key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
key->num_left--;
|
||||
if (key->num_left >= soft_limit) {
|
||||
return srtp_key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
#endif
|
||||
if (key->state == key_state_normal) {
|
||||
/* we just passed the soft limit, so change the state */
|
||||
key->state = key_state_past_soft_limit;
|
||||
}
|
||||
if (key->state == srtp_key_state_normal) {
|
||||
/* we just passed the soft limit, so change the state */
|
||||
key->state = srtp_key_state_past_soft_limit;
|
||||
}
|
||||
#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
|
||||
if (key->num_left < 1)
|
||||
if (key->num_left < 1)
|
||||
#endif
|
||||
{ /* we just hit the hard limit */
|
||||
key->state = key_state_expired;
|
||||
return key_event_hard_limit;
|
||||
}
|
||||
return key_event_soft_limit;
|
||||
{ /* we just hit the hard limit */
|
||||
key->state = srtp_key_state_expired;
|
||||
return srtp_key_event_hard_limit;
|
||||
}
|
||||
return srtp_key_event_soft_limit;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,6 +43,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
int
|
||||
|
@ -98,14 +106,13 @@ octet_get_weight(uint8_t octet) {
|
|||
char bit_string[MAX_PRINT_STRING_LEN];
|
||||
|
||||
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',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
return buf[nibble & 0xF];
|
||||
}
|
||||
|
||||
char *
|
||||
octet_string_hex_string(const void *s, int length) {
|
||||
char * srtp_octet_string_hex_string(const void *s, int length) {
|
||||
const uint8_t *str = (const uint8_t *)s;
|
||||
int i;
|
||||
|
||||
|
@ -114,93 +121,23 @@ octet_string_hex_string(const void *s, int length) {
|
|||
|
||||
/* truncate string if it would be too long */
|
||||
if (length > MAX_PRINT_STRING_LEN)
|
||||
length = MAX_PRINT_STRING_LEN-1;
|
||||
length = MAX_PRINT_STRING_LEN-2;
|
||||
|
||||
for (i=0; i < length; i+=2) {
|
||||
bit_string[i] = nibble_to_hex_char(*str >> 4);
|
||||
bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF);
|
||||
bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
|
||||
bit_string[i+1] = srtp_nibble_to_hex_char(*str++ & 0xF);
|
||||
}
|
||||
bit_string[i] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
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 *
|
||||
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++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
|
||||
bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
|
@ -427,7 +364,7 @@ bitvector_alloc(bitvector_t *v, unsigned long length) {
|
|||
if (l == 0)
|
||||
v->word = NULL;
|
||||
else {
|
||||
v->word = (uint32_t*)crypto_alloc(l);
|
||||
v->word = (uint32_t*)srtp_crypto_alloc(l);
|
||||
if (v->word == NULL) {
|
||||
v->word = NULL;
|
||||
v->length = 0;
|
||||
|
@ -446,7 +383,7 @@ bitvector_alloc(bitvector_t *v, unsigned long length) {
|
|||
void
|
||||
bitvector_dealloc(bitvector_t *v) {
|
||||
if (v->word != NULL)
|
||||
crypto_free(v->word);
|
||||
srtp_crypto_free(v->word);
|
||||
v->word = NULL;
|
||||
v->length = 0;
|
||||
}
|
||||
|
@ -507,214 +444,75 @@ bitvector_left_shift(bitvector_t *x, int shift) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
|
||||
uint8_t *end = b + len;
|
||||
uint8_t accumulator = 0;
|
||||
|
||||
/*
|
||||
* We use this somewhat obscure implementation to try to ensure the running
|
||||
* time only depends on len, even accounting for compiler optimizations.
|
||||
* The accumulator ends up zero iff the strings are equal.
|
||||
*/
|
||||
while (b < end)
|
||||
if (*a++ != *b++)
|
||||
return 1;
|
||||
return 0;
|
||||
accumulator |= (*a++ ^ *b++);
|
||||
|
||||
/* Return 1 if *not* equal. */
|
||||
return accumulator != 0;
|
||||
}
|
||||
|
||||
void
|
||||
octet_string_set_to_zero(uint8_t *s, int len) {
|
||||
uint8_t *end = s + len;
|
||||
|
||||
do {
|
||||
*s = 0;
|
||||
} while (++s < end);
|
||||
|
||||
srtp_cleanse(void *s, size_t len)
|
||||
{
|
||||
volatile unsigned char *p = (volatile unsigned char *)s;
|
||||
while(len--) *p++ = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* From RFC 1521: The Base64 Alphabet
|
||||
*
|
||||
* Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
* 0 A 17 R 34 i 51 z
|
||||
* 1 B 18 S 35 j 52 0
|
||||
* 2 C 19 T 36 k 53 1
|
||||
* 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;
|
||||
void
|
||||
octet_string_set_to_zero(void *s, size_t len)
|
||||
{
|
||||
#ifdef OPENSSL
|
||||
OPENSSL_cleanse(s, len);
|
||||
#else
|
||||
srtp_cleanse(s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* base64_string_to_octet_string converts a hexadecimal string
|
||||
* of length 2 * len to a raw octet string of length len
|
||||
*/
|
||||
#ifdef TESTAPP_SOURCE
|
||||
|
||||
int
|
||||
base64_string_to_octet_string(char *raw, char *base64, int len) {
|
||||
uint8_t x;
|
||||
int tmp;
|
||||
int base64_len;
|
||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
base64_len = 0;
|
||||
while (base64_len < len) {
|
||||
tmp = base64_char_to_sextet(base64[0]);
|
||||
if (tmp == -1)
|
||||
return base64_len;
|
||||
x = (uint8_t)(tmp << 6);
|
||||
base64_len++;
|
||||
tmp = base64_char_to_sextet(base64[1]);
|
||||
if (tmp == -1)
|
||||
return base64_len;
|
||||
x |= (tmp & 0xffff);
|
||||
base64_len++;
|
||||
*raw++ = x;
|
||||
base64 += 2;
|
||||
static int base64_block_to_octet_triple(char *out, char *in) {
|
||||
unsigned char sextets[4] = {0};
|
||||
int j = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
char *p = strchr(b64chars, in[i]);
|
||||
if (p != NULL) sextets[i] = p - b64chars;
|
||||
else j++;
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,15 +1,55 @@
|
|||
/*
|
||||
* stats.c
|
||||
*
|
||||
* statistical tests for randomness (FIPS 140-2, Section 4.9)
|
||||
* statistical tests
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* 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"
|
||||
|
||||
debug_module_t mod_stat = {
|
||||
srtp_debug_module_t mod_stat = {
|
||||
0, /* debugging is off by default */
|
||||
(char *)"stat test" /* printable module name */
|
||||
};
|
||||
|
@ -21,26 +61,26 @@ debug_module_t mod_stat = {
|
|||
|
||||
#define STAT_TEST_DATA_LEN 2500
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
stat_test_monobit(uint8_t *data) {
|
||||
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
|
||||
uint16_t ones_count;
|
||||
|
||||
ones_count = 0;
|
||||
while (data < data_end) {
|
||||
ones_count += (uint16_t)octet_get_weight(*data);
|
||||
ones_count += octet_get_weight(*data);
|
||||
data++;
|
||||
}
|
||||
|
||||
debug_print(mod_stat, "bit count: %d", ones_count);
|
||||
|
||||
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) {
|
||||
int i;
|
||||
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);
|
||||
|
||||
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)
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
stat_test_runs(uint8_t *data) {
|
||||
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
|
||||
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
@ -107,7 +147,7 @@ stat_test_runs(uint8_t *data) {
|
|||
/* check for long runs */
|
||||
if (state > 25) {
|
||||
debug_print(mod_stat, ">25 runs: %d", state);
|
||||
return err_status_algo_fail;
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else if (state < 0) {
|
||||
|
@ -115,7 +155,7 @@ stat_test_runs(uint8_t *data) {
|
|||
/* prefix is a gap */
|
||||
if (state < -25) {
|
||||
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) {
|
||||
state = -6; /* group together gaps > 5 */
|
||||
|
@ -135,7 +175,7 @@ stat_test_runs(uint8_t *data) {
|
|||
/* prefix is a run */
|
||||
if (state > 25) {
|
||||
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) {
|
||||
state = 6; /* group together runs > 5 */
|
||||
|
@ -150,7 +190,7 @@ stat_test_runs(uint8_t *data) {
|
|||
/* check for long gaps */
|
||||
if (state < -25) {
|
||||
debug_print(mod_stat, ">25 gaps (2): %d", state);
|
||||
return err_status_algo_fail;
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -177,191 +217,10 @@ stat_test_runs(uint8_t *data) {
|
|||
for (i=0; i < 6; i++)
|
||||
if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
|
||||
|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
|
||||
return 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;
|
||||
}
|
||||
|
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -44,94 +44,100 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "rdb.h"
|
||||
|
||||
|
||||
/*
|
||||
* this implementation of a replay database works as follows:
|
||||
*
|
||||
*
|
||||
* window_start is the index of the first packet in the window
|
||||
* bitmask a bit-buffer, containing the most recently entered
|
||||
* index as the leftmost bit
|
||||
* index as the leftmost bit
|
||||
*
|
||||
*/
|
||||
|
||||
/* rdb_init initalizes rdb */
|
||||
|
||||
err_status_t
|
||||
rdb_init(rdb_t *rdb) {
|
||||
v128_set_to_zero(&rdb->bitmask);
|
||||
rdb->window_start = 0;
|
||||
return err_status_ok;
|
||||
/* srtp_rdb_init initalizes rdb */
|
||||
srtp_err_status_t srtp_rdb_init (srtp_rdb_t *rdb)
|
||||
{
|
||||
v128_set_to_zero(&rdb->bitmask);
|
||||
rdb->window_start = 0;
|
||||
return srtp_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
|
||||
rdb_check(const rdb_t *rdb, uint32_t p_index) {
|
||||
|
||||
/* if the index appears after (or at very end of) the window, its good */
|
||||
if (p_index >= rdb->window_start + rdb_bits_in_bitmask)
|
||||
return err_status_ok;
|
||||
|
||||
/* if the index appears before the window, its bad */
|
||||
if (p_index < rdb->window_start)
|
||||
return err_status_replay_old;
|
||||
/* if the index appears after (or at very end of) the window, its good */
|
||||
if (p_index >= rdb->window_start + rdb_bits_in_bitmask) {
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/* otherwise, the index appears within the window, so check the bitmask */
|
||||
if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1)
|
||||
return err_status_replay_fail;
|
||||
|
||||
/* otherwise, the index is okay */
|
||||
return err_status_ok;
|
||||
/* if the index appears before the window, its bad */
|
||||
if (p_index < rdb->window_start) {
|
||||
return srtp_err_status_replay_old;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
rdb_add_index(rdb_t *rdb, uint32_t p_index) {
|
||||
int delta;
|
||||
/* here we *assume* that p_index > rdb->window_start */
|
||||
|
||||
/* 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 (delta < rdb_bits_in_bitmask) {
|
||||
/* if the p_index is within the window, set the appropriate bit */
|
||||
v128_set_bit(&rdb->bitmask, delta);
|
||||
|
||||
/* if the p_index is within the window, set the appropriate bit */
|
||||
v128_set_bit(&rdb->bitmask, delta);
|
||||
} else {
|
||||
|
||||
} else {
|
||||
|
||||
delta -= rdb_bits_in_bitmask - 1;
|
||||
delta -= rdb_bits_in_bitmask - 1;
|
||||
|
||||
/* shift the window forward by delta bits*/
|
||||
v128_left_shift(&rdb->bitmask, delta);
|
||||
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1);
|
||||
rdb->window_start += delta;
|
||||
/* shift the window forward by delta bits*/
|
||||
v128_left_shift(&rdb->bitmask, delta);
|
||||
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask - 1);
|
||||
rdb->window_start += delta;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rdb_increment(rdb_t *rdb) {
|
||||
srtp_err_status_t srtp_rdb_increment (srtp_rdb_t *rdb)
|
||||
{
|
||||
|
||||
if (rdb->window_start++ > 0x7fffffff)
|
||||
return err_status_key_expired;
|
||||
return err_status_ok;
|
||||
if (rdb->window_start >= 0x7fffffff) {
|
||||
return srtp_err_status_key_expired;
|
||||
}
|
||||
++rdb->window_start;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rdb_get_value(const rdb_t *rdb) {
|
||||
return rdb->window_start;
|
||||
uint32_t srtp_rdb_get_value (const srtp_rdb_t *rdb)
|
||||
{
|
||||
return rdb->window_start;
|
||||
}
|
||||
|
|
|
@ -8,26 +8,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
*
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
|
@ -43,6 +43,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "rdbx.h"
|
||||
|
||||
|
||||
|
@ -65,111 +69,109 @@
|
|||
/*
|
||||
* 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
|
||||
* rollover counter and a sequence number; the sequence number is the
|
||||
* explicit part, and the rollover counter is the implicit part.
|
||||
*
|
||||
* 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
|
||||
* local xtd_seq_num_t as a basis. This is done using the function
|
||||
* index_guess(&local, &guess, seq_from_packet). This function
|
||||
* packet), the complete srtp_xtd_seq_num_t can be estimated by using a
|
||||
* local srtp_xtd_seq_num_t as a basis. This is done using the function
|
||||
* srtp_index_guess(&local, &guess, seq_from_packet). This function
|
||||
* 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
|
||||
* index_advance(&guess, delta), where delta is the difference.
|
||||
*
|
||||
* srtp_xtd_seq_num_t can be moved forward to the guess using the function
|
||||
* 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
|
||||
* which of the recent indicies have been received as well. The
|
||||
* highest bit in the bitmask corresponds to the index in the bitmask.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
index_init(xtd_seq_num_t *pi) {
|
||||
void srtp_index_init (srtp_xtd_seq_num_t *pi)
|
||||
{
|
||||
#ifdef NO_64BIT_MATH
|
||||
*pi = make64(0,0);
|
||||
*pi = make64(0, 0);
|
||||
#else
|
||||
*pi = 0;
|
||||
*pi = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
index_advance(xtd_seq_num_t *pi, sequence_number_t s) {
|
||||
void srtp_index_advance (srtp_xtd_seq_num_t *pi, srtp_sequence_number_t s)
|
||||
{
|
||||
#ifdef NO_64BIT_MATH
|
||||
/* a > ~b means a+b will generate a carry */
|
||||
/* s is uint16 here */
|
||||
*pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s);
|
||||
/* a > ~b means a+b will generate a carry */
|
||||
/* s is uint16 here */
|
||||
*pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0), low32(*pi) + s);
|
||||
#else
|
||||
*pi += s;
|
||||
*pi += s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* index_guess(local, guess, s)
|
||||
*
|
||||
* given a xtd_seq_num_t local (which represents the last
|
||||
* known-to-be-good received xtd_seq_num_t) and a sequence number s
|
||||
* srtp_index_guess(local, guess, s)
|
||||
*
|
||||
* given a srtp_xtd_seq_num_t local (which represents the last
|
||||
* 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
|
||||
* contain the best guess of the packet index to which s corresponds,
|
||||
* and returns the difference between *guess and *local
|
||||
*
|
||||
* nota bene - the output is a signed integer, DON'T cast it to a
|
||||
* unsigned integer!
|
||||
* unsigned integer!
|
||||
*/
|
||||
|
||||
int
|
||||
index_guess(const xtd_seq_num_t *local,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s) {
|
||||
int32_t srtp_index_guess (const srtp_xtd_seq_num_t *local, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s)
|
||||
{
|
||||
#ifdef NO_64BIT_MATH
|
||||
uint32_t local_roc = ((high32(*local) << 16) |
|
||||
(low32(*local) >> 16));
|
||||
uint16_t local_seq = (uint16_t) (low32(*local));
|
||||
uint32_t local_roc = ((high32(*local) << 16) |
|
||||
(low32(*local) >> 16));
|
||||
uint16_t local_seq = (uint16_t)(low32(*local));
|
||||
#else
|
||||
uint32_t local_roc = (uint32_t)(*local >> 16);
|
||||
uint16_t local_seq = (uint16_t) *local;
|
||||
uint32_t local_roc = (uint32_t)(*local >> 16);
|
||||
uint16_t local_seq = (uint16_t)*local;
|
||||
#endif
|
||||
#ifdef NO_64BIT_MATH
|
||||
uint32_t guess_roc = ((high32(*guess) << 16) |
|
||||
(low32(*guess) >> 16));
|
||||
uint16_t guess_seq = (uint16_t) (low32(*guess));
|
||||
uint32_t guess_roc = ((high32(*guess) << 16) |
|
||||
(low32(*guess) >> 16));
|
||||
uint16_t guess_seq = (uint16_t)(low32(*guess));
|
||||
#else
|
||||
uint32_t guess_roc = (uint32_t)(*guess >> 16);
|
||||
uint16_t guess_seq = (uint16_t) *guess;
|
||||
uint32_t guess_roc = (uint32_t)(*guess >> 16);
|
||||
uint16_t guess_seq = (uint16_t)*guess;
|
||||
#endif
|
||||
int difference;
|
||||
|
||||
if (local_seq < seq_num_median) {
|
||||
if (s - local_seq > seq_num_median) {
|
||||
guess_roc = local_roc - 1;
|
||||
difference = s - local_seq - seq_num_max;
|
||||
int32_t difference;
|
||||
|
||||
if (local_seq < seq_num_median) {
|
||||
if (s - local_seq > seq_num_median) {
|
||||
guess_roc = local_roc - 1;
|
||||
difference = s - local_seq - seq_num_max;
|
||||
} else {
|
||||
guess_roc = local_roc;
|
||||
difference = s - local_seq;
|
||||
}
|
||||
} else {
|
||||
guess_roc = local_roc;
|
||||
difference = s - local_seq;
|
||||
if (local_seq - seq_num_median > s) {
|
||||
guess_roc = local_roc + 1;
|
||||
difference = s - local_seq + seq_num_max;
|
||||
} else {
|
||||
guess_roc = local_roc;
|
||||
difference = s - local_seq;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (local_seq - seq_num_median > s) {
|
||||
guess_roc = local_roc + 1;
|
||||
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! */
|
||||
guess_seq = s;
|
||||
|
||||
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
|
||||
#ifdef NO_64BIT_MATH
|
||||
*guess = make64(guess_roc >> 16,
|
||||
(guess_roc << 16) | guess_seq);
|
||||
*guess = make64(guess_roc >> 16,
|
||||
(guess_roc << 16) | guess_seq);
|
||||
#else
|
||||
*guess = (((uint64_t) guess_roc) << 16) | guess_seq;
|
||||
*guess = (((uint64_t)guess_roc) << 16) | guess_seq;
|
||||
#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
|
||||
rdbx_init(rdbx_t *rdbx, unsigned long ws) {
|
||||
if (ws == 0)
|
||||
return err_status_bad_param;
|
||||
if (bitvector_alloc(&rdbx->bitmask, ws) != 0) {
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
|
||||
if (bitvector_alloc(&rdbx->bitmask, ws) != 0)
|
||||
return err_status_alloc_fail;
|
||||
srtp_index_init(&rdbx->index);
|
||||
|
||||
index_init(&rdbx->index);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_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
|
||||
rdbx_dealloc(rdbx_t *rdbx) {
|
||||
bitvector_dealloc(&rdbx->bitmask);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_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
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) {
|
||||
bitvector_set_to_zero(&rdbx->bitmask);
|
||||
srtp_err_status_t srtp_rdbx_set_roc (srtp_rdbx_t *rdbx, uint32_t roc)
|
||||
{
|
||||
bitvector_set_to_zero(&rdbx->bitmask);
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
#error not yet implemented
|
||||
#else
|
||||
|
||||
/* make sure that we're not moving backwards */
|
||||
if (roc < (rdbx->index >> 16))
|
||||
return err_status_replay_old;
|
||||
/* make sure that we're not moving backwards */
|
||||
if (roc < (rdbx->index >> 16)) {
|
||||
return srtp_err_status_replay_old;
|
||||
}
|
||||
|
||||
rdbx->index &= 0xffff; /* retain lowest 16 bits */
|
||||
rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
|
||||
rdbx->index &= 0xffff; /* retain lowest 16 bits */
|
||||
rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
|
||||
#endif
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_get_packet_index(rdbx) returns the value of the packet index
|
||||
* for the rdbx_t pointed to by rdbx
|
||||
*
|
||||
* srtp_rdbx_get_packet_index(rdbx) returns the value of the packet index
|
||||
* for the srtp_rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
xtd_seq_num_t
|
||||
rdbx_get_packet_index(const rdbx_t *rdbx) {
|
||||
return rdbx->index;
|
||||
srtp_xtd_seq_num_t srtp_rdbx_get_packet_index (const srtp_rdbx_t *rdbx)
|
||||
{
|
||||
return rdbx->index;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_get_window_size(rdbx) returns the value of the window size
|
||||
* for the rdbx_t pointed to by rdbx
|
||||
*
|
||||
* srtp_rdbx_get_window_size(rdbx) returns the value of the window size
|
||||
* for the srtp_rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
rdbx_get_window_size(const rdbx_t *rdbx) {
|
||||
return bitvector_get_length(&rdbx->bitmask);
|
||||
unsigned long srtp_rdbx_get_window_size (const srtp_rdbx_t *rdbx)
|
||||
{
|
||||
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
|
||||
*/
|
||||
srtp_err_status_t srtp_rdbx_check (const srtp_rdbx_t *rdbx, int delta)
|
||||
{
|
||||
|
||||
err_status_t
|
||||
rdbx_check(const rdbx_t *rdbx, int delta) {
|
||||
|
||||
if (delta > 0) { /* if delta is positive, it's good */
|
||||
return err_status_ok;
|
||||
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
|
||||
/* if delta is lower than the bitmask, it's bad */
|
||||
return err_status_replay_old;
|
||||
} else if (bitvector_get_bit(&rdbx->bitmask,
|
||||
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
|
||||
/* delta is within the window, so check the bitmask */
|
||||
return err_status_replay_fail;
|
||||
}
|
||||
/* otherwise, the index is okay */
|
||||
if (delta > 0) { /* if delta is positive, it's good */
|
||||
return srtp_err_status_ok;
|
||||
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
|
||||
/* if delta is lower than the bitmask, it's bad */
|
||||
return srtp_err_status_replay_old;
|
||||
} else if (bitvector_get_bit(&rdbx->bitmask,
|
||||
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
|
||||
/* delta is within the window, so check the bitmask */
|
||||
return srtp_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
|
||||
* replay_db (and does *not* check if that xtd_seq_num_t appears in db)
|
||||
* 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 srtp_xtd_seq_num_t appears in db)
|
||||
*
|
||||
* this function should be called only after replay_check has
|
||||
* indicated that the index does not appear in the rdbx, e.g., a mutex
|
||||
* should protect the rdbx between these calls if need be
|
||||
*/
|
||||
srtp_err_status_t srtp_rdbx_add_index (srtp_rdbx_t *rdbx, int delta)
|
||||
{
|
||||
|
||||
err_status_t
|
||||
rdbx_add_index(rdbx_t *rdbx, int delta) {
|
||||
|
||||
if (delta > 0) {
|
||||
/* shift forward by delta */
|
||||
index_advance(&rdbx->index, (sequence_number_t)delta);
|
||||
bitvector_left_shift(&rdbx->bitmask, delta);
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
|
||||
} else {
|
||||
/* delta is in window */
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
|
||||
}
|
||||
if (delta > 0) {
|
||||
/* shift forward by delta */
|
||||
srtp_index_advance(&rdbx->index, delta);
|
||||
bitvector_left_shift(&rdbx->bitmask, delta);
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
|
||||
} 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 */
|
||||
|
||||
return err_status_ok;
|
||||
/* note that we need not consider the case that delta == 0 */
|
||||
|
||||
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),
|
||||
* sets the contents of *guess to contain the best guess of the packet
|
||||
* index to which s corresponds, and returns the difference between
|
||||
* *guess and the locally stored synch info
|
||||
*/
|
||||
int32_t srtp_rdbx_estimate_index (const srtp_rdbx_t *rdbx, srtp_xtd_seq_num_t *guess, srtp_sequence_number_t s)
|
||||
{
|
||||
|
||||
int
|
||||
rdbx_estimate_index(const rdbx_t *rdbx,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s) {
|
||||
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
/*
|
||||
* if the sequence number and rollover counter in the rdbx are
|
||||
* non-zero, then use the srtp_index_guess(...) function, otherwise, just
|
||||
* set the rollover counter to zero (since the srtp_index_guess(...)
|
||||
* function might incorrectly guess that the rollover counter is
|
||||
* 0xffffffff)
|
||||
*/
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
/* seq_num_median = 0x8000 */
|
||||
if (high32(rdbx->index) > 0 ||
|
||||
low32(rdbx->index) > seq_num_median)
|
||||
/* seq_num_median = 0x8000 */
|
||||
if (high32(rdbx->index) > 0 ||
|
||||
low32(rdbx->index) > seq_num_median)
|
||||
#else
|
||||
if (rdbx->index > seq_num_median)
|
||||
if (rdbx->index > seq_num_median)
|
||||
#endif
|
||||
return index_guess(&rdbx->index, guess, s);
|
||||
|
||||
{ return srtp_index_guess(&rdbx->index, guess, s); }
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
*guess = make64(0,(uint32_t) s);
|
||||
#else
|
||||
*guess = s;
|
||||
*guess = make64(0, (uint32_t)s);
|
||||
#else
|
||||
*guess = s;
|
||||
#endif
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
return s - (uint16_t) low32(rdbx->index);
|
||||
return s - (uint16_t)low32(rdbx->index);
|
||||
#else
|
||||
return s - (uint16_t) rdbx->index;
|
||||
return s - (uint16_t)rdbx->index;
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,6 +45,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "ut_sim.h"
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
aes_calc
|
||||
cipher_driver
|
||||
datatypes_driver
|
||||
env
|
||||
kernel_driver
|
||||
rand_gen
|
||||
sha1_driver
|
||||
stat_driver
|
|
@ -7,6 +7,42 @@
|
|||
* 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):
|
||||
|
@ -18,9 +54,14 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "aes.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
|
@ -34,10 +75,10 @@ int
|
|||
main (int argc, char *argv[]) {
|
||||
v128_t data;
|
||||
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 verbose = 0;
|
||||
err_status_t status;
|
||||
srtp_err_status_t status;
|
||||
|
||||
if (argc == 3) {
|
||||
/* we're not in verbose mode */
|
||||
|
@ -98,14 +139,14 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
/* 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) {
|
||||
fprintf(stderr,
|
||||
"error: AES key expansion failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
aes_encrypt(&data, &exp_key);
|
||||
srtp_aes_encrypt(&data, &exp_key);
|
||||
|
||||
/* write ciphertext to output */
|
||||
if (verbose) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006,2013 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 <stdlib.h> /* for rand() */
|
||||
#include <string.h> /* for memset() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "getopt_s.h"
|
||||
#include "cipher.h"
|
||||
#ifdef OPENSSL
|
||||
#include "aes_icm_ossl.h"
|
||||
|
@ -54,15 +58,14 @@
|
|||
#else
|
||||
#include "aes_icm.h"
|
||||
#endif
|
||||
#include "null_cipher.h"
|
||||
|
||||
#define PRINT_DEBUG 0
|
||||
|
||||
void
|
||||
cipher_driver_test_throughput(cipher_t *c);
|
||||
cipher_driver_test_throughput(srtp_cipher_t *c);
|
||||
|
||||
err_status_t
|
||||
cipher_driver_self_test(cipher_type_t *ct);
|
||||
srtp_err_status_t
|
||||
cipher_driver_self_test(srtp_cipher_type_t *ct);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -71,30 +74,30 @@ cipher_driver_self_test(cipher_type_t *ct);
|
|||
* calls
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_buffering(cipher_t *c);
|
||||
srtp_err_status_t
|
||||
cipher_driver_test_buffering(srtp_cipher_t *c);
|
||||
|
||||
|
||||
/*
|
||||
* functions for testing cipher cache thrash
|
||||
*/
|
||||
err_status_t
|
||||
cipher_driver_test_array_throughput(cipher_type_t *ct,
|
||||
srtp_err_status_t
|
||||
cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
|
||||
int klen, int num_cipher);
|
||||
|
||||
void
|
||||
cipher_array_test_throughput(cipher_t *ca[], int num_cipher);
|
||||
cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
|
||||
|
||||
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);
|
||||
|
||||
err_status_t
|
||||
cipher_array_delete(cipher_t *cipher_array[], int num_cipher);
|
||||
srtp_err_status_t
|
||||
cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher);
|
||||
|
||||
err_status_t
|
||||
cipher_array_alloc_init(cipher_t ***cipher_array, int num_ciphers,
|
||||
cipher_type_t *ctype, int klen);
|
||||
srtp_err_status_t
|
||||
cipher_array_alloc_init(srtp_cipher_t ***cipher_array, int num_ciphers,
|
||||
srtp_cipher_type_t *ctype, int klen);
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
|
@ -103,7 +106,7 @@ usage(char *prog_name) {
|
|||
}
|
||||
|
||||
void
|
||||
check_status(err_status_t s) {
|
||||
check_status(srtp_err_status_t s) {
|
||||
if (s) {
|
||||
printf("error (code %d)\n", 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
|
||||
* declared external so that we can use these cipher types here
|
||||
*/
|
||||
|
||||
extern cipher_type_t null_cipher;
|
||||
extern cipher_type_t aes_icm;
|
||||
#ifndef OPENSSL
|
||||
extern cipher_type_t aes_cbc;
|
||||
#else
|
||||
extern cipher_type_t aes_icm_192;
|
||||
extern cipher_type_t aes_icm_256;
|
||||
extern cipher_type_t aes_gcm_128_openssl;
|
||||
extern cipher_type_t aes_gcm_256_openssl;
|
||||
extern srtp_cipher_type_t srtp_null_cipher;
|
||||
extern srtp_cipher_type_t srtp_aes_icm_128;
|
||||
extern srtp_cipher_type_t srtp_aes_icm_256;
|
||||
#ifdef OPENSSL
|
||||
extern srtp_cipher_type_t srtp_aes_icm_192;
|
||||
extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
|
||||
extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
cipher_t *c = NULL;
|
||||
err_status_t status;
|
||||
srtp_cipher_t *c = NULL;
|
||||
srtp_err_status_t status;
|
||||
unsigned char test_key[48] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
|
@ -147,7 +148,7 @@ main(int argc, char *argv[]) {
|
|||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "tva");
|
||||
q = getopt_s(argc, argv, "tva");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
|
@ -164,7 +165,7 @@ main(int argc, char *argv[]) {
|
|||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("cipher test driver\n"
|
||||
"David A. McGrew\n"
|
||||
"Cisco Systems, Inc.\n");
|
||||
|
@ -178,55 +179,44 @@ main(int argc, char *argv[]) {
|
|||
int num_cipher;
|
||||
|
||||
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)
|
||||
cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher);
|
||||
|
||||
#ifndef OPENSSL
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher);
|
||||
cipher_driver_test_array_throughput(&srtp_aes_icm_128, SRTP_AES_ICM_128_KEY_LEN_WSALT, num_cipher);
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_cbc, 16, 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);
|
||||
cipher_driver_test_array_throughput(&srtp_aes_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
|
||||
|
||||
#ifdef OPENSSL
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&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) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
if (do_validation) {
|
||||
cipher_driver_self_test(&null_cipher);
|
||||
cipher_driver_self_test(&aes_icm);
|
||||
#ifndef OPENSSL
|
||||
cipher_driver_self_test(&aes_cbc);
|
||||
#else
|
||||
cipher_driver_self_test(&aes_icm_192);
|
||||
cipher_driver_self_test(&aes_icm_256);
|
||||
cipher_driver_self_test(&aes_gcm_128_openssl);
|
||||
cipher_driver_self_test(&aes_gcm_256_openssl);
|
||||
cipher_driver_self_test(&srtp_null_cipher);
|
||||
cipher_driver_self_test(&srtp_aes_icm_128);
|
||||
cipher_driver_self_test(&srtp_aes_icm_256);
|
||||
#ifdef OPENSSL
|
||||
cipher_driver_self_test(&srtp_aes_icm_192);
|
||||
cipher_driver_self_test(&srtp_aes_gcm_128_openssl);
|
||||
cipher_driver_self_test(&srtp_aes_gcm_256_openssl);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* do timing and/or buffer_test on null_cipher */
|
||||
status = cipher_type_alloc(&null_cipher, &c, 0, 0);
|
||||
/* do timing and/or buffer_test on srtp_null_cipher */
|
||||
status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
|
||||
check_status(status);
|
||||
|
||||
status = cipher_init(c, NULL);
|
||||
status = srtp_cipher_init(c, NULL);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
|
@ -235,18 +225,18 @@ main(int argc, char *argv[]) {
|
|||
status = cipher_driver_test_buffering(c);
|
||||
check_status(status);
|
||||
}
|
||||
status = cipher_dealloc(c);
|
||||
status = srtp_cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
|
||||
/* 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) {
|
||||
fprintf(stderr, "error: can't allocate cipher\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
status = cipher_init(c, test_key);
|
||||
status = srtp_cipher_init(c, test_key);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
|
@ -257,21 +247,17 @@ main(int argc, char *argv[]) {
|
|||
check_status(status);
|
||||
}
|
||||
|
||||
status = cipher_dealloc(c);
|
||||
status = srtp_cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
/* repeat the tests with 256-bit keys */
|
||||
#ifndef OPENSSL
|
||||
status = cipher_type_alloc(&aes_icm, &c, 46, 0);
|
||||
#else
|
||||
status = cipher_type_alloc(&aes_icm_256, &c, 46, 0);
|
||||
#endif
|
||||
status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: can't allocate cipher\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
status = cipher_init(c, test_key);
|
||||
status = srtp_cipher_init(c, test_key);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
|
@ -282,17 +268,17 @@ main(int argc, char *argv[]) {
|
|||
check_status(status);
|
||||
}
|
||||
|
||||
status = cipher_dealloc(c);
|
||||
status = srtp_cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
#ifdef OPENSSL
|
||||
/* 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) {
|
||||
fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
|
||||
exit(status);
|
||||
}
|
||||
status = cipher_init(c, test_key);
|
||||
status = srtp_cipher_init(c, test_key);
|
||||
check_status(status);
|
||||
if (do_timing_test) {
|
||||
cipher_driver_test_throughput(c);
|
||||
|
@ -302,16 +288,16 @@ main(int argc, char *argv[]) {
|
|||
status = cipher_driver_test_buffering(c);
|
||||
check_status(status);
|
||||
}
|
||||
status = cipher_dealloc(c);
|
||||
status = srtp_cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
/* run the throughput test on the aes_gcm_256_openssl cipher */
|
||||
status = cipher_type_alloc(&aes_gcm_256_openssl, &c, 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) {
|
||||
fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
|
||||
exit(status);
|
||||
}
|
||||
status = cipher_init(c, test_key);
|
||||
status = srtp_cipher_init(c, test_key);
|
||||
check_status(status);
|
||||
if (do_timing_test) {
|
||||
cipher_driver_test_throughput(c);
|
||||
|
@ -321,7 +307,7 @@ main(int argc, char *argv[]) {
|
|||
status = cipher_driver_test_buffering(c);
|
||||
check_status(status);
|
||||
}
|
||||
status = cipher_dealloc(c);
|
||||
status = srtp_cipher_dealloc(c);
|
||||
check_status(status);
|
||||
#endif
|
||||
|
||||
|
@ -329,7 +315,7 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
void
|
||||
cipher_driver_test_throughput(cipher_t *c) {
|
||||
cipher_driver_test_throughput(srtp_cipher_t *c) {
|
||||
int i;
|
||||
int min_enc_len = 32;
|
||||
int max_enc_len = 2048; /* should be a power of two */
|
||||
|
@ -339,23 +325,23 @@ cipher_driver_test_throughput(cipher_t *c) {
|
|||
fflush(stdout);
|
||||
for (i=min_enc_len; i <= max_enc_len; i = i * 2)
|
||||
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
|
||||
cipher_driver_self_test(cipher_type_t *ct) {
|
||||
err_status_t status;
|
||||
srtp_err_status_t
|
||||
cipher_driver_self_test(srtp_cipher_type_t *ct) {
|
||||
srtp_err_status_t status;
|
||||
|
||||
printf("running cipher self-test for %s...", ct->description);
|
||||
status = cipher_type_self_test(ct);
|
||||
status = srtp_cipher_type_self_test(ct);
|
||||
if (status) {
|
||||
printf("failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_buffering(cipher_t *c) {
|
||||
#define INITIAL_BUFLEN 1024
|
||||
srtp_err_status_t
|
||||
cipher_driver_test_buffering(srtp_cipher_t *c) {
|
||||
int i, j, num_trials = 1000;
|
||||
unsigned len, buflen = 1024;
|
||||
uint8_t buffer0[buflen], buffer1[buflen], *current, *end;
|
||||
unsigned len, buflen = INITIAL_BUFLEN;
|
||||
uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
|
||||
uint8_t idx[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34
|
||||
};
|
||||
err_status_t status;
|
||||
srtp_err_status_t status;
|
||||
|
||||
printf("testing output buffering for cipher %s...",
|
||||
c->type->description);
|
||||
|
@ -381,21 +368,22 @@ cipher_driver_test_buffering(cipher_t *c) {
|
|||
for (i=0; i < num_trials; i++) {
|
||||
|
||||
/* set buffers to zero */
|
||||
for (j=0; j < buflen; j++)
|
||||
for (j=0; j < (int) buflen; j++) {
|
||||
buffer0[j] = buffer1[j] = 0;
|
||||
}
|
||||
|
||||
/* initialize cipher */
|
||||
status = cipher_set_iv(c, idx, direction_encrypt);
|
||||
status = srtp_cipher_set_iv(c, (uint8_t*)idx, srtp_direction_encrypt);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* generate 'reference' value by encrypting all at once */
|
||||
status = cipher_encrypt(c, buffer0, &buflen);
|
||||
status = srtp_cipher_encrypt(c, buffer0, &buflen);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* 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)
|
||||
return status;
|
||||
|
||||
|
@ -411,7 +399,7 @@ cipher_driver_test_buffering(cipher_t *c) {
|
|||
if (current + len > end)
|
||||
len = end - current;
|
||||
|
||||
status = cipher_encrypt(c, current, &len);
|
||||
status = srtp_cipher_encrypt(c, current, &len);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -424,20 +412,21 @@ cipher_driver_test_buffering(cipher_t *c) {
|
|||
}
|
||||
|
||||
/* compare buffers */
|
||||
for (j=0; j < buflen; j++)
|
||||
for (j=0; j < (int) buflen; j++) {
|
||||
if (buffer0[j] != buffer1[j]) {
|
||||
#if PRINT_DEBUG
|
||||
printf("test case %d failed at byte %d\n", i, j);
|
||||
printf("computed: %s\n", octet_string_hex_string(buffer1, buflen));
|
||||
printf("expected: %s\n", octet_string_hex_string(buffer0, buflen));
|
||||
#endif
|
||||
return err_status_algo_fail;
|
||||
return srtp_err_status_algo_fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
||||
cipher_type_t *ctype, int klen) {
|
||||
srtp_err_status_t
|
||||
cipher_array_alloc_init(srtp_cipher_t ***ca, int num_ciphers,
|
||||
srtp_cipher_type_t *ctype, int klen) {
|
||||
int i, j;
|
||||
err_status_t status;
|
||||
srtp_err_status_t status;
|
||||
uint8_t *key;
|
||||
cipher_t **cipher_array;
|
||||
srtp_cipher_t **cipher_array;
|
||||
/* pad klen allocation, to handle aes_icm reading 16 bytes for the
|
||||
14-byte salt */
|
||||
int klen_pad = ((klen + 15) >> 4) << 4;
|
||||
|
||||
/* allocate array of pointers to ciphers */
|
||||
cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers);
|
||||
cipher_array = (srtp_cipher_t **) malloc(sizeof(srtp_cipher_t *) * num_ciphers);
|
||||
if (cipher_array == NULL)
|
||||
return err_status_alloc_fail;
|
||||
return srtp_err_status_alloc_fail;
|
||||
|
||||
/* set ca to location of cipher_array */
|
||||
*ca = cipher_array;
|
||||
|
||||
/* allocate key */
|
||||
key = crypto_alloc(klen_pad);
|
||||
key = srtp_crypto_alloc(klen_pad);
|
||||
if (key == NULL) {
|
||||
free(cipher_array);
|
||||
return err_status_alloc_fail;
|
||||
return srtp_err_status_alloc_fail;
|
||||
}
|
||||
|
||||
/* allocate and initialize an array of ciphers */
|
||||
for (i=0; i < num_ciphers; i++) {
|
||||
|
||||
/* allocate cipher */
|
||||
status = cipher_type_alloc(ctype, cipher_array, klen, 16);
|
||||
status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -488,7 +477,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
key[j] = (uint8_t) rand();
|
||||
for (; j < klen_pad; j++)
|
||||
key[j] = 0;
|
||||
status = cipher_init(*cipher_array, key);
|
||||
status = srtp_cipher_init(*cipher_array, key);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -500,22 +489,22 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
cipher_array++;
|
||||
}
|
||||
|
||||
crypto_free(key);
|
||||
srtp_crypto_free(key);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
cipher_array_delete(cipher_t *cipher_array[], int num_cipher) {
|
||||
srtp_err_status_t
|
||||
cipher_array_delete(srtp_cipher_t *cipher_array[], int num_cipher) {
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_cipher; i++) {
|
||||
cipher_dealloc(cipher_array[i]);
|
||||
srtp_cipher_dealloc(cipher_array[i]);
|
||||
}
|
||||
|
||||
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
|
||||
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) {
|
||||
int i;
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
return 0; /* indicate bad parameters by returning null */
|
||||
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);
|
||||
timer = clock();
|
||||
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. */
|
||||
unsigned octets_to_encrypt = octets_in_buffer;
|
||||
|
||||
/* encrypt buffer with cipher */
|
||||
cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt);
|
||||
cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
|
||||
srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t*)&nonce, srtp_direction_encrypt);
|
||||
srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
|
||||
|
||||
/* choose a cipher at random from the array*/
|
||||
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
|
||||
cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
|
||||
cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher) {
|
||||
int i;
|
||||
int min_enc_len = 16;
|
||||
int max_enc_len = 2048; /* should be a power of two */
|
||||
|
@ -589,11 +578,11 @@ cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
|
|||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_array_throughput(cipher_type_t *ct,
|
||||
srtp_err_status_t
|
||||
cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
|
||||
int klen, int num_cipher) {
|
||||
cipher_t **ca = NULL;
|
||||
err_status_t status;
|
||||
srtp_cipher_t **ca = NULL;
|
||||
srtp_err_status_t status;
|
||||
|
||||
status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
|
||||
if (status) {
|
||||
|
@ -606,5 +595,5 @@ cipher_driver_test_array_throughput(cipher_type_t *ct,
|
|||
|
||||
cipher_array_delete(ca, num_cipher);
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -44,9 +44,14 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <string.h> /* for strlen() */
|
||||
#include "datatypes.h"
|
||||
#include "util.h"
|
||||
|
||||
void
|
||||
byte_order(void);
|
||||
|
@ -205,7 +210,7 @@ test_hex_string_funcs(void) {
|
|||
|
||||
void
|
||||
print_string(char *s) {
|
||||
int i;
|
||||
size_t i;
|
||||
printf("%s\n", s);
|
||||
printf("strlen(s) = %u\n", (unsigned)strlen(s));
|
||||
printf("{ ");
|
||||
|
@ -222,7 +227,7 @@ test_bswap(void) {
|
|||
uint32_t x = 0x11223344;
|
||||
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,
|
||||
(unsigned long long)be64_to_cpu(y));
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -49,7 +49,6 @@
|
|||
int
|
||||
main(void) {
|
||||
int err_count = 0;
|
||||
char *str;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
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");
|
||||
#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)
|
||||
printf("warning: configuration is probably in error "
|
||||
"(found %d problems)\n", err_count);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,8 +43,12 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "getopt_s.h"
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
void
|
||||
|
@ -55,25 +59,24 @@ usage(char *prog_name) {
|
|||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
extern char *optarg;
|
||||
int q;
|
||||
int do_validation = 0;
|
||||
err_status_t status;
|
||||
srtp_err_status_t status;
|
||||
|
||||
if (argc == 1)
|
||||
usage(argv[0]);
|
||||
|
||||
/* initialize kernel - we need to do this before anything else */
|
||||
status = crypto_kernel_init();
|
||||
status = srtp_crypto_kernel_init();
|
||||
if (status) {
|
||||
printf("error: crypto_kernel init failed\n");
|
||||
printf("error: srtp_crypto_kernel init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("crypto_kernel successfully initalized\n");
|
||||
printf("srtp_crypto_kernel successfully initalized\n");
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "vd:");
|
||||
q = getopt_s(argc, argv, "vd:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
|
@ -81,9 +84,9 @@ main (int argc, char *argv[]) {
|
|||
do_validation = 1;
|
||||
break;
|
||||
case 'd':
|
||||
status = crypto_kernel_set_debug_module(optarg, 1);
|
||||
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg);
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
@ -93,21 +96,21 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if (do_validation) {
|
||||
printf("checking crypto_kernel status...\n");
|
||||
status = crypto_kernel_status();
|
||||
printf("checking srtp_crypto_kernel status...\n");
|
||||
status = srtp_crypto_kernel_status();
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
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) {
|
||||
printf("error: crypto_kernel shutdown failed\n");
|
||||
printf("error: srtp_crypto_kernel shutdown failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("crypto_kernel successfully shut down\n");
|
||||
printf("srtp_crypto_kernel successfully shut down\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -117,10 +120,10 @@ main (int argc, char *argv[]) {
|
|||
* of the crypto_kernel
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
crypto_kernel_cipher_test(void) {
|
||||
|
||||
/* not implemented yet! */
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,8 +43,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sha1.h"
|
||||
#include "util.h"
|
||||
|
||||
#define SHA_PASS 0
|
||||
#define SHA_FAIL 1
|
||||
|
@ -62,7 +68,7 @@ typedef struct hash_test_case_t {
|
|||
|
||||
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,
|
||||
char *hex_data,
|
||||
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));
|
||||
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);
|
||||
if (tmp_len != data_len*2)
|
||||
return err_status_parse_err;
|
||||
if (tmp_len != data_len*2) {
|
||||
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);
|
||||
if (tmp_len != hash_len*2)
|
||||
return err_status_parse_err;
|
||||
if (tmp_len != hash_len*2) {
|
||||
free(test_case);
|
||||
return srtp_err_status_parse_err;
|
||||
}
|
||||
|
||||
test_case->data_len = data_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;
|
||||
*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_ctx_t ctx;
|
||||
srtp_sha1_ctx_t ctx;
|
||||
uint32_t hash_value[5];
|
||||
|
||||
if (test_case == NULL)
|
||||
return err_status_bad_param;
|
||||
return srtp_err_status_bad_param;
|
||||
|
||||
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)
|
||||
return err_status_bad_param;
|
||||
return srtp_err_status_bad_param;
|
||||
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, test_case->data, test_case->data_len);
|
||||
sha1_final(&ctx, hash_value);
|
||||
srtp_sha1_init(&ctx);
|
||||
srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
|
||||
srtp_sha1_final(&ctx, hash_value);
|
||||
if (0 == memcmp(test_case->hash, hash_value, 20)) {
|
||||
#if VERBOSE
|
||||
printf("PASSED: reference value: %s\n",
|
||||
|
@ -117,7 +127,7 @@ sha1_test_case_validate(const hash_test_case_t *test_case) {
|
|||
printf("PASSED: computed value: %s\n",
|
||||
octet_string_hex_string((const uint8_t *)hash_value, 20));
|
||||
#endif
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
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",
|
||||
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];
|
||||
};
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
sha1_add_test_cases(void) {
|
||||
int i;
|
||||
err_status_t err;
|
||||
srtp_err_status_t err;
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
hash_test_case_t *t, *next;
|
||||
|
||||
|
@ -496,15 +506,15 @@ sha1_dealloc_test_cases(void) {
|
|||
|
||||
sha1_test_case_list = NULL;
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
sha1_validate(void) {
|
||||
hash_test_case_t *test_case;
|
||||
err_status_t err;
|
||||
srtp_err_status_t err;
|
||||
|
||||
err = sha1_add_test_cases();
|
||||
if (err) {
|
||||
|
@ -513,7 +523,7 @@ sha1_validate(void) {
|
|||
}
|
||||
|
||||
if (sha1_test_case_list == NULL)
|
||||
return err_status_cant_check;
|
||||
return srtp_err_status_cant_check;
|
||||
|
||||
test_case = sha1_test_case_list;
|
||||
while (test_case != NULL) {
|
||||
|
@ -527,14 +537,14 @@ sha1_validate(void) {
|
|||
|
||||
sha1_dealloc_test_cases();
|
||||
|
||||
return err_status_ok;
|
||||
return srtp_err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (void) {
|
||||
err_status_t err;
|
||||
srtp_err_status_t err;
|
||||
|
||||
printf("sha1 test driver\n");
|
||||
|
||||
|
|
|
@ -7,6 +7,45 @@
|
|||
* 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() */
|
||||
|
||||
|
@ -20,11 +59,11 @@ typedef struct {
|
|||
void *state;
|
||||
} random_source_t;
|
||||
|
||||
err_status_t
|
||||
srtp_err_status_t
|
||||
random_source_alloc(void);
|
||||
|
||||
void
|
||||
err_check(err_status_t s) {
|
||||
err_check(srtp_err_status_t s) {
|
||||
if (s) {
|
||||
printf("error (code %d)\n", s);
|
||||
exit(1);
|
||||
|
@ -36,12 +75,13 @@ main (int argc, char *argv[]) {
|
|||
uint8_t buffer[2532];
|
||||
unsigned int buf_len = 2500;
|
||||
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
|
||||
extern cipher_type_t aes_gcm_128_openssl;
|
||||
extern cipher_type_t aes_gcm_256_openssl;
|
||||
extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
|
||||
extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
|
||||
#endif
|
||||
cipher_t *c;
|
||||
srtp_cipher_t *c;
|
||||
uint8_t key[46] = {
|
||||
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 */
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
err_check(cipher_type_alloc(&aes_icm, &c, 30, 0));
|
||||
err_check(cipher_init(c, key));
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_type_alloc(&srtp_aes_icm_128, &c, SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
|
||||
err_check(srtp_cipher_init(c, key));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
/* run tests on cipher outout */
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
|
@ -94,8 +134,8 @@ main (int argc, char *argv[]) {
|
|||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
nonce.v32[3] = i;
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
if (stat_test_runs(buffer)) {
|
||||
num_fail++;
|
||||
}
|
||||
|
@ -105,16 +145,16 @@ main (int argc, char *argv[]) {
|
|||
printf("(nota bene: a small fraction of stat_test failures does not \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");
|
||||
/* set buffer to cipher output */
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
err_check(cipher_type_alloc(&aes_icm, &c, 46, 0));
|
||||
err_check(cipher_init(c, key));
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c, SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
|
||||
err_check(srtp_cipher_init(c, key));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
/* run tests on cipher outout */
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
|
@ -128,8 +168,8 @@ main (int argc, char *argv[]) {
|
|||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
nonce.v32[3] = i;
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
if (stat_test_runs(buffer)) {
|
||||
num_fail++;
|
||||
}
|
||||
|
@ -142,10 +182,10 @@ main (int argc, char *argv[]) {
|
|||
for (i=0; i < 2500; i++) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
err_check(cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSALT, 8));
|
||||
err_check(cipher_init(c, key));
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c, SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
|
||||
err_check(srtp_cipher_init(c, key));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
/* run tests on cipher outout */
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
|
@ -158,8 +198,8 @@ main (int argc, char *argv[]) {
|
|||
buffer[i] = 0;
|
||||
}
|
||||
nonce.v32[3] = i;
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
buf_len = 2500;
|
||||
if (stat_test_runs(buffer)) {
|
||||
num_fail++;
|
||||
|
@ -171,10 +211,10 @@ main (int argc, char *argv[]) {
|
|||
for (i=0; i < 2500; i++) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
err_check(cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSALT, 16));
|
||||
err_check(cipher_init(c, key));
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c, SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
|
||||
err_check(srtp_cipher_init(c, key));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
/* run tests on cipher outout */
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
|
@ -187,8 +227,8 @@ main (int argc, char *argv[]) {
|
|||
buffer[i] = 0;
|
||||
}
|
||||
nonce.v32[3] = i;
|
||||
err_check(cipher_set_iv(c, &nonce, direction_encrypt));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
err_check(srtp_cipher_set_iv(c, (uint8_t*)&nonce, srtp_direction_encrypt));
|
||||
err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
|
||||
buf_len = 2500;
|
||||
if (stat_test_runs(buffer)) {
|
||||
num_fail++;
|
||||
|
@ -201,7 +241,7 @@ main (int argc, char *argv[]) {
|
|||
printf("(nota bene: a small fraction of stat_test failures does not \n"
|
||||
"indicate that the random source is invalid)\n");
|
||||
|
||||
err_check(cipher_dealloc(c));
|
||||
err_check(srtp_cipher_dealloc(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -4,10 +4,8 @@
|
|||
# Cisco Systems, Inc.
|
||||
#
|
||||
# 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
|
||||
# these, then there is no way that you can make your own
|
||||
# documentation. Of course, you can just go online at pick up the
|
||||
# documentation from http://srtp.sourceforge.net.
|
||||
# it. We just run doxygen.
|
||||
# The most up to date documentation can be found at www.github.com/cisco/libsrtp
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
@ -18,27 +16,17 @@ VPATH = @srcdir@
|
|||
|
||||
version = $(shell cat $(top_srcdir)/VERSION)
|
||||
|
||||
|
||||
.PHONY: libsrtpdoc cryptodoc clean
|
||||
libsrtpdoc:
|
||||
@if test ! -e Doxyfile; then \
|
||||
.PHONY: libsrtpdoc clean
|
||||
libsrtpdoc:
|
||||
@if test ! -e Doxyfile.in; then \
|
||||
echo "*** Sorry, can't build doc outside source dir"; exit 1; \
|
||||
fi
|
||||
sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex
|
||||
sed 's/LIBSRTPVERSIONNUMBER/$(version)/' Doxyfile.in > Doxyfile
|
||||
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:
|
||||
rm -rf latex/ header.tex
|
||||
for a in * ; do \
|
||||
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
|
||||
done;
|
||||
|
||||
rm -rf html/ Doxyfile
|
||||
for a in * ; do \
|
||||
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
|
||||
done;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -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}
|
||||
|
||||
|
|
@ -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.
|
||||
|
||||
|
||||
*/
|
|
@ -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
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -59,96 +59,82 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef EKT_H
|
||||
#define EKT_H
|
||||
#ifndef SRTP_EKT_H
|
||||
#define SRTP_EKT_H
|
||||
|
||||
// left in commented out as reminder to not include private headers
|
||||
//#include "srtp_priv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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
|
||||
#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;
|
||||
typedef uint16_t srtp_ekt_spi_t;
|
||||
|
||||
|
||||
unsigned
|
||||
ekt_octets_after_base_tag(ekt_stream_t ekt);
|
||||
unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* is passed into libsrtp to indicate what policy should be in effect
|
||||
*/
|
||||
|
||||
typedef struct ekt_policy_ctx_t {
|
||||
ekt_spi_t spi; /* security parameter index */
|
||||
typedef struct srtp_ekt_policy_ctx_t {
|
||||
srtp_ekt_spi_t spi; /* security parameter index */
|
||||
uint8_t ekt_cipher_type;
|
||||
uint8_t *ekt_key;
|
||||
struct ekt_policy_ctx_t *next_ekt_policy;
|
||||
} ekt_policy_ctx_t;
|
||||
struct srtp_ekt_policy_ctx_t *next_ekt_policy;
|
||||
} 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
|
||||
*/
|
||||
|
||||
typedef struct ekt_data_t {
|
||||
ekt_spi_t spi;
|
||||
typedef struct srtp_ekt_data_t {
|
||||
srtp_ekt_spi_t spi;
|
||||
uint8_t ekt_cipher_type;
|
||||
aes_expanded_key_t ekt_enc_key;
|
||||
aes_expanded_key_t ekt_dec_key;
|
||||
srtp_aes_expanded_key_t ekt_enc_key;
|
||||
srtp_aes_expanded_key_t ekt_dec_key;
|
||||
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
|
||||
*/
|
||||
|
||||
typedef struct ekt_stream_ctx_t {
|
||||
ekt_data_t *data;
|
||||
uint16_t isn; /* initial sequence number */
|
||||
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
|
||||
} ekt_stream_ctx_t;
|
||||
typedef struct srtp_ekt_stream_ctx_t {
|
||||
srtp_ekt_data_t *data;
|
||||
uint16_t isn; /* initial sequence number */
|
||||
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
|
||||
} srtp_ekt_stream_ctx_t;
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy);
|
||||
srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data, srtp_ekt_policy_t policy);
|
||||
|
||||
err_status_t
|
||||
ekt_stream_init(ekt_stream_t e,
|
||||
ekt_spi_t spi,
|
||||
void *ekt_key,
|
||||
unsigned ekt_cipher_type);
|
||||
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);
|
||||
|
||||
err_status_t
|
||||
ekt_stream_init_from_policy(ekt_stream_t e, ekt_policy_t p);
|
||||
srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t e, srtp_ekt_policy_t p);
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_stream_init_from_ekt(srtp_stream_t stream,
|
||||
const void *srtcp_hdr,
|
||||
unsigned pkt_octet_len);
|
||||
srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream, const void *srtcp_hdr, unsigned pkt_octet_len);
|
||||
|
||||
|
||||
void
|
||||
ekt_write_data(ekt_stream_t ekt,
|
||||
uint8_t *base_tag,
|
||||
unsigned base_tag_len,
|
||||
int *packet_len,
|
||||
xtd_seq_num_t pkt_index);
|
||||
void srtp_ekt_write_data(srtp_ekt_stream_t ekt, uint8_t *base_tag, unsigned base_tag_len, int *packet_len, srtp_xtd_seq_num_t pkt_index);
|
||||
|
||||
/*
|
||||
* We handle EKT by performing some additional steps before
|
||||
|
@ -158,16 +144,9 @@ ekt_write_data(ekt_stream_t ekt,
|
|||
* With EKT, the tag_len parameter is actually the base tag
|
||||
* length
|
||||
*/
|
||||
srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag, uint8_t *pkt_tag_copy, unsigned tag_len);
|
||||
|
||||
err_status_t
|
||||
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);
|
||||
srtp_err_status_t srtp_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.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_stream_srtcp_auth_tag_generation_preprocess(const srtp_stream_t *s,
|
||||
uint8_t *pkt_tag,
|
||||
unsigned pkt_octet_len);
|
||||
srtp_err_status_t srtp_stream_srtcp_auth_tag_generation_preprocess(const srtp_stream_t *s, uint8_t *pkt_tag, unsigned pkt_octet_len);
|
||||
|
||||
/* it's not clear that a tag_generation_postprocess function is needed */
|
||||
|
||||
err_status_t
|
||||
srtcp_auth_tag_generation_postprocess(void);
|
||||
srtp_err_status_t srtcp_auth_tag_generation_postprocess(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EKT_H */
|
||||
#endif /* SRTP_EKT_H */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,6 +45,10 @@
|
|||
#ifndef GETOPT_S_H
|
||||
#define GETOPT_S_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* getopt_s(), optarg_s, and optind_s are small, locally defined
|
||||
* 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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GETOPT_S_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,117 +45,28 @@
|
|||
#ifndef 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 "rdbx.h"
|
||||
#include "rdb.h"
|
||||
#include "integers.h"
|
||||
#include "cipher.h"
|
||||
#include "auth.h"
|
||||
#include "aes.h"
|
||||
#include "key.h"
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
/*
|
||||
* an srtp_hdr_t represents the srtp header
|
||||
*
|
||||
* 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;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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 */
|
||||
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
|
||||
#define SRTP_VER_STRING PACKAGE_STRING
|
||||
#define SRTP_VERSION PACKAGE_VERSION
|
||||
|
||||
typedef struct srtp_stream_ctx_t_ srtp_stream_ctx_t;
|
||||
typedef srtp_stream_ctx_t *srtp_stream_t;
|
||||
|
||||
/*
|
||||
* the following declarations are libSRTP internal functions
|
||||
|
@ -165,27 +76,31 @@ typedef struct {
|
|||
* srtp_get_stream(ssrc) returns a pointer to the stream corresponding
|
||||
* 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
|
||||
* 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_keys(srtp_stream_t srtp, const void *key);
|
||||
/*
|
||||
* srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s by
|
||||
* deriving all of the needed keys for all the master keys using the KDF and the keys from k.
|
||||
*/
|
||||
srtp_err_status_t srtp_steam_init_all_master_keys(srtp_stream_ctx_t *srtp,
|
||||
unsigned char *key,
|
||||
srtp_master_key_t **keys,
|
||||
const unsigned int max_master_keys);
|
||||
|
||||
/*
|
||||
* srtp_stream_init(s, p) initializes the srtp_stream_t s to
|
||||
* use the policy at the location p
|
||||
*/
|
||||
err_status_t
|
||||
srtp_stream_init(srtp_stream_t srtp,
|
||||
const srtp_policy_t *p);
|
||||
srtp_err_status_t srtp_stream_init(srtp_stream_t srtp, const srtp_policy_t *p);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -198,44 +113,162 @@ typedef enum direction_t {
|
|||
dir_srtp_receiver = 2
|
||||
} 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
|
||||
* key, sequence number, and replay database
|
||||
*
|
||||
* 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;
|
||||
cipher_t *rtp_cipher;
|
||||
auth_t *rtp_auth;
|
||||
rdbx_t rtp_rdbx;
|
||||
sec_serv_t rtp_services;
|
||||
cipher_t *rtcp_cipher;
|
||||
auth_t *rtcp_auth;
|
||||
rdb_t rtcp_rdb;
|
||||
sec_serv_t rtcp_services;
|
||||
key_limit_ctx_t *limit;
|
||||
srtp_session_keys_t *session_keys;
|
||||
unsigned int num_master_keys;
|
||||
srtp_rdbx_t rtp_rdbx;
|
||||
srtp_sec_serv_t rtp_services;
|
||||
srtp_rdb_t rtcp_rdb;
|
||||
srtp_sec_serv_t rtcp_services;
|
||||
direction_t direction;
|
||||
int allow_repeat_tx;
|
||||
ekt_stream_t ekt;
|
||||
uint8_t salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTP */
|
||||
uint8_t c_salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTCP */
|
||||
struct srtp_stream_ctx_t *next; /* linked list of streams */
|
||||
} srtp_stream_ctx_t;
|
||||
srtp_ekt_stream_t ekt;
|
||||
int *enc_xtn_hdr;
|
||||
int enc_xtn_hdr_count;
|
||||
uint32_t pending_roc;
|
||||
struct srtp_stream_ctx_t_ *next; /* linked list of streams */
|
||||
} strp_stream_ctx_t_;
|
||||
|
||||
|
||||
/*
|
||||
* an srtp_ctx_t holds a stream list and a service description
|
||||
*/
|
||||
|
||||
typedef struct srtp_ctx_t {
|
||||
srtp_stream_ctx_t *stream_list; /* linked list of streams */
|
||||
srtp_stream_ctx_t *stream_template; /* act as template for other streams */
|
||||
} srtp_ctx_t;
|
||||
typedef struct srtp_ctx_t_ {
|
||||
struct srtp_stream_ctx_t_ *stream_list; /* linked list of streams */
|
||||
struct srtp_stream_ctx_t_ *stream_template; /* act as template for other streams */
|
||||
void *user_data; /* user custom data */
|
||||
} 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
|
||||
|
@ -249,10 +282,13 @@ typedef struct srtp_ctx_t {
|
|||
if(srtp_event_handler) { \
|
||||
srtp_event_data_t data; \
|
||||
data.session = srtp; \
|
||||
data.stream = strm; \
|
||||
data.ssrc = ntohl(strm->ssrc); \
|
||||
data.event = evnt; \
|
||||
srtp_event_handler(&data); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SRTP_PRIV_H */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2017, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -51,6 +51,10 @@
|
|||
|
||||
#include "integers.h" /* for uint32_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UT_BUF 160 /* maximum amount of packet reorder */
|
||||
|
||||
typedef struct {
|
||||
|
@ -76,5 +80,8 @@ ut_init(ut_connection *utc);
|
|||
uint32_t
|
||||
ut_next_index(ut_connection *utc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UT_SIM_H */
|
||||
|
|
|
@ -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
|
|
@ -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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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>
|
|
@ -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">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Dll|Win32">
|
||||
|
@ -367,11 +367,8 @@
|
|||
<ClCompile Include="srtp\srtp.c" />
|
||||
<ClCompile Include="crypto\kernel\alloc.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\key.c" />
|
||||
<ClCompile Include="crypto\rng\prng.c" />
|
||||
<ClCompile Include="crypto\rng\rand_source.c" />
|
||||
<ClCompile Include="crypto\cipher\aes.c">
|
||||
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">Default</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</IntrinsicFunctions>
|
||||
|
@ -380,7 +377,6 @@
|
|||
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</IntrinsicFunctions>
|
||||
<FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</FunctionLevelLinking>
|
||||
</ClCompile>
|
||||
<ClCompile Include="crypto\cipher\aes_cbc.c" />
|
||||
<ClCompile Include="crypto\cipher\cipher.c" />
|
||||
<ClCompile Include="crypto\cipher\null_cipher.c" />
|
||||
<ClCompile Include="crypto\hash\auth.c" />
|
||||
|
@ -393,7 +389,6 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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_icm.h" />
|
||||
<ClInclude Include="crypto\include\aes_icm_ossl.h" />
|
||||
|
@ -401,22 +396,15 @@
|
|||
<ClInclude Include="crypto\include\auth.h" />
|
||||
<ClInclude Include="crypto\include\cipher.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_math.h" />
|
||||
<ClInclude Include="crypto\include\crypto_types.h" />
|
||||
<ClInclude Include="crypto\include\cryptoalg.h" />
|
||||
<ClInclude Include="crypto\include\datatypes.h" />
|
||||
<ClInclude Include="crypto\include\err.h" />
|
||||
<ClInclude Include="crypto\include\gf2_8.h" />
|
||||
<ClInclude Include="crypto\include\hmac.h" />
|
||||
<ClInclude Include="crypto\include\integers.h" />
|
||||
<ClInclude Include="crypto\include\kernel_compat.h" />
|
||||
<ClInclude Include="crypto\include\key.h" />
|
||||
<ClInclude Include="crypto\include\null_auth.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\rdbx.h" />
|
||||
<ClInclude Include="include\rtp.h" />
|
||||
|
@ -424,7 +412,6 @@
|
|||
<ClInclude Include="include\srtp.h" />
|
||||
<ClInclude Include="crypto\include\stat.h" />
|
||||
<ClInclude Include="include\ut_sim.h" />
|
||||
<ClInclude Include="crypto\include\xfm.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="srtp.def" />
|
||||
|
@ -437,4 +424,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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 "$(InputDir)config.hw" "$(InputDir)crypto\include\config.h" > 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>
|
|
@ -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}
|
|
@ -1,91 +1,65 @@
|
|||
EXPORTS
|
||||
srtp_init
|
||||
srtp_shutdown
|
||||
srtp_protect
|
||||
srtp_unprotect
|
||||
srtp_create
|
||||
srtp_add_stream
|
||||
srtp_remove_stream
|
||||
crypto_policy_set_rtp_default
|
||||
crypto_policy_set_rtcp_default
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_32
|
||||
crypto_policy_set_aes_cm_128_null_auth
|
||||
crypto_policy_set_null_cipher_hmac_sha1_80
|
||||
srtp_update
|
||||
srtp_update_stream
|
||||
srtp_crypto_policy_set_rtp_default
|
||||
srtp_crypto_policy_set_rtcp_default
|
||||
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_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_unprotect_rtcp
|
||||
srtp_set_user_data
|
||||
srtp_get_user_data
|
||||
srtp_install_event_handler
|
||||
crypto_kernel_init
|
||||
crypto_kernel_shutdown
|
||||
crypto_kernel_status
|
||||
crypto_kernel_list_debug_modules
|
||||
crypto_kernel_load_cipher_type
|
||||
crypto_kernel_load_auth_type
|
||||
crypto_kernel_load_debug_module
|
||||
crypto_kernel_alloc_cipher
|
||||
crypto_kernel_alloc_auth
|
||||
crypto_kernel_set_debug_module
|
||||
crypto_get_random
|
||||
rand_source_init
|
||||
rand_source_get_octet_string
|
||||
rand_source_deinit
|
||||
x917_prng_init
|
||||
x917_prng_get_octet_string
|
||||
ctr_prng_init
|
||||
ctr_prng_get_octet_string
|
||||
cipher_output
|
||||
cipher_get_key_length
|
||||
cipher_type_self_test
|
||||
cipher_bits_per_second
|
||||
auth_get_key_length
|
||||
auth_get_tag_length
|
||||
auth_get_prefix_length
|
||||
auth_type_self_test
|
||||
auth_type_get_ref_count
|
||||
stat_test_monobit
|
||||
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
|
||||
srtp_get_version_string
|
||||
srtp_get_version
|
||||
srtp_set_debug_module
|
||||
srtp_list_debug_modules
|
||||
srtp_ekt_octets_after_base_tag
|
||||
srtp_ekt_alloc
|
||||
srtp_ekt_stream_init_from_policy
|
||||
srtp_ekt_write_data
|
||||
srtp_cipher_get_key_length
|
||||
srtp_cipher_type_self_test
|
||||
srtp_cipher_type_test
|
||||
srtp_cipher_bits_per_second
|
||||
srtp_cipher_type_alloc
|
||||
srtp_cipher_dealloc
|
||||
srtp_cipher_init
|
||||
srtp_cipher_set_iv
|
||||
srtp_cipher_output
|
||||
srtp_cipher_encrypt
|
||||
srtp_cipher_decrypt
|
||||
srtp_cipher_get_tag
|
||||
srtp_cipher_set_aad
|
||||
srtp_replace_cipher_type
|
||||
srtp_auth_get_key_length
|
||||
srtp_auth_get_tag_length
|
||||
srtp_auth_get_prefix_length
|
||||
srtp_auth_type_self_test
|
||||
srtp_auth_type_test
|
||||
srtp_replace_auth_type
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue