Commit 235513aa authored by Cullen Jennings's avatar Cullen Jennings

Initial revision

parents
Changelog
1.3.20
Lots of changes. Thanks to Jeff Chan for catching a memory leak and
helping track down the endian issues with the SSRCs.
1.3.8
This is an interim release. Several little-endian bugs were identified
and fixed; this means that we can use intel/linux for development again.
Cleaned up sha1 and hmac code significantly, got rid of some excess
functions and properly documented the fuctions in the .h files.
Eliminated some vestigial files.
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.
Planned changes
Change interface to nonces (xtd_seq_num_t) so that it uses
network byte ordering, and is consistent with other arguments.
1.3.6
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).
Added machine/types.h case in include/integers.h.
1.3.5
Removing srtp_t::template and stream_clone().
Adding a new policy structure, which will reflect a complete SRTP
policy (including SRTCP).
This version is *incomplete* and will undergo more changes. It is
provided only as a basis for discussion.
1.3.4
Removed tmmh.c and tmmh.h, which implemented version one of TMMH.
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.
Removed 'salt' from cipher input.
Changed rdbx to use err.h error codes.
Changed malloc() and free() to xalloc() and xfree; these functions
are defined in crypto/kernel/alloc.c and declared in
include/alloc.h.
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.
Changed octet_string_hex_string() so that "times two" isn't needed
in its input.
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.
Improved srtp_init_aes_128_prf - wrote key derivation function
(srtp_kdf_t).
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.
Re-named files from a-b.c to a_b.c. in order to help portability.
Re-named rijndael to aes (or aes_128 as appropriate).
1.2.1
Changes so that 1.2.0 compiles on cygwin-win2k.
Added better error reporting system. If syslog is present on the
OS, then it is used.
1.2.0 Many improvements and additions, and a fex fixes
Fixed endian issues in RTP header construction in the function
rtp_sendto() in srtp/rtp.c.
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.
Implemented random number source using /dev/random, in the files
crypto/rng/rand_source.c and include/rand_source.h.
Added index check to SEAL cipher (only values less than 2^32 are
allowed)
Added test case for null_auth authentication function.
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.
A minor auth_t API change: last argument of auth_init() eliminated.
1.0.6 A small but important fix
Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero()
after buffer allocation.
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.
Corrected spelling of Richard Priestley's name in credits. Sorry
Richard!
1.0.5 Many little fixes
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.
Changed sizeof(uint32_t) to srtp_get_trailer_length() in
srtp-driver.c. This is just defensive coding.
Added NULL check to malloc in srtp_alloc().
1.0.4 Many minor fixes and two big ones (thanks for the bug reports!)
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.
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.
Updated tmmhv2_compute() so that it didn't assume any particular
alginment of the output tag.
Changed bit field variables in srtp.h to unsigned char from
unsigned int in order to avoid a potential endianness issue.
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.
Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed
from rijndael_icm_set_segment().
Added error checking and handling to srtp_sender_init() and
srtp_receiver_init().
Changed srtp_alloc() so that it does what you'd expect: allocate an
srtp_ctx_t structure. This hides the library internals.
1.0.1 Many minor fixes
Added cipher_driver_buffer_test(...) to test/cipher-driver.c. This
function checks that the byte-buffering functions used by a cipher
are correct.
Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and
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
/*
*
* Copyright (c) 2001-2003 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.
*
*/
# Makefile for secure rtp
#
# David A. McGrew
# Cisco Systems, Inc.
# targets:
#
# runtest runs test applications
# test builds test applications
# libcrypt.a static library implementing crypto engine
# libsrtp.a static library implementing srtp
# clean removes objects, libs, and executables
# distribution cleans and builds a .tgz
# tags builds etags file from all .c and .h files
.PHONY: test all runtest
runtest: test
@echo "running libsrtp test applications..."
test/cipher_driver$(EXE) -v >/dev/null
test/rdbx_driver$(EXE) -v >/dev/null
test/srtp_driver$(EXE) -v >/dev/null
test/roc_driver$(EXE) -v >/dev/null
test/kernel_driver$(EXE) -v >/dev/null
@echo "libsrtp test applications passed."
all: test tables
# makefile variables
CC = @CC@
CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops
CDEFS = -DHAVE_CONFIG_H
INCDIR = -I./include/ -I./crypto/include
LIBS = @LIBS@ -lsrtp
LIBDIR = -L.
# implicit rules for object files and test apps
%.o: %.c
$(CC) $(CDEFS) -c $(CFLAGS) $(INCDIR) $< -o $@
%: %.c libsrtp.a
$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ $(LIBDIR) $(LIBS)
# libcrypt.a (the crypto engine)
ciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o \
crypto/cipher/aes.o crypto/cipher/aes_icm.o \
crypto/cipher/aes_cbc.o
hashes = crypto/hash/null_auth.o crypto/hash/sha1.o \
crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o
replay = crypto/replay/rdb.o crypto/replay/rdbx.o \
crypto/replay/ut_sim.o
math = crypto/math/datatypes.o crypto/math/stat.o
ust = crypto/ust/ust.o
rng = crypto/rng/rand_source.o crypto/rng/prng.o crypto/rng/ctr_prng.o
err = crypto/kernel/err.o
kernel = crypto/kernel/crypto_kernel.o crypto/kernel/alloc.o \
crypto/kernel/key.o $(rng) $(err) # $(ust)
cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay)
aesicmobj = $(aesicm) $(rng)
# gdoi is the group domain of interpretation for isakmp, a group key
# management system which can provide keys for srtp
gdoi = @GDOI_OBJS@
# libsrtp.a (implements srtp processing)
srtpobj = srtp/srtp.o
libsrtp.a: $(srtpobj) $(cryptobj) $(gdoi)
ar cr libsrtp.a $(srtpobj) $(cryptobj) $(gdoi)
ranlib libsrtp.a
# libaesicm.a provides an icm implementation used by mpeg4ip
libaesicm.a: $(aesicmobj)
ar cr libaesicm.a $(aesicmobj)
ranlib libaesicm.a
# libcryptomath.a contains general-purpose routines that are used to
# generate tables and verify cryptoalgorithm implementations - this
# library is not meant to be included in production code
cryptomath = crypto/math/math.o crypto/math/gf2_8.o crypto/math/gf2_128.o
libcryptomath.a: $(cryptomath)
ar cr libcryptomath.a $(cryptomath)
ranlib libcryptomath.a
# test applications
testapp = test/cipher_driver test/datatypes_driver test/srtp_driver \
test/replay_driver test/roc_driver test/rdbx_driver \
test/stat_driver test/sha1_driver test/kernel_driver \
test/aes_calc test/rand_gen # test/ust_driver @GDOI_APPS@
# test/auth_driver test/rtpw \
test/rtpw: test/rtpw.c test/rtp.c
$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) -o test/rtpw test/rtpw.c test/rtp.c $(LIBDIR) $(LIBS)
test: $(testapp)
memtest: test/srtp_driver
@test/srtp_driver -v -d "alloc" > tmp
@grep freed tmp | wc -l > freed
@grep allocated tmp | wc -l > allocated
@echo "checking for memory leaks (only works with --enable-stdout)"
cmp -s allocated freed
@echo "passed (same number of alloc() and dealloc() calls found)"
@rm freed allocated tmp
# tables_apps are used to generate the tables used in the crypto
# implementations; these need only be generated during porting, not
# for building libsrtp or the test applications
table_apps = tables/aes_tables tables/gf_128_tables
# in the tables/ subdirectory, we use libcryptomath instead of libsrtp
tables/%: tables/%.c libcryptomath.a
$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ $(LIBDIR) libcryptomath.a
# the target 'plot' runs the timing test (test/srtp_driver -t) then
# uses gnuplot to produce plots of the results - see the script file
# 'timing'
plot: test/srtp_driver
test/srtp_driver -t > timing.dat
# bookkeeping: tags, clean, and distribution
tags:
etags */*.[ch] */*/*.[ch]
# documentation - the target libsrtpdoc builds a PDF file documenting
# libsrtp
libsrtpdoc:
cd doc; make
# EXE defines the suffix on executables - it's .exe for cygwin, and
# null on linux, bsd, and OS X and other OSes. we define this so that
# `make clean` will work on the cygwin platform
EXE = @EXE@
.PHONY: clean superclean install
install:
if [ -d /usr/local/include/srtp ]; then \
echo "you should run 'make uninstall' first"; exit 1; \
fi
mkdir /usr/local/include/srtp
cp include/*.h /usr/local/include/srtp
cp crypto/include/*.h /usr/local/include/srtp
cp libsrtp.a /usr/local/lib/
if [ -f libaesicm.a ]; then cp libaesicm.a /usr/local/lib/; fi
uninstall:
rm -rf /usr/local/include/srtp
rm -rf /usr/local/lib/libsrtp.a
if [ -f libaesicm.a ]; then rm -rf /usr/local/lib/libaesicm.a; fi
clean:
rm -rf $(cryptobj) $(srtpobj) $(cryptomath) $(table_apps) TAGS \
libcryptomath.a libsrtp.a libaesicm.a core *.core test/core
for a in * */* */*/*; do \
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
done;
for a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done
rm -rf *.pict *.jpg *.dat
rm -rf freed allocated tmp
cd doc; make clean
cd crypto; make clean
superclean: clean
rm -rf include/config.h config.log config.cache config.status \
Makefile .gdb_history test/.gdb_history .DS_Store
rm -rf autom4te.cache
distname = srtp-$(shell cat VERSION)
distribution: superclean
if ! [ -f VERSION ]; then exit 1; fi
if [ -f ../$(distname).tgz ]; then \
mv ../$(distname).tgz ../$(distname).tgz.bak; \
fi
cd ..; tar cvzf $(distname).tgz srtp
# EOF
Secure RTP (SRTP) and UST Reference Implementations
David A. McGrew
Cisco Systems, Inc.
mcgrew@cisco.com
This package provides an implementation of the Secure Real-time
Transport Protocol (SRTP), the Universal Security Transform (UST), and
a supporting cryptographic kernel. These mechanisms are documented in
the Internet Drafts in the doc/ subdirectory. The SRTP API is
documented in include/srtp.h, and the library is in libsrtp.a (after
compilation).
Installation:
./configure [ options ] # GNU autoconf script
make # or gmake if needed; use GNU make
The configure script accepts the following options:
--help provides a usage summary
--disable-debug compile without the runtime debugging system
--enable-syslog use syslog for error reporting
--disable-stdout use stdout for error reporting
--enable-console use /dev/console for error reporting
--gdoi use GDOI key management (disabled at present)
By default, debbuging is enabled and stdout is used for debugging.
You can use the above configure options to have the debugging output
sent to syslog or the system console. Alternatively, you can define
ERR_REPORTING_FILE in 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 Mac OS X (powerpc-apple-darwin1.4),
Cygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6). Previous
versions have been tested on Linux and OpenBSD on both x86 and sparc
platforms.
A quick tour of this package:
Makefile targets: all, clean, ...
README this file
CHANGES change log
VERSION version number of this package
LICENSE legal details (it's a BSD-like license)
crypto/ciphers/ ciphers (null, aes_icm, ...)
crypto/math/ crypto math routines
crypto/hash/ crypto hashing (hmac, tmmhv2, ...)
crypto/replay/ replay protection
doc/ documentation: rfcs, apis, and suchlike
include/ include files for all code in distribution
srtp/ secure real-time transport protocol implementation
tables/ apps for generating tables (useful in porting)
test/ test drivers
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 (n.b. not used in libsrtp)
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: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port
or rtpw -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.
options:
-s (s)rtp sender - causes app to send words
-r (s)rtp receive - causes app to receve 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 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).
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:
set 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
...
[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
...
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 is 128 bits in length, and is hard-coded to this
value for now.
TODO List
- add tests for key_limit_t datatype
- move octet_get_weight() from datatypes.c to math.c (any other
funcs?)
Changes and additions planned
Make cipher and auth dealloc() functions zeroize the key-storage
areas before calling free().
Fix UST
- implement scatter/gather API
- SRTP using UST
- possibly add legacy SHA1 usage
Eliminate key_len from auth_init()
Doucument internal APIs (cipher, auth, srtp_protect, ...)
SRTP options not (yet) included in this libaray:
- the aes-f8-mode cipher
- HMAC-SHA-1
- the Master Key Index
- re-keying using the key derivation function (only the initial
use of the PRF has been implemented, as it's sufficient
for most uses)
INCOMPLETE ADDITIONS
Added DES and 3DES ICM.
PLANNED CHANGES
strip out test/lfsr.c
Write new documentation!!!
Fix the x86 assembly code in aes.c.
Eliminate /* DAM */ - there's one in srtp.c
Change debugging so that it can print more than one line. Or perhaps
just change it so that a single check of the debug-enabled flag is
needed.
Improve interface between cipher and rdbx - perhaps generalize rdbx
into 'nonce' datatype.
Make rijndael_icm accept variable sized keys.
Add rdbx functions that allow different-sized explicit sequence
numbers to be used.
Write uniform byte-buffering code for PRFs, preferably as macros.
Consider eliminating low-level alloc functions in favor of len()
functions, so that there need not be multiple allocations within a
particular alloc() function.
Update test/stat-driver.c so that it tests the rand_source API.
Add a pseudorandom rand_source.
This diff is collapsed.
This diff is collapsed.
/*
* config_in.h
*
* template for header config file for Secure RTP and UST implementation
*
* David A. McGrew
* Cisco Systems, Inc.
*/
#ifndef CONFIG_H
#define CONFIG_H
/* if we're on a big endian machine, we need to define this */
#define WORDS_BIGENDIAN 0
/* check for <stdint.h> or <machine/types.h> */
#define HAVE_STDINT_H 0
#define HAVE_MACHINE_TYPES_H 0
#define HAVE_SYS_INT_TYPES_H 0
/* check for microsoft integer definitions (e.g., cygwin) */
#define HAVE_MS_TYPES 1
/* if we don't have uio.h, we'll need to define struct iovec */
#define HAVE_SYS_UIO_H 0