Bug 1230759: Part 2 - update libsrtp to 2.2.0-pre draft
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Tue, 07 Nov 2017 22:06:37 -0800
changeset 702421 a8ed8252fdce6f6a8ab1e3b97255ea0408f52c4d
parent 702420 363cc293242734dc02d12e8b793000c1f5b90fcf
child 702422 3422f12cfb42ab7d96e9dfa285c0dffa8b9d19d2
push id90487
push userdrno@ohlmeier.org
push dateThu, 23 Nov 2017 07:07:55 +0000
bugs1230759
milestone59.0a1
Bug 1230759: Part 2 - update libsrtp to 2.2.0-pre MozReview-Commit-ID: HUsFNUJhl1Q
netwerk/srtp/src/LICENSE
netwerk/srtp/src/README
netwerk/srtp/src/README.md
netwerk/srtp/src/VERSION
netwerk/srtp/src/configure.in
netwerk/srtp/src/crypto/ae_xfm/xfm.c
netwerk/srtp/src/crypto/cipher/aes.c
netwerk/srtp/src/crypto/cipher/aes_cbc.c
netwerk/srtp/src/crypto/cipher/aes_icm.c
netwerk/srtp/src/crypto/cipher/cipher.c
netwerk/srtp/src/crypto/cipher/null_cipher.c
netwerk/srtp/src/crypto/hash/auth.c
netwerk/srtp/src/crypto/hash/hmac.c
netwerk/srtp/src/crypto/hash/null_auth.c
netwerk/srtp/src/crypto/hash/sha1.c
netwerk/srtp/src/crypto/include/aes.h
netwerk/srtp/src/crypto/include/aes_cbc.h
netwerk/srtp/src/crypto/include/aes_icm.h
netwerk/srtp/src/crypto/include/alloc.h
netwerk/srtp/src/crypto/include/auth.h
netwerk/srtp/src/crypto/include/cipher.h
netwerk/srtp/src/crypto/include/cipher_types.h
netwerk/srtp/src/crypto/include/crypto.h
netwerk/srtp/src/crypto/include/crypto_kernel.h
netwerk/srtp/src/crypto/include/crypto_math.h
netwerk/srtp/src/crypto/include/crypto_types.h
netwerk/srtp/src/crypto/include/cryptoalg.h
netwerk/srtp/src/crypto/include/datatypes.h
netwerk/srtp/src/crypto/include/err.h
netwerk/srtp/src/crypto/include/hmac.h
netwerk/srtp/src/crypto/include/integers.h
netwerk/srtp/src/crypto/include/kernel_compat.h
netwerk/srtp/src/crypto/include/key.h
netwerk/srtp/src/crypto/include/null_auth.h
netwerk/srtp/src/crypto/include/null_cipher.h
netwerk/srtp/src/crypto/include/prng.h
netwerk/srtp/src/crypto/include/rand_source.h
netwerk/srtp/src/crypto/include/rdb.h
netwerk/srtp/src/crypto/include/rdbx.h
netwerk/srtp/src/crypto/include/sha1.h
netwerk/srtp/src/crypto/include/stat.h
netwerk/srtp/src/crypto/include/xfm.h
netwerk/srtp/src/crypto/kernel/alloc.c
netwerk/srtp/src/crypto/kernel/crypto_kernel.c
netwerk/srtp/src/crypto/kernel/err.c
netwerk/srtp/src/crypto/kernel/key.c
netwerk/srtp/src/crypto/math/datatypes.c
netwerk/srtp/src/crypto/math/math.c
netwerk/srtp/src/crypto/math/stat.c
netwerk/srtp/src/crypto/replay/rdb.c
netwerk/srtp/src/crypto/replay/rdbx.c
netwerk/srtp/src/crypto/replay/ut_sim.c
netwerk/srtp/src/crypto/rng/ctr_prng.c
netwerk/srtp/src/crypto/rng/prng.c
netwerk/srtp/src/crypto/rng/rand_linux_kernel.c
netwerk/srtp/src/crypto/rng/rand_source.c
netwerk/srtp/src/crypto/test/aes_calc.c
netwerk/srtp/src/crypto/test/auth_driver.c
netwerk/srtp/src/crypto/test/cipher_driver.c
netwerk/srtp/src/crypto/test/datatypes_driver.c
netwerk/srtp/src/crypto/test/env.c
netwerk/srtp/src/crypto/test/kernel_driver.c
netwerk/srtp/src/crypto/test/rand_gen.c
netwerk/srtp/src/crypto/test/sha1_driver.c
netwerk/srtp/src/crypto/test/stat_driver.c
netwerk/srtp/src/include/ekt.h
netwerk/srtp/src/include/getopt_s.h
netwerk/srtp/src/include/rtp.h
netwerk/srtp/src/include/rtp_priv.h
netwerk/srtp/src/include/srtp.h
netwerk/srtp/src/include/srtp_priv.h
netwerk/srtp/src/include/ut_sim.h
netwerk/srtp/src/srtp/ekt.c
netwerk/srtp/src/srtp/srtp.c
netwerk/srtp/src/test/cutest.h
netwerk/srtp/src/test/dtls_srtp_driver.c
netwerk/srtp/src/test/getopt_s.c
netwerk/srtp/src/test/rdbx_driver.c
netwerk/srtp/src/test/replay_driver.c
netwerk/srtp/src/test/roc_driver.c
netwerk/srtp/src/test/rtp.c
netwerk/srtp/src/test/rtp.h
netwerk/srtp/src/test/rtp_decoder.c
netwerk/srtp/src/test/rtp_decoder.h
netwerk/srtp/src/test/rtpw.c
netwerk/srtp/src/test/rtpw_test.sh
netwerk/srtp/src/test/rtpw_test_gcm.sh
netwerk/srtp/src/test/srtp_driver.c
netwerk/srtp/src/test/test_srtp.c
netwerk/srtp/src/test/util.c
netwerk/srtp/src/test/util.h
netwerk/srtp/src/test/words.txt
netwerk/srtp/srtp_update.log
--- a/netwerk/srtp/src/LICENSE
+++ b/netwerk/srtp/src/LICENSE
@@ -1,11 +1,11 @@
 /*
  *	
- * 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.
deleted file mode 100644
--- a/netwerk/srtp/src/README
+++ /dev/null
@@ -1,174 +0,0 @@
-Secure RTP (SRTP) Reference Implementation
-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).  An overview and reference manual is available in
-doc/libsrtp.pdf.  The PDF documentation is more up to date than this
-file.
-
-
-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.  
-
-
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/README.md
@@ -0,0 +1,487 @@
+[![Build Status](https://travis-ci.org/cisco/libsrtp.svg?branch=master)](https://travis-ci.org/cisco/libsrtp)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/14274/badge.svg)](https://scan.coverity.com/projects/cisco-libsrtp)
+
+<a name="introduction-to-libsrtp"></a>
+# Introduction to libSRTP
+
+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)
+  - [Changing Build Configuration](#changing-build-configuration)
+- [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="changing-build-configuration"></a>
+## Changing Build Configuration
+
+To build the `./configure` script mentioned above, libSRTP relies on the
+[automake](https://www.gnu.org/software/automake/) toolchain.  Since
+`./configure` is built from `configure.in` by automake, if you make changes in
+how `./configure` works (e.g., to add a new library dependency), you will need
+to rebuild `./configure` and commit the updated version.  In addition to
+automake itself, you will need to have the `pkgconfig` tools installed as well.
+
+For example, on macOS:
+
+```
+brew install automake pkgconfig
+# Edit configure.in
+autoremake -ivf
+```
+
+--------------------------------------------------------------------------------
+
+<a name="applications"></a>
+# Applications
+
+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();
+
+// default policy values
+memset(&policy, 0x0, sizeof(srtp_policy_t));
+
+// set policy to describe a policy for an SRTP stream
+crypto_policy_set_rtp_default(&policy.rtp);
+crypto_policy_set_rtcp_default(&policy.rtcp);
+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)
--- a/netwerk/srtp/src/VERSION
+++ b/netwerk/srtp/src/VERSION
@@ -1,1 +1,1 @@
-1.4.4
+2.2.0-pre
deleted file mode 100644
--- a/netwerk/srtp/src/configure.in
+++ /dev/null
@@ -1,209 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(srtp)
-
-dnl Must come before AC_PROG_CC
-if test -z "$CFLAGS"; then
-   dnl Default value for CFLAGS if not specified.
-   CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops"
-fi
-
-dnl Checks for programs.
-AC_PROG_RANLIB
-AC_PROG_CC
-AC_PROG_INSTALL
-
-dnl Check the byte order
-AC_C_BIGENDIAN
-
-AC_CANONICAL_HOST
-
-dnl check host_cpu type, set defines appropriately
-case $host_cpu in
-     i*86 | x86_64 )
-	AC_DEFINE(CPU_CISC, 1,
-	   [Define if building for a CISC machine (e.g. Intel).])
-        AC_DEFINE(HAVE_X86, 1,
-	   [Define to use X86 inlined assembly code]);; 
-	* )
-	# CPU_RISC is only supported for big endian machines.
-	if test "$ac_cv_c_bigendian" = "yes"; then
-	   AC_DEFINE(CPU_RISC, 1,
-	    [Define if building for a RISC machine (assume slow byte access).])
-	else
-	   AC_DEFINE(CPU_CISC, 1)
-	fi
-	;;
-esac	
-
-dnl Check if we are on a Windows platform.
-case $host_os in
-    *cygwin*|*mingw* ) 
-	EXE=.exe
-	HOST_IS_WINDOWS=yes
-	;;
-    * )
-	EXE=""
-	;;
-esac
-AC_SUBST(EXE)   # define executable suffix; this is needed for `make clean'
-
-
-AC_ARG_ENABLE(kernel-linux,
-  [AS_HELP_STRING([--enable-kernel-linux],
-		  [build library to run in Linux kernel context])],
-  [], enable_kernel_linux=no)
-AC_MSG_CHECKING(whether to build for Linux kernel context)
-if test "$enable_kernel_linux" = "yes"; then
-   AC_DEFINE(SRTP_KERNEL, 1,
-	[Define to compile for kernel contexts.])
-   AC_DEFINE(SRTP_KERNEL_LINUX, 1,
-	[Define to compile for Linux kernel context.])
-fi
-AC_MSG_RESULT($enable_kernel_linux)
-
-if test "$cross_compiling" != yes -a "$HOST_IS_WINDOWS" != yes; then
-   dnl Check for /dev/urandom
-   AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom,
-      [AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])
-fi
-
-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])
-   else
-      AC_MSG_RESULT([standard rand() function...])
-   fi
-fi
-AC_SUBST(RNG_OBJS)
-
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(stdlib.h)
-AC_CHECK_HEADERS(unistd.h)
-AC_CHECK_HEADERS(byteswap.h)
-AC_CHECK_HEADERS(stdint.h)
-AC_CHECK_HEADERS(sys/uio.h)
-AC_CHECK_HEADERS(inttypes.h)
-AC_CHECK_HEADERS(sys/types.h)
-AC_CHECK_HEADERS(machine/types.h)
-AC_CHECK_HEADERS(sys/int_types.h)
-
-dnl socket() and friends
-AC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h)
-AC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)])
-
-AC_CHECK_HEADERS(syslog.h)
-
-AC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t])
-AC_CHECK_SIZEOF(unsigned long)
-AC_CHECK_SIZEOF(unsigned long long)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_SIZE_T
-
-dnl Checks for library functions.
-AC_CHECK_FUNCS(socket inet_aton usleep sigaction)
-
-dnl Find socket function if not found yet.
-if test "x$ac_cv_func_socket" = "xno"; then
-  AC_CHECK_LIB(socket, socket)
-  AC_MSG_CHECKING([for socket in -lwsock32])
-  SAVELIBS="$LIBS"
-  LIBS="$LIBS -lwsock32"
-  AC_TRY_LINK([
-#include <winsock2.h>
-],[
-socket(0, 0, 0);
-],
-    ac_cv_func_socket=yes
-    AC_MSG_RESULT(yes),
-    LIBS="$SAVELIBS"
-    AC_MSG_RESULT(no))
-fi
-
-AC_MSG_CHECKING(whether to compile in debugging)
-AC_ARG_ENABLE(debug,
-  [AS_HELP_STRING([--disable-debug],
-		  [do not compile in dynamic debugging system])],
-  [], enable_debug=yes)
-if test "$enable_debug" = "yes"; then
-   AC_DEFINE(ENABLE_DEBUGGING, 1,
-      [Define to compile in dynamic debugging system.])
-fi
-AC_MSG_RESULT($enable_debug)
-
-AC_MSG_CHECKING(whether to use ISMAcryp code)
-AC_ARG_ENABLE(generic-aesicm,
-  [AS_HELP_STRING([--enable-generic-aesicm],
-		  [compile in changes for ISMAcryp])],
-  [], enable_generic_aesicm=no)
-if test "$enable_generic_aesicm" = "yes"; then
-   AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.])
-fi
-AC_MSG_RESULT($enable_generic_aesicm)
-
-AC_MSG_CHECKING(whether to use syslog for error reporting)
-AC_ARG_ENABLE(syslog,
-  [AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])],
-  [], enable_syslog=no)
-if test "$enable_syslog" = "yes"; then
-   AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.])
-fi
-AC_MSG_RESULT($enable_syslog)
-
-AC_MSG_CHECKING(whether to use stdout for error reporting)
-AC_ARG_ENABLE(stdout,
-  [AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])],
-  [], enable_stdout=yes)
-if test "$enable_stdout" = "yes"; then
-   AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.])
-fi
-AC_MSG_RESULT($enable_stdout)
-
-AC_MSG_CHECKING(whether to use /dev/console for error reporting)
-AC_ARG_ENABLE(console,
-  [AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])],
-  [], enable_console=no)
-if test "$enable_console" = "yes"; then
-   AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file])
-   AC_DEFINE(ERR_REPORTING_FILE, "/dev/console", [Report errors to this file.])
-fi
-AC_MSG_RESULT($enable_console)
-
-AC_MSG_CHECKING(whether to use GDOI key management)
-AC_ARG_ENABLE(gdoi,
-  [AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])],
-  [], enable_gdoi=no)
-if test "$enable_gdoi" = "yes"; then
-   AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.])
-   GDOI_OBJS=gdoi/srtp+gdoi.o
-   AC_SUBST(GDOI_OBJS)                              
-fi
-AC_MSG_RESULT($enable_gdoi)
-
-AC_CONFIG_HEADER(crypto/include/config.h:config_in.h)
-
-AC_OUTPUT(Makefile crypto/Makefile doc/Makefile)
-
-# 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)
-AS_MKDIR_P(tables)
-AS_MKDIR_P(test)
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/ae_xfm/xfm.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * xfm.c
- *
- * Crypto transform 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.
- *
- */
-
-#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 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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));
-#endif
-    *opaque_len -= NULL_TAG_LEN;
-#if DEBUG
-    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;
-}
--- a/netwerk/srtp/src/crypto/cipher/aes.c
+++ b/netwerk/srtp/src/crypto/cipher/aes.c
@@ -3,2077 +3,2187 @@
  *
  * An implemnetation of the AES block cipher.
  *
  * 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
  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include "aes.h"
 #include "err.h"
-#include "datatypes.h"
-
-typedef uint8_t gf2_8;
-
-#define gf2_8_field_polynomial 0x1B
 
 /*
- * 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))
-
-/* 
- * we use the tables T0, T1, T2, T3, and T4 to compute AES, and 
+ * we use the tables T0, T1, T2, T3, and T4 to compute AES, and
  * the tables U0, U1, U2, and U4 to compute its inverse
  *
  * different tables are used on little-endian (Intel, VMS) and
  * big-endian processors (everything else)
  *
  * these tables are computed using the program tables/aes_tables; use
  * this program to generate different tables for porting or
  * optimization on a different platform
  */
 
 #ifndef WORDS_BIGENDIAN
-
-static uint32_t T0[256] = {
-  0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 
-  0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 
-  0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, 
-  0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 
-  0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 
-  0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, 
-  0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 
-  0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 
-  0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 
-  0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, 
-  0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, 
-  0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 
-  0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 
-  0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f, 
-  0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 
-  0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 
-  0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 
-  0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 
-  0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 
-  0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 
-  0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, 
-  0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 
-  0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 
-  0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 
-  0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 
-  0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 
-  0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, 
-  0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 
-  0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 
-  0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, 
-  0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 
-  0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf, 
-  0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 
-  0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 
-  0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 
-  0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 
-  0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 
-  0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 
-  0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 
-  0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 
-  0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 
-  0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, 
-  0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 
-  0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 
-  0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 
-  0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 
-  0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, 
-  0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 
-  0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 
-  0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 
-  0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 
-  0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 
-  0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 
-  0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, 
-  0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 
-  0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 
-  0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 
-  0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 
-  0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 
-  0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 
-  0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 
-  0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 
-  0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 
-  0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, 
+/* clang-format off */
+static const uint32_t T0[256] = {
+    0xa56363c6, 0x847c7cf8,  0x997777ee,  0x8d7b7bf6,
+    0xdf2f2ff,  0xbd6b6bd6,  0xb16f6fde,  0x54c5c591,
+    0x50303060, 0x3010102,   0xa96767ce,  0x7d2b2b56,
+    0x19fefee7, 0x62d7d7b5,  0xe6abab4d,  0x9a7676ec,
+    0x45caca8f, 0x9d82821f,  0x40c9c989,  0x877d7dfa,
+    0x15fafaef, 0xeb5959b2,  0xc947478e,  0xbf0f0fb,
+    0xecadad41, 0x67d4d4b3,  0xfda2a25f,  0xeaafaf45,
+    0xbf9c9c23, 0xf7a4a453,  0x967272e4,  0x5bc0c09b,
+    0xc2b7b775, 0x1cfdfde1,  0xae93933d,  0x6a26264c,
+    0x5a36366c, 0x413f3f7e,  0x2f7f7f5,   0x4fcccc83,
+    0x5c343468, 0xf4a5a551,  0x34e5e5d1,  0x8f1f1f9,
+    0x937171e2, 0x73d8d8ab,  0x53313162,  0x3f15152a,
+    0xc040408,  0x52c7c795,  0x65232346,  0x5ec3c39d,
+    0x28181830, 0xa1969637,  0xf05050a,   0xb59a9a2f,
+    0x907070e,  0x36121224,  0x9b80801b,  0x3de2e2df,
+    0x26ebebcd, 0x6927274e,  0xcdb2b27f,  0x9f7575ea,
+    0x1b090912, 0x9e83831d,  0x742c2c58,  0x2e1a1a34,
+    0x2d1b1b36, 0xb26e6edc,  0xee5a5ab4,  0xfba0a05b,
+    0xf65252a4, 0x4d3b3b76,  0x61d6d6b7,  0xceb3b37d,
+    0x7b292952, 0x3ee3e3dd,  0x712f2f5e,  0x97848413,
+    0xf55353a6, 0x68d1d1b9,  0x0,         0x2cededc1,
+    0x60202040, 0x1ffcfce3,  0xc8b1b179,  0xed5b5bb6,
+    0xbe6a6ad4, 0x46cbcb8d,  0xd9bebe67,  0x4b393972,
+    0xde4a4a94, 0xd44c4c98,  0xe85858b0,  0x4acfcf85,
+    0x6bd0d0bb, 0x2aefefc5,  0xe5aaaa4f,  0x16fbfbed,
+    0xc5434386, 0xd74d4d9a,  0x55333366,  0x94858511,
+    0xcf45458a, 0x10f9f9e9,  0x6020204,   0x817f7ffe,
+    0xf05050a0, 0x443c3c78,  0xba9f9f25,  0xe3a8a84b,
+    0xf35151a2, 0xfea3a35d,  0xc0404080,  0x8a8f8f05,
+    0xad92923f, 0xbc9d9d21,  0x48383870,  0x4f5f5f1,
+    0xdfbcbc63, 0xc1b6b677,  0x75dadaaf,  0x63212142,
+    0x30101020, 0x1affffe5,  0xef3f3fd,   0x6dd2d2bf,
+    0x4ccdcd81, 0x140c0c18,  0x35131326,  0x2fececc3,
+    0xe15f5fbe, 0xa2979735,  0xcc444488,  0x3917172e,
+    0x57c4c493, 0xf2a7a755,  0x827e7efc,  0x473d3d7a,
+    0xac6464c8, 0xe75d5dba,  0x2b191932,  0x957373e6,
+    0xa06060c0, 0x98818119,  0xd14f4f9e,  0x7fdcdca3,
+    0x66222244, 0x7e2a2a54,  0xab90903b,  0x8388880b,
+    0xca46468c, 0x29eeeec7,  0xd3b8b86b,  0x3c141428,
+    0x79dedea7, 0xe25e5ebc,  0x1d0b0b16,  0x76dbdbad,
+    0x3be0e0db, 0x56323264,  0x4e3a3a74,  0x1e0a0a14,
+    0xdb494992, 0xa06060c,   0x6c242448,  0xe45c5cb8,
+    0x5dc2c29f, 0x6ed3d3bd,  0xefacac43,  0xa66262c4,
+    0xa8919139, 0xa4959531,  0x37e4e4d3,  0x8b7979f2,
+    0x32e7e7d5, 0x43c8c88b,  0x5937376e,  0xb76d6dda,
+    0x8c8d8d01, 0x64d5d5b1,  0xd24e4e9c,  0xe0a9a949,
+    0xb46c6cd8, 0xfa5656ac,  0x7f4f4f3,   0x25eaeacf,
+    0xaf6565ca, 0x8e7a7af4,  0xe9aeae47,  0x18080810,
+    0xd5baba6f, 0x887878f0,  0x6f25254a,  0x722e2e5c,
+    0x241c1c38, 0xf1a6a657,  0xc7b4b473,  0x51c6c697,
+    0x23e8e8cb, 0x7cdddda1,  0x9c7474e8,  0x211f1f3e,
+    0xdd4b4b96, 0xdcbdbd61,  0x868b8b0d,  0x858a8a0f,
+    0x907070e0, 0x423e3e7c,  0xc4b5b571,  0xaa6666cc,
+    0xd8484890, 0x5030306,   0x1f6f6f7,   0x120e0e1c,
+    0xa36161c2, 0x5f35356a,  0xf95757ae,  0xd0b9b969,
+    0x91868617, 0x58c1c199,  0x271d1d3a,  0xb99e9e27,
+    0x38e1e1d9, 0x13f8f8eb,  0xb398982b,  0x33111122,
+    0xbb6969d2, 0x70d9d9a9,  0x898e8e07,  0xa7949433,
+    0xb69b9b2d, 0x221e1e3c,  0x92878715,  0x20e9e9c9,
+    0x49cece87, 0xff5555aa,  0x78282850,  0x7adfdfa5,
+    0x8f8c8c03, 0xf8a1a159,  0x80898909,  0x170d0d1a,
+    0xdabfbf65, 0x31e6e6d7,  0xc6424284,  0xb86868d0,
+    0xc3414182, 0xb0999929,  0x772d2d5a,  0x110f0f1e,
+    0xcbb0b07b, 0xfc5454a8,  0xd6bbbb6d,  0x3a16162c,
 };
+/* clang-format on */
 
-static uint32_t T1[256] = {
-  0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 
-  0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 
-  0x30306050, 0x1010203, 0x6767cea9, 0x2b2b567d, 
-  0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 
-  0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 
-  0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 
-  0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 
-  0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 
-  0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 
-  0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 
-  0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 
-  0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 
-  0x404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 
-  0x18183028, 0x969637a1, 0x5050a0f, 0x9a9a2fb5, 
-  0x7070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 
-  0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 
-  0x909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 
-  0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 
-  0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 
-  0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 
-  0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 
-  0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 
-  0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 
-  0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 
-  0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 
-  0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 
-  0x45458acf, 0xf9f9e910, 0x2020406, 0x7f7ffe81, 
-  0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 
-  0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 
-  0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 
-  0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 
-  0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 
-  0xcdcd814c, 0xc0c1814, 0x13132635, 0xececc32f, 
-  0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 
-  0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 
-  0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 
-  0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 
-  0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 
-  0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 
-  0xdedea779, 0x5e5ebce2, 0xb0b161d, 0xdbdbad76, 
-  0xe0e0db3b, 0x32326456, 0x3a3a744e, 0xa0a141e, 
-  0x494992db, 0x6060c0a, 0x2424486c, 0x5c5cb8e4, 
-  0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 
-  0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 
-  0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 
-  0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 
-  0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 
-  0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x8081018, 
-  0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 
-  0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 
-  0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 
-  0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 
-  0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 
-  0x484890d8, 0x3030605, 0xf6f6f701, 0xe0e1c12, 
-  0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 
-  0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 
-  0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 
-  0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 
-  0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 
-  0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 
-  0x8c8c038f, 0xa1a159f8, 0x89890980, 0xd0d1a17, 
-  0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 
-  0x414182c3, 0x999929b0, 0x2d2d5a77, 0xf0f1e11, 
-  0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, 
+/* clang-format off */
+static const uint32_t T1[256] = {
+    0x6363c6a5, 0x7c7cf884,  0x7777ee99,  0x7b7bf68d,
+    0xf2f2ff0d, 0x6b6bd6bd,  0x6f6fdeb1,  0xc5c59154,
+    0x30306050, 0x1010203,   0x6767cea9,  0x2b2b567d,
+    0xfefee719, 0xd7d7b562,  0xabab4de6,  0x7676ec9a,
+    0xcaca8f45, 0x82821f9d,  0xc9c98940,  0x7d7dfa87,
+    0xfafaef15, 0x5959b2eb,  0x47478ec9,  0xf0f0fb0b,
+    0xadad41ec, 0xd4d4b367,  0xa2a25ffd,  0xafaf45ea,
+    0x9c9c23bf, 0xa4a453f7,  0x7272e496,  0xc0c09b5b,
+    0xb7b775c2, 0xfdfde11c,  0x93933dae,  0x26264c6a,
+    0x36366c5a, 0x3f3f7e41,  0xf7f7f502,  0xcccc834f,
+    0x3434685c, 0xa5a551f4,  0xe5e5d134,  0xf1f1f908,
+    0x7171e293, 0xd8d8ab73,  0x31316253,  0x15152a3f,
+    0x404080c,  0xc7c79552,  0x23234665,  0xc3c39d5e,
+    0x18183028, 0x969637a1,  0x5050a0f,   0x9a9a2fb5,
+    0x7070e09,  0x12122436,  0x80801b9b,  0xe2e2df3d,
+    0xebebcd26, 0x27274e69,  0xb2b27fcd,  0x7575ea9f,
+    0x909121b,  0x83831d9e,  0x2c2c5874,  0x1a1a342e,
+    0x1b1b362d, 0x6e6edcb2,  0x5a5ab4ee,  0xa0a05bfb,
+    0x5252a4f6, 0x3b3b764d,  0xd6d6b761,  0xb3b37dce,
+    0x2929527b, 0xe3e3dd3e,  0x2f2f5e71,  0x84841397,
+    0x5353a6f5, 0xd1d1b968,  0x00000000,  0xededc12c,
+    0x20204060, 0xfcfce31f,  0xb1b179c8,  0x5b5bb6ed,
+    0x6a6ad4be, 0xcbcb8d46,  0xbebe67d9,  0x3939724b,
+    0x4a4a94de, 0x4c4c98d4,  0x5858b0e8,  0xcfcf854a,
+    0xd0d0bb6b, 0xefefc52a,  0xaaaa4fe5,  0xfbfbed16,
+    0x434386c5, 0x4d4d9ad7,  0x33336655,  0x85851194,
+    0x45458acf, 0xf9f9e910,  0x2020406,   0x7f7ffe81,
+    0x5050a0f0, 0x3c3c7844,  0x9f9f25ba,  0xa8a84be3,
+    0x5151a2f3, 0xa3a35dfe,  0x404080c0,  0x8f8f058a,
+    0x92923fad, 0x9d9d21bc,  0x38387048,  0xf5f5f104,
+    0xbcbc63df, 0xb6b677c1,  0xdadaaf75,  0x21214263,
+    0x10102030, 0xffffe51a,  0xf3f3fd0e,  0xd2d2bf6d,
+    0xcdcd814c, 0xc0c1814,   0x13132635,  0xececc32f,
+    0x5f5fbee1, 0x979735a2,  0x444488cc,  0x17172e39,
+    0xc4c49357, 0xa7a755f2,  0x7e7efc82,  0x3d3d7a47,
+    0x6464c8ac, 0x5d5dbae7,  0x1919322b,  0x7373e695,
+    0x6060c0a0, 0x81811998,  0x4f4f9ed1,  0xdcdca37f,
+    0x22224466, 0x2a2a547e,  0x90903bab,  0x88880b83,
+    0x46468cca, 0xeeeec729,  0xb8b86bd3,  0x1414283c,
+    0xdedea779, 0x5e5ebce2,  0xb0b161d,   0xdbdbad76,
+    0xe0e0db3b, 0x32326456,  0x3a3a744e,  0xa0a141e,
+    0x494992db, 0x6060c0a,   0x2424486c,  0x5c5cb8e4,
+    0xc2c29f5d, 0xd3d3bd6e,  0xacac43ef,  0x6262c4a6,
+    0x919139a8, 0x959531a4,  0xe4e4d337,  0x7979f28b,
+    0xe7e7d532, 0xc8c88b43,  0x37376e59,  0x6d6ddab7,
+    0x8d8d018c, 0xd5d5b164,  0x4e4e9cd2,  0xa9a949e0,
+    0x6c6cd8b4, 0x5656acfa,  0xf4f4f307,  0xeaeacf25,
+    0x6565caaf, 0x7a7af48e,  0xaeae47e9,  0x8081018,
+    0xbaba6fd5, 0x7878f088,  0x25254a6f,  0x2e2e5c72,
+    0x1c1c3824, 0xa6a657f1,  0xb4b473c7,  0xc6c69751,
+    0xe8e8cb23, 0xdddda17c,  0x7474e89c,  0x1f1f3e21,
+    0x4b4b96dd, 0xbdbd61dc,  0x8b8b0d86,  0x8a8a0f85,
+    0x7070e090, 0x3e3e7c42,  0xb5b571c4,  0x6666ccaa,
+    0x484890d8, 0x3030605,   0xf6f6f701,  0xe0e1c12,
+    0x6161c2a3, 0x35356a5f,  0x5757aef9,  0xb9b969d0,
+    0x86861791, 0xc1c19958,  0x1d1d3a27,  0x9e9e27b9,
+    0xe1e1d938, 0xf8f8eb13,  0x98982bb3,  0x11112233,
+    0x6969d2bb, 0xd9d9a970,  0x8e8e0789,  0x949433a7,
+    0x9b9b2db6, 0x1e1e3c22,  0x87871592,  0xe9e9c920,
+    0xcece8749, 0x5555aaff,  0x28285078,  0xdfdfa57a,
+    0x8c8c038f, 0xa1a159f8,  0x89890980,  0xd0d1a17,
+    0xbfbf65da, 0xe6e6d731,  0x424284c6,  0x6868d0b8,
+    0x414182c3, 0x999929b0,  0x2d2d5a77,  0xf0f1e11,
+    0xb0b07bcb, 0x5454a8fc,  0xbbbb6dd6,  0x16162c3a,
 };
+/* clang-format on */
 
-static uint32_t T2[256] = {
-  0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 
-  0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 
-  0x30605030, 0x1020301, 0x67cea967, 0x2b567d2b, 
-  0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 
-  0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 
-  0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 
-  0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 
-  0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 
-  0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 
-  0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 
-  0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 
-  0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 
-  0x4080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 
-  0x18302818, 0x9637a196, 0x50a0f05, 0x9a2fb59a, 
-  0x70e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 
-  0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 
-  0x9121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 
-  0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 
-  0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 
-  0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 
-  0x53a6f553, 0xd1b968d1, 0x0, 0xedc12ced, 
-  0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 
-  0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 
-  0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 
-  0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 
-  0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 
-  0x458acf45, 0xf9e910f9, 0x2040602, 0x7ffe817f, 
-  0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 
-  0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 
-  0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 
-  0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 
-  0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 
-  0xcd814ccd, 0xc18140c, 0x13263513, 0xecc32fec, 
-  0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 
-  0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 
-  0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 
-  0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 
-  0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 
-  0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 
-  0xdea779de, 0x5ebce25e, 0xb161d0b, 0xdbad76db, 
-  0xe0db3be0, 0x32645632, 0x3a744e3a, 0xa141e0a, 
-  0x4992db49, 0x60c0a06, 0x24486c24, 0x5cb8e45c, 
-  0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 
-  0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 
-  0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 
-  0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 
-  0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 
-  0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x8101808, 
-  0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 
-  0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 
-  0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 
-  0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 
-  0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 
-  0x4890d848, 0x3060503, 0xf6f701f6, 0xe1c120e, 
-  0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 
-  0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 
-  0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 
-  0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 
-  0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 
-  0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 
-  0x8c038f8c, 0xa159f8a1, 0x89098089, 0xd1a170d, 
-  0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 
-  0x4182c341, 0x9929b099, 0x2d5a772d, 0xf1e110f, 
-  0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, 
+/* clang-format off */
+static const uint32_t T2[256] = {
+    0x63c6a563, 0x7cf8847c,  0x77ee9977,  0x7bf68d7b,
+    0xf2ff0df2, 0x6bd6bd6b,  0x6fdeb16f,  0xc59154c5,
+    0x30605030, 0x1020301,   0x67cea967,  0x2b567d2b,
+    0xfee719fe, 0xd7b562d7,  0xab4de6ab,  0x76ec9a76,
+    0xca8f45ca, 0x821f9d82,  0xc98940c9,  0x7dfa877d,
+    0xfaef15fa, 0x59b2eb59,  0x478ec947,  0xf0fb0bf0,
+    0xad41ecad, 0xd4b367d4,  0xa25ffda2,  0xaf45eaaf,
+    0x9c23bf9c, 0xa453f7a4,  0x72e49672,  0xc09b5bc0,
+    0xb775c2b7, 0xfde11cfd,  0x933dae93,  0x264c6a26,
+    0x366c5a36, 0x3f7e413f,  0xf7f502f7,  0xcc834fcc,
+    0x34685c34, 0xa551f4a5,  0xe5d134e5,  0xf1f908f1,
+    0x71e29371, 0xd8ab73d8,  0x31625331,  0x152a3f15,
+    0x4080c04,  0xc79552c7,  0x23466523,  0xc39d5ec3,
+    0x18302818, 0x9637a196,  0x50a0f05,   0x9a2fb59a,
+    0x70e0907,  0x12243612,  0x801b9b80,  0xe2df3de2,
+    0xebcd26eb, 0x274e6927,  0xb27fcdb2,  0x75ea9f75,
+    0x9121b09,  0x831d9e83,  0x2c58742c,  0x1a342e1a,
+    0x1b362d1b, 0x6edcb26e,  0x5ab4ee5a,  0xa05bfba0,
+    0x52a4f652, 0x3b764d3b,  0xd6b761d6,  0xb37dceb3,
+    0x29527b29, 0xe3dd3ee3,  0x2f5e712f,  0x84139784,
+    0x53a6f553, 0xd1b968d1,  0x0,         0xedc12ced,
+    0x20406020, 0xfce31ffc,  0xb179c8b1,  0x5bb6ed5b,
+    0x6ad4be6a, 0xcb8d46cb,  0xbe67d9be,  0x39724b39,
+    0x4a94de4a, 0x4c98d44c,  0x58b0e858,  0xcf854acf,
+    0xd0bb6bd0, 0xefc52aef,  0xaa4fe5aa,  0xfbed16fb,
+    0x4386c543, 0x4d9ad74d,  0x33665533,  0x85119485,
+    0x458acf45, 0xf9e910f9,  0x2040602,   0x7ffe817f,
+    0x50a0f050, 0x3c78443c,  0x9f25ba9f,  0xa84be3a8,
+    0x51a2f351, 0xa35dfea3,  0x4080c040,  0x8f058a8f,
+    0x923fad92, 0x9d21bc9d,  0x38704838,  0xf5f104f5,
+    0xbc63dfbc, 0xb677c1b6,  0xdaaf75da,  0x21426321,
+    0x10203010, 0xffe51aff,  0xf3fd0ef3,  0xd2bf6dd2,
+    0xcd814ccd, 0xc18140c,   0x13263513,  0xecc32fec,
+    0x5fbee15f, 0x9735a297,  0x4488cc44,  0x172e3917,
+    0xc49357c4, 0xa755f2a7,  0x7efc827e,  0x3d7a473d,
+    0x64c8ac64, 0x5dbae75d,  0x19322b19,  0x73e69573,
+    0x60c0a060, 0x81199881,  0x4f9ed14f,  0xdca37fdc,
+    0x22446622, 0x2a547e2a,  0x903bab90,  0x880b8388,
+    0x468cca46, 0xeec729ee,  0xb86bd3b8,  0x14283c14,
+    0xdea779de, 0x5ebce25e,  0xb161d0b,   0xdbad76db,
+    0xe0db3be0, 0x32645632,  0x3a744e3a,  0xa141e0a,
+    0x4992db49, 0x60c0a06,   0x24486c24,  0x5cb8e45c,
+    0xc29f5dc2, 0xd3bd6ed3,  0xac43efac,  0x62c4a662,
+    0x9139a891, 0x9531a495,  0xe4d337e4,  0x79f28b79,
+    0xe7d532e7, 0xc88b43c8,  0x376e5937,  0x6ddab76d,
+    0x8d018c8d, 0xd5b164d5,  0x4e9cd24e,  0xa949e0a9,
+    0x6cd8b46c, 0x56acfa56,  0xf4f307f4,  0xeacf25ea,
+    0x65caaf65, 0x7af48e7a,  0xae47e9ae,  0x8101808,
+    0xba6fd5ba, 0x78f08878,  0x254a6f25,  0x2e5c722e,
+    0x1c38241c, 0xa657f1a6,  0xb473c7b4,  0xc69751c6,
+    0xe8cb23e8, 0xdda17cdd,  0x74e89c74,  0x1f3e211f,
+    0x4b96dd4b, 0xbd61dcbd,  0x8b0d868b,  0x8a0f858a,
+    0x70e09070, 0x3e7c423e,  0xb571c4b5,  0x66ccaa66,
+    0x4890d848, 0x3060503,   0xf6f701f6,  0xe1c120e,
+    0x61c2a361, 0x356a5f35,  0x57aef957,  0xb969d0b9,
+    0x86179186, 0xc19958c1,  0x1d3a271d,  0x9e27b99e,
+    0xe1d938e1, 0xf8eb13f8,  0x982bb398,  0x11223311,
+    0x69d2bb69, 0xd9a970d9,  0x8e07898e,  0x9433a794,
+    0x9b2db69b, 0x1e3c221e,  0x87159287,  0xe9c920e9,
+    0xce8749ce, 0x55aaff55,  0x28507828,  0xdfa57adf,
+    0x8c038f8c, 0xa159f8a1,  0x89098089,  0xd1a170d,
+    0xbf65dabf, 0xe6d731e6,  0x4284c642,  0x68d0b868,
+    0x4182c341, 0x9929b099,  0x2d5a772d,  0xf1e110f,
+    0xb07bcbb0, 0x54a8fc54,  0xbb6dd6bb,  0x162c3a16,
 };
+/* clang-format on */
 
-static uint32_t T3[256] = {
-  0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 
-  0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 
-  0x60503030, 0x2030101, 0xcea96767, 0x567d2b2b, 
-  0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 
-  0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 
-  0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 
-  0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 
-  0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 
-  0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 
-  0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 
-  0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 
-  0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 
-  0x80c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 
-  0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, 
-  0xe090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 
-  0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 
-  0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 
-  0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 
-  0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 
-  0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 
-  0xa6f55353, 0xb968d1d1, 0x0, 0xc12ceded, 
-  0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 
-  0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 
-  0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 
-  0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 
-  0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 
-  0x8acf4545, 0xe910f9f9, 0x4060202, 0xfe817f7f, 
-  0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 
-  0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x58a8f8f, 
-  0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 
-  0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 
-  0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 
-  0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 
-  0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 
-  0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 
-  0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 
-  0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 
-  0x44662222, 0x547e2a2a, 0x3bab9090, 0xb838888, 
-  0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 
-  0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 
-  0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 
-  0x92db4949, 0xc0a0606, 0x486c2424, 0xb8e45c5c, 
-  0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 
-  0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 
-  0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 
-  0x18c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 
-  0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 
-  0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 
-  0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 
-  0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 
-  0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 
-  0x96dd4b4b, 0x61dcbdbd, 0xd868b8b, 0xf858a8a, 
-  0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 
-  0x90d84848, 0x6050303, 0xf701f6f6, 0x1c120e0e, 
-  0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 
-  0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 
-  0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 
-  0xd2bb6969, 0xa970d9d9, 0x7898e8e, 0x33a79494, 
-  0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 
-  0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 
-  0x38f8c8c, 0x59f8a1a1, 0x9808989, 0x1a170d0d, 
-  0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 
-  0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 
-  0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, 
+/* clang-format off */
+static const uint32_t T3[256] = {
+    0xc6a56363, 0xf8847c7c,  0xee997777,  0xf68d7b7b,
+    0xff0df2f2, 0xd6bd6b6b,  0xdeb16f6f,  0x9154c5c5,
+    0x60503030, 0x2030101,   0xcea96767,  0x567d2b2b,
+    0xe719fefe, 0xb562d7d7,  0x4de6abab,  0xec9a7676,
+    0x8f45caca, 0x1f9d8282,  0x8940c9c9,  0xfa877d7d,
+    0xef15fafa, 0xb2eb5959,  0x8ec94747,  0xfb0bf0f0,
+    0x41ecadad, 0xb367d4d4,  0x5ffda2a2,  0x45eaafaf,
+    0x23bf9c9c, 0x53f7a4a4,  0xe4967272,  0x9b5bc0c0,
+    0x75c2b7b7, 0xe11cfdfd,  0x3dae9393,  0x4c6a2626,
+    0x6c5a3636, 0x7e413f3f,  0xf502f7f7,  0x834fcccc,
+    0x685c3434, 0x51f4a5a5,  0xd134e5e5,  0xf908f1f1,
+    0xe2937171, 0xab73d8d8,  0x62533131,  0x2a3f1515,
+    0x80c0404,  0x9552c7c7,  0x46652323,  0x9d5ec3c3,
+    0x30281818, 0x37a19696,  0xa0f0505,   0x2fb59a9a,
+    0xe090707,  0x24361212,  0x1b9b8080,  0xdf3de2e2,
+    0xcd26ebeb, 0x4e692727,  0x7fcdb2b2,  0xea9f7575,
+    0x121b0909, 0x1d9e8383,  0x58742c2c,  0x342e1a1a,
+    0x362d1b1b, 0xdcb26e6e,  0xb4ee5a5a,  0x5bfba0a0,
+    0xa4f65252, 0x764d3b3b,  0xb761d6d6,  0x7dceb3b3,
+    0x527b2929, 0xdd3ee3e3,  0x5e712f2f,  0x13978484,
+    0xa6f55353, 0xb968d1d1,  0x0,         0xc12ceded,
+    0x40602020, 0xe31ffcfc,  0x79c8b1b1,  0xb6ed5b5b,
+    0xd4be6a6a, 0x8d46cbcb,  0x67d9bebe,  0x724b3939,
+    0x94de4a4a, 0x98d44c4c,  0xb0e85858,  0x854acfcf,
+    0xbb6bd0d0, 0xc52aefef,  0x4fe5aaaa,  0xed16fbfb,
+    0x86c54343, 0x9ad74d4d,  0x66553333,  0x11948585,
+    0x8acf4545, 0xe910f9f9,  0x4060202,   0xfe817f7f,
+    0xa0f05050, 0x78443c3c,  0x25ba9f9f,  0x4be3a8a8,
+    0xa2f35151, 0x5dfea3a3,  0x80c04040,  0x58a8f8f,
+    0x3fad9292, 0x21bc9d9d,  0x70483838,  0xf104f5f5,
+    0x63dfbcbc, 0x77c1b6b6,  0xaf75dada,  0x42632121,
+    0x20301010, 0xe51affff,  0xfd0ef3f3,  0xbf6dd2d2,
+    0x814ccdcd, 0x18140c0c,  0x26351313,  0xc32fecec,
+    0xbee15f5f, 0x35a29797,  0x88cc4444,  0x2e391717,
+    0x9357c4c4, 0x55f2a7a7,  0xfc827e7e,  0x7a473d3d,
+    0xc8ac6464, 0xbae75d5d,  0x322b1919,  0xe6957373,
+    0xc0a06060, 0x19988181,  0x9ed14f4f,  0xa37fdcdc,
+    0x44662222, 0x547e2a2a,  0x3bab9090,  0xb838888,
+    0x8cca4646, 0xc729eeee,  0x6bd3b8b8,  0x283c1414,
+    0xa779dede, 0xbce25e5e,  0x161d0b0b,  0xad76dbdb,
+    0xdb3be0e0, 0x64563232,  0x744e3a3a,  0x141e0a0a,
+    0x92db4949, 0xc0a0606,   0x486c2424,  0xb8e45c5c,
+    0x9f5dc2c2, 0xbd6ed3d3,  0x43efacac,  0xc4a66262,
+    0x39a89191, 0x31a49595,  0xd337e4e4,  0xf28b7979,
+    0xd532e7e7, 0x8b43c8c8,  0x6e593737,  0xdab76d6d,
+    0x18c8d8d,  0xb164d5d5,  0x9cd24e4e,  0x49e0a9a9,
+    0xd8b46c6c, 0xacfa5656,  0xf307f4f4,  0xcf25eaea,
+    0xcaaf6565, 0xf48e7a7a,  0x47e9aeae,  0x10180808,
+    0x6fd5baba, 0xf0887878,  0x4a6f2525,  0x5c722e2e,
+    0x38241c1c, 0x57f1a6a6,  0x73c7b4b4,  0x9751c6c6,
+    0xcb23e8e8, 0xa17cdddd,  0xe89c7474,  0x3e211f1f,
+    0x96dd4b4b, 0x61dcbdbd,  0xd868b8b,   0xf858a8a,
+    0xe0907070, 0x7c423e3e,  0x71c4b5b5,  0xccaa6666,
+    0x90d84848, 0x6050303,   0xf701f6f6,  0x1c120e0e,
+    0xc2a36161, 0x6a5f3535,  0xaef95757,  0x69d0b9b9,
+    0x17918686, 0x9958c1c1,  0x3a271d1d,  0x27b99e9e,
+    0xd938e1e1, 0xeb13f8f8,  0x2bb39898,  0x22331111,
+    0xd2bb6969, 0xa970d9d9,  0x7898e8e,   0x33a79494,
+    0x2db69b9b, 0x3c221e1e,  0x15928787,  0xc920e9e9,
+    0x8749cece, 0xaaff5555,  0x50782828,  0xa57adfdf,
+    0x38f8c8c,  0x59f8a1a1,  0x9808989,   0x1a170d0d,
+    0x65dabfbf, 0xd731e6e6,  0x84c64242,  0xd0b86868,
+    0x82c34141, 0x29b09999,  0x5a772d2d,  0x1e110f0f,
+    0x7bcbb0b0, 0xa8fc5454,  0x6dd6bbbb,  0x2c3a1616,
 };
+/* clang-format on */
 
-static uint32_t U0[256] = {
-  0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 
-  0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 
-  0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 
-  0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 
-  0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 
-  0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 
-  0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 
-  0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, 
-  0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 
-  0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 
-  0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 
-  0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 
-  0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 
-  0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 
-  0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, 
-  0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 
-  0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 
-  0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, 
-  0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 
-  0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd, 
-  0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 
-  0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, 
-  0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 
-  0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 
-  0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 
-  0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 
-  0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 
-  0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 
-  0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, 
-  0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 
-  0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 
-  0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 
-  0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 
-  0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 
-  0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 
-  0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 
-  0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 
-  0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, 
-  0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 
-  0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 
-  0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 
-  0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 
-  0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 
-  0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 
-  0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 
-  0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 
-  0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, 
-  0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, 
-  0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 
-  0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 
-  0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 
-  0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, 
-  0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 
-  0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 
-  0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 
-  0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 
-  0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 
-  0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 
-  0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 
-  0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 
-  0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 
-  0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff, 
-  0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 
-  0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, 
+/* clang-format off */
+static const uint32_t U0[256] = {
+    0x50a7f451, 0x5365417e,  0xc3a4171a,  0x965e273a,
+    0xcb6bab3b, 0xf1459d1f,  0xab58faac,  0x9303e34b,
+    0x55fa3020, 0xf66d76ad,  0x9176cc88,  0x254c02f5,
+    0xfcd7e54f, 0xd7cb2ac5,  0x80443526,  0x8fa362b5,
+    0x495ab1de, 0x671bba25,  0x980eea45,  0xe1c0fe5d,
+    0x2752fc3,  0x12f04c81,  0xa397468d,  0xc6f9d36b,
+    0xe75f8f03, 0x959c9215,  0xeb7a6dbf,  0xda595295,
+    0x2d83bed4, 0xd3217458,  0x2969e049,  0x44c8c98e,
+    0x6a89c275, 0x78798ef4,  0x6b3e5899,  0xdd71b927,
+    0xb64fe1be, 0x17ad88f0,  0x66ac20c9,  0xb43ace7d,
+    0x184adf63, 0x82311ae5,  0x60335197,  0x457f5362,
+    0xe07764b1, 0x84ae6bbb,  0x1ca081fe,  0x942b08f9,
+    0x58684870, 0x19fd458f,  0x876cde94,  0xb7f87b52,
+    0x23d373ab, 0xe2024b72,  0x578f1fe3,  0x2aab5566,
+    0x728ebb2,  0x3c2b52f,   0x9a7bc586,  0xa50837d3,
+    0xf2872830, 0xb2a5bf23,  0xba6a0302,  0x5c8216ed,
+    0x2b1ccf8a, 0x92b479a7,  0xf0f207f3,  0xa1e2694e,
+    0xcdf4da65, 0xd5be0506,  0x1f6234d1,  0x8afea6c4,
+    0x9d532e34, 0xa055f3a2,  0x32e18a05,  0x75ebf6a4,
+    0x39ec830b, 0xaaef6040,  0x69f715e,   0x51106ebd,
+    0xf98a213e, 0x3d06dd96,  0xae053edd,  0x46bde64d,
+    0xb58d5491, 0x55dc471,   0x6fd40604,  0xff155060,
+    0x24fb9819, 0x97e9bdd6,  0xcc434089,  0x779ed967,
+    0xbd42e8b0, 0x888b8907,  0x385b19e7,  0xdbeec879,
+    0x470a7ca1, 0xe90f427c,  0xc91e84f8,  0x0,
+    0x83868009, 0x48ed2b32,  0xac70111e,  0x4e725a6c,
+    0xfbff0efd, 0x5638850f,  0x1ed5ae3d,  0x27392d36,
+    0x64d90f0a, 0x21a65c68,  0xd1545b9b,  0x3a2e3624,
+    0xb1670a0c, 0xfe75793,   0xd296eeb4,  0x9e919b1b,
+    0x4fc5c080, 0xa220dc61,  0x694b775a,  0x161a121c,
+    0xaba93e2,  0xe52aa0c0,  0x43e0223c,  0x1d171b12,
+    0xb0d090e,  0xadc78bf2,  0xb9a8b62d,  0xc8a91e14,
+    0x8519f157, 0x4c0775af,  0xbbdd99ee,  0xfd607fa3,
+    0x9f2601f7, 0xbcf5725c,  0xc53b6644,  0x347efb5b,
+    0x7629438b, 0xdcc623cb,  0x68fcedb6,  0x63f1e4b8,
+    0xcadc31d7, 0x10856342,  0x40229713,  0x2011c684,
+    0x7d244a85, 0xf83dbbd2,  0x1132f9ae,  0x6da129c7,
+    0x4b2f9e1d, 0xf330b2dc,  0xec52860d,  0xd0e3c177,
+    0x6c16b32b, 0x99b970a9,  0xfa489411,  0x2264e947,
+    0xc48cfca8, 0x1a3ff0a0,  0xd82c7d56,  0xef903322,
+    0xc74e4987, 0xc1d138d9,  0xfea2ca8c,  0x360bd498,
+    0xcf81f5a6, 0x28de7aa5,  0x268eb7da,  0xa4bfad3f,
+    0xe49d3a2c, 0xd927850,   0x9bcc5f6a,  0x62467e54,
+    0xc2138df6, 0xe8b8d890,  0x5ef7392e,  0xf5afc382,
+    0xbe805d9f, 0x7c93d069,  0xa92dd56f,  0xb31225cf,
+    0x3b99acc8, 0xa77d1810,  0x6e639ce8,  0x7bbb3bdb,
+    0x97826cd,  0xf418596e,  0x1b79aec,   0xa89a4f83,
+    0x656e95e6, 0x7ee6ffaa,  0x8cfbc21,   0xe6e815ef,
+    0xd99be7ba, 0xce366f4a,  0xd4099fea,  0xd67cb029,
+    0xafb2a431, 0x31233f2a,  0x3094a5c6,  0xc066a235,
+    0x37bc4e74, 0xa6ca82fc,  0xb0d090e0,  0x15d8a733,
+    0x4a9804f1, 0xf7daec41,  0xe50cd7f,   0x2ff69117,
+    0x8dd64d76, 0x4db0ef43,  0x544daacc,  0xdf0496e4,
+    0xe3b5d19e, 0x1b886a4c,  0xb81f2cc1,  0x7f516546,
+    0x4ea5e9d,  0x5d358c01,  0x737487fa,  0x2e410bfb,
+    0x5a1d67b3, 0x52d2db92,  0x335610e9,  0x1347d66d,
+    0x8c61d79a, 0x7a0ca137,  0x8e14f859,  0x893c13eb,
+    0xee27a9ce, 0x35c961b7,  0xede51ce1,  0x3cb1477a,
+    0x59dfd29c, 0x3f73f255,  0x79ce1418,  0xbf37c773,
+    0xeacdf753, 0x5baafd5f,  0x146f3ddf,  0x86db4478,
+    0x81f3afca, 0x3ec468b9,  0x2c342438,  0x5f40a3c2,
+    0x72c31d16, 0xc25e2bc,   0x8b493c28,  0x41950dff,
+    0x7101a839, 0xdeb30c08,  0x9ce4b4d8,  0x90c15664,
+    0x6184cb7b, 0x70b632d5,  0x745c6c48,  0x4257b8d0,
 };
+/* clang-format on */
 
-static uint32_t U1[256] = {
-  0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 
-  0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x3e34b93, 
-  0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, 
-  0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 
-  0x5ab1de49, 0x1bba2567, 0xeea4598, 0xc0fe5de1, 
-  0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, 
-  0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 
-  0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, 
-  0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, 
-  0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 
-  0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, 
-  0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, 
-  0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 
-  0xd373ab23, 0x24b72e2, 0x8f1fe357, 0xab55662a, 
-  0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x837d3a5, 
-  0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 
-  0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, 
-  0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, 
-  0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 
-  0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, 
-  0x8a213ef9, 0x6dd963d, 0x53eddae, 0xbde64d46, 
-  0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 
-  0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, 
-  0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, 
-  0xa7ca147, 0xf427ce9, 0x1e84f8c9, 0x0, 
-  0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, 
-  0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, 
-  0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 
-  0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, 
-  0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, 
-  0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 
-  0xd090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, 
-  0x19f15785, 0x775af4c, 0xdd99eebb, 0x607fa3fd, 
-  0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 
-  0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, 
-  0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, 
-  0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 
-  0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, 
-  0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, 
-  0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 
-  0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0xbd49836, 
-  0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, 
-  0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 
-  0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, 
-  0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, 
-  0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 
-  0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, 
-  0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, 
-  0x9be7bad9, 0x366f4ace, 0x99fead4, 0x7cb029d6, 
-  0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, 
-  0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, 
-  0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 
-  0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x496e4df, 
-  0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, 
-  0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 
-  0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, 
-  0x61d79a8c, 0xca1377a, 0x14f8598e, 0x3c13eb89, 
-  0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 
-  0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, 
-  0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, 
-  0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 
-  0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, 
-  0x1a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, 
-  0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042, 
+/* clang-format off */
+static const uint32_t U1[256] = {
+    0xa7f45150, 0x65417e53,  0xa4171ac3,  0x5e273a96,
+    0x6bab3bcb, 0x459d1ff1,  0x58faacab,  0x3e34b93,
+    0xfa302055, 0x6d76adf6,  0x76cc8891,  0x4c02f525,
+    0xd7e54ffc, 0xcb2ac5d7,  0x44352680,  0xa362b58f,
+    0x5ab1de49, 0x1bba2567,  0xeea4598,   0xc0fe5de1,
+    0x752fc302, 0xf04c8112,  0x97468da3,  0xf9d36bc6,
+    0x5f8f03e7, 0x9c921595,  0x7a6dbfeb,  0x595295da,
+    0x83bed42d, 0x217458d3,  0x69e04929,  0xc8c98e44,
+    0x89c2756a, 0x798ef478,  0x3e58996b,  0x71b927dd,
+    0x4fe1beb6, 0xad88f017,  0xac20c966,  0x3ace7db4,
+    0x4adf6318, 0x311ae582,  0x33519760,  0x7f536245,
+    0x7764b1e0, 0xae6bbb84,  0xa081fe1c,  0x2b08f994,
+    0x68487058, 0xfd458f19,  0x6cde9487,  0xf87b52b7,
+    0xd373ab23, 0x24b72e2,   0x8f1fe357,  0xab55662a,
+    0x28ebb207, 0xc2b52f03,  0x7bc5869a,  0x837d3a5,
+    0x872830f2, 0xa5bf23b2,  0x6a0302ba,  0x8216ed5c,
+    0x1ccf8a2b, 0xb479a792,  0xf207f3f0,  0xe2694ea1,
+    0xf4da65cd, 0xbe0506d5,  0x6234d11f,  0xfea6c48a,
+    0x532e349d, 0x55f3a2a0,  0xe18a0532,  0xebf6a475,
+    0xec830b39, 0xef6040aa,  0x9f715e06,  0x106ebd51,
+    0x8a213ef9, 0x6dd963d,   0x53eddae,   0xbde64d46,
+    0x8d5491b5, 0x5dc47105,  0xd406046f,  0x155060ff,
+    0xfb981924, 0xe9bdd697,  0x434089cc,  0x9ed96777,
+    0x42e8b0bd, 0x8b890788,  0x5b19e738,  0xeec879db,
+    0xa7ca147,  0xf427ce9,   0x1e84f8c9,  0x0,
+    0x86800983, 0xed2b3248,  0x70111eac,  0x725a6c4e,
+    0xff0efdfb, 0x38850f56,  0xd5ae3d1e,  0x392d3627,
+    0xd90f0a64, 0xa65c6821,  0x545b9bd1,  0x2e36243a,
+    0x670a0cb1, 0xe757930f,  0x96eeb4d2,  0x919b1b9e,
+    0xc5c0804f, 0x20dc61a2,  0x4b775a69,  0x1a121c16,
+    0xba93e20a, 0x2aa0c0e5,  0xe0223c43,  0x171b121d,
+    0xd090e0b,  0xc78bf2ad,  0xa8b62db9,  0xa91e14c8,
+    0x19f15785, 0x775af4c,   0xdd99eebb,  0x607fa3fd,
+    0x2601f79f, 0xf5725cbc,  0x3b6644c5,  0x7efb5b34,
+    0x29438b76, 0xc623cbdc,  0xfcedb668,  0xf1e4b863,
+    0xdc31d7ca, 0x85634210,  0x22971340,  0x11c68420,
+    0x244a857d, 0x3dbbd2f8,  0x32f9ae11,  0xa129c76d,
+    0x2f9e1d4b, 0x30b2dcf3,  0x52860dec,  0xe3c177d0,
+    0x16b32b6c, 0xb970a999,  0x489411fa,  0x64e94722,
+    0x8cfca8c4, 0x3ff0a01a,  0x2c7d56d8,  0x903322ef,
+    0x4e4987c7, 0xd138d9c1,  0xa2ca8cfe,  0xbd49836,
+    0x81f5a6cf, 0xde7aa528,  0x8eb7da26,  0xbfad3fa4,
+    0x9d3a2ce4, 0x9278500d,  0xcc5f6a9b,  0x467e5462,
+    0x138df6c2, 0xb8d890e8,  0xf7392e5e,  0xafc382f5,
+    0x805d9fbe, 0x93d0697c,  0x2dd56fa9,  0x1225cfb3,
+    0x99acc83b, 0x7d1810a7,  0x639ce86e,  0xbb3bdb7b,
+    0x7826cd09, 0x18596ef4,  0xb79aec01,  0x9a4f83a8,
+    0x6e95e665, 0xe6ffaa7e,  0xcfbc2108,  0xe815efe6,
+    0x9be7bad9, 0x366f4ace,  0x99fead4,   0x7cb029d6,
+    0xb2a431af, 0x233f2a31,  0x94a5c630,  0x66a235c0,
+    0xbc4e7437, 0xca82fca6,  0xd090e0b0,  0xd8a73315,
+    0x9804f14a, 0xdaec41f7,  0x50cd7f0e,  0xf691172f,
+    0xd64d768d, 0xb0ef434d,  0x4daacc54,  0x496e4df,
+    0xb5d19ee3, 0x886a4c1b,  0x1f2cc1b8,  0x5165467f,
+    0xea5e9d04, 0x358c015d,  0x7487fa73,  0x410bfb2e,
+    0x1d67b35a, 0xd2db9252,  0x5610e933,  0x47d66d13,
+    0x61d79a8c, 0xca1377a,   0x14f8598e,  0x3c13eb89,
+    0x27a9ceee, 0xc961b735,  0xe51ce1ed,  0xb1477a3c,
+    0xdfd29c59, 0x73f2553f,  0xce141879,  0x37c773bf,
+    0xcdf753ea, 0xaafd5f5b,  0x6f3ddf14,  0xdb447886,
+    0xf3afca81, 0xc468b93e,  0x3424382c,  0x40a3c25f,
+    0xc31d1672, 0x25e2bc0c,  0x493c288b,  0x950dff41,
+    0x1a83971,  0xb30c08de,  0xe4b4d89c,  0xc1566490,
+    0x84cb7b61, 0xb632d570,  0x5c6c4874,  0x57b8d042,
 };
+/* clang-format on */
 
-static uint32_t U2[256] = {
-  0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 
-  0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, 
-  0x302055fa, 0x76adf66d, 0xcc889176, 0x2f5254c, 
-  0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 
-  0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, 
-  0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, 
-  0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 
-  0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, 
-  0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, 
-  0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 
-  0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, 
-  0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x8f9942b, 
-  0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 
-  0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, 
-  0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, 
-  0x2830f287, 0xbf23b2a5, 0x302ba6a, 0x16ed5c82, 
-  0xcf8a2b1c, 0x79a792b4, 0x7f3f0f2, 0x694ea1e2, 
-  0xda65cdf4, 0x506d5be, 0x34d11f62, 0xa6c48afe, 
-  0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 
-  0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, 
-  0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, 
-  0x5491b58d, 0xc471055d, 0x6046fd4, 0x5060ff15, 
-  0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, 
-  0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, 
-  0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x0, 
-  0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, 
-  0xefdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, 
-  0xf0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 
-  0xa0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, 
-  0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, 
-  0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 
-  0x90e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, 
-  0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, 
-  0x1f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 
-  0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, 
-  0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, 
-  0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 
-  0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, 
-  0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, 
-  0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 
-  0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, 
-  0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, 
-  0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 
-  0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, 
-  0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, 
-  0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 
-  0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, 
-  0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, 
-  0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 
-  0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, 
-  0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, 
-  0x4f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 
-  0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, 
-  0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, 
-  0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0xbfb2e41, 
-  0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, 
-  0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, 
-  0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 
-  0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, 
-  0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, 
-  0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 
-  0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0xdff4195, 
-  0xa8397101, 0xc08deb3, 0xb4d89ce4, 0x566490c1, 
-  0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257, 
+/* clang-format off */
+static const uint32_t U2[256] = {
+    0xf45150a7, 0x417e5365,  0x171ac3a4,  0x273a965e,
+    0xab3bcb6b, 0x9d1ff145,  0xfaacab58,  0xe34b9303,
+    0x302055fa, 0x76adf66d,  0xcc889176,  0x2f5254c,
+    0xe54ffcd7, 0x2ac5d7cb,  0x35268044,  0x62b58fa3,
+    0xb1de495a, 0xba25671b,  0xea45980e,  0xfe5de1c0,
+    0x2fc30275, 0x4c8112f0,  0x468da397,  0xd36bc6f9,
+    0x8f03e75f, 0x9215959c,  0x6dbfeb7a,  0x5295da59,
+    0xbed42d83, 0x7458d321,  0xe0492969,  0xc98e44c8,
+    0xc2756a89, 0x8ef47879,  0x58996b3e,  0xb927dd71,
+    0xe1beb64f, 0x88f017ad,  0x20c966ac,  0xce7db43a,
+    0xdf63184a, 0x1ae58231,  0x51976033,  0x5362457f,
+    0x64b1e077, 0x6bbb84ae,  0x81fe1ca0,  0x8f9942b,
+    0x48705868, 0x458f19fd,  0xde94876c,  0x7b52b7f8,
+    0x73ab23d3, 0x4b72e202,  0x1fe3578f,  0x55662aab,
+    0xebb20728, 0xb52f03c2,  0xc5869a7b,  0x37d3a508,
+    0x2830f287, 0xbf23b2a5,  0x302ba6a,   0x16ed5c82,
+    0xcf8a2b1c, 0x79a792b4,  0x7f3f0f2,   0x694ea1e2,
+    0xda65cdf4, 0x506d5be,   0x34d11f62,  0xa6c48afe,
+    0x2e349d53, 0xf3a2a055,  0x8a0532e1,  0xf6a475eb,
+    0x830b39ec, 0x6040aaef,  0x715e069f,  0x6ebd5110,
+    0x213ef98a, 0xdd963d06,  0x3eddae05,  0xe64d46bd,
+    0x5491b58d, 0xc471055d,  0x6046fd4,   0x5060ff15,
+    0x981924fb, 0xbdd697e9,  0x4089cc43,  0xd967779e,
+    0xe8b0bd42, 0x8907888b,  0x19e7385b,  0xc879dbee,
+    0x7ca1470a, 0x427ce90f,  0x84f8c91e,  0x0,
+    0x80098386, 0x2b3248ed,  0x111eac70,  0x5a6c4e72,
+    0xefdfbff,  0x850f5638,  0xae3d1ed5,  0x2d362739,
+    0xf0a64d9,  0x5c6821a6,  0x5b9bd154,  0x36243a2e,
+    0xa0cb167,  0x57930fe7,  0xeeb4d296,  0x9b1b9e91,
+    0xc0804fc5, 0xdc61a220,  0x775a694b,  0x121c161a,
+    0x93e20aba, 0xa0c0e52a,  0x223c43e0,  0x1b121d17,
+    0x90e0b0d,  0x8bf2adc7,  0xb62db9a8,  0x1e14c8a9,
+    0xf1578519, 0x75af4c07,  0x99eebbdd,  0x7fa3fd60,
+    0x1f79f26,  0x725cbcf5,  0x6644c53b,  0xfb5b347e,
+    0x438b7629, 0x23cbdcc6,  0xedb668fc,  0xe4b863f1,
+    0x31d7cadc, 0x63421085,  0x97134022,  0xc6842011,
+    0x4a857d24, 0xbbd2f83d,  0xf9ae1132,  0x29c76da1,
+    0x9e1d4b2f, 0xb2dcf330,  0x860dec52,  0xc177d0e3,
+    0xb32b6c16, 0x70a999b9,  0x9411fa48,  0xe9472264,
+    0xfca8c48c, 0xf0a01a3f,  0x7d56d82c,  0x3322ef90,
+    0x4987c74e, 0x38d9c1d1,  0xca8cfea2,  0xd498360b,
+    0xf5a6cf81, 0x7aa528de,  0xb7da268e,  0xad3fa4bf,
+    0x3a2ce49d, 0x78500d92,  0x5f6a9bcc,  0x7e546246,
+    0x8df6c213, 0xd890e8b8,  0x392e5ef7,  0xc382f5af,
+    0x5d9fbe80, 0xd0697c93,  0xd56fa92d,  0x25cfb312,
+    0xacc83b99, 0x1810a77d,  0x9ce86e63,  0x3bdb7bbb,
+    0x26cd0978, 0x596ef418,  0x9aec01b7,  0x4f83a89a,
+    0x95e6656e, 0xffaa7ee6,  0xbc2108cf,  0x15efe6e8,
+    0xe7bad99b, 0x6f4ace36,  0x9fead409,  0xb029d67c,
+    0xa431afb2, 0x3f2a3123,  0xa5c63094,  0xa235c066,
+    0x4e7437bc, 0x82fca6ca,  0x90e0b0d0,  0xa73315d8,
+    0x4f14a98,  0xec41f7da,  0xcd7f0e50,  0x91172ff6,
+    0x4d768dd6, 0xef434db0,  0xaacc544d,  0x96e4df04,
+    0xd19ee3b5, 0x6a4c1b88,  0x2cc1b81f,  0x65467f51,
+    0x5e9d04ea, 0x8c015d35,  0x87fa7374,  0xbfb2e41,
+    0x67b35a1d, 0xdb9252d2,  0x10e93356,  0xd66d1347,
+    0xd79a8c61, 0xa1377a0c,  0xf8598e14,  0x13eb893c,
+    0xa9ceee27, 0x61b735c9,  0x1ce1ede5,  0x477a3cb1,
+    0xd29c59df, 0xf2553f73,  0x141879ce,  0xc773bf37,
+    0xf753eacd, 0xfd5f5baa,  0x3ddf146f,  0x447886db,
+    0xafca81f3, 0x68b93ec4,  0x24382c34,  0xa3c25f40,
+    0x1d1672c3, 0xe2bc0c25,  0x3c288b49,  0xdff4195,
+    0xa8397101, 0xc08deb3,   0xb4d89ce4,  0x566490c1,
+    0xcb7b6184, 0x32d570b6,  0x6c48745c,  0xb8d04257,
 };
+/* clang-format on */
 
-static uint32_t U3[256] = {
-  0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 
-  0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, 
-  0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, 
-  0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 
-  0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, 
-  0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, 
-  0x3e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 
-  0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, 
-  0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, 
-  0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 
-  0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, 
-  0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, 
-  0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 
-  0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, 
-  0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, 
-  0x30f28728, 0x23b2a5bf, 0x2ba6a03, 0xed5c8216, 
-  0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, 
-  0x65cdf4da, 0x6d5be05, 0xd11f6234, 0xc48afea6, 
-  0x349d532e, 0xa2a055f3, 0x532e18a, 0xa475ebf6, 
-  0xb39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, 
-  0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, 
-  0x91b58d54, 0x71055dc4, 0x46fd406, 0x60ff1550, 
-  0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, 
-  0xb0bd42e8, 0x7888b89, 0xe7385b19, 0x79dbeec8, 
-  0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x0, 
-  0x9838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, 
-  0xfdfbff0e, 0xf563885, 0x3d1ed5ae, 0x3627392d, 
-  0xa64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 
-  0xcb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, 
-  0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, 
-  0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 
-  0xe0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, 
-  0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, 
-  0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 
-  0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, 
-  0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, 
-  0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 
-  0x1d4b2f9e, 0xdcf330b2, 0xdec5286, 0x77d0e3c1, 
-  0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, 
-  0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 
-  0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, 
-  0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, 
-  0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 
-  0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, 
-  0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, 
-  0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 
-  0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, 
-  0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, 
-  0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 
-  0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, 
-  0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, 
-  0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 
-  0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, 
-  0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, 
-  0x9d04ea5e, 0x15d358c, 0xfa737487, 0xfb2e410b, 
-  0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, 
-  0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, 
-  0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 
-  0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, 
-  0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, 
-  0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 
-  0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, 
-  0x397101a8, 0x8deb30c, 0xd89ce4b4, 0x6490c156, 
-  0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8, 
+/* clang-format off */
+static const uint32_t U3[256] = {
+    0x5150a7f4, 0x7e536541,  0x1ac3a417,  0x3a965e27,
+    0x3bcb6bab, 0x1ff1459d,  0xacab58fa,  0x4b9303e3,
+    0x2055fa30, 0xadf66d76,  0x889176cc,  0xf5254c02,
+    0x4ffcd7e5, 0xc5d7cb2a,  0x26804435,  0xb58fa362,
+    0xde495ab1, 0x25671bba,  0x45980eea,  0x5de1c0fe,
+    0xc302752f, 0x8112f04c,  0x8da39746,  0x6bc6f9d3,
+    0x3e75f8f,  0x15959c92,  0xbfeb7a6d,  0x95da5952,
+    0xd42d83be, 0x58d32174,  0x492969e0,  0x8e44c8c9,
+    0x756a89c2, 0xf478798e,  0x996b3e58,  0x27dd71b9,
+    0xbeb64fe1, 0xf017ad88,  0xc966ac20,  0x7db43ace,
+    0x63184adf, 0xe582311a,  0x97603351,  0x62457f53,
+    0xb1e07764, 0xbb84ae6b,  0xfe1ca081,  0xf9942b08,
+    0x70586848, 0x8f19fd45,  0x94876cde,  0x52b7f87b,
+    0xab23d373, 0x72e2024b,  0xe3578f1f,  0x662aab55,
+    0xb20728eb, 0x2f03c2b5,  0x869a7bc5,  0xd3a50837,
+    0x30f28728, 0x23b2a5bf,  0x2ba6a03,   0xed5c8216,
+    0x8a2b1ccf, 0xa792b479,  0xf3f0f207,  0x4ea1e269,
+    0x65cdf4da, 0x6d5be05,   0xd11f6234,  0xc48afea6,
+    0x349d532e, 0xa2a055f3,  0x532e18a,   0xa475ebf6,
+    0xb39ec83,  0x40aaef60,  0x5e069f71,  0xbd51106e,
+    0x3ef98a21, 0x963d06dd,  0xddae053e,  0x4d46bde6,
+    0x91b58d54, 0x71055dc4,  0x46fd406,   0x60ff1550,
+    0x1924fb98, 0xd697e9bd,  0x89cc4340,  0x67779ed9,
+    0xb0bd42e8, 0x7888b89,   0xe7385b19,  0x79dbeec8,
+    0xa1470a7c, 0x7ce90f42,  0xf8c91e84,  0x0,
+    0x9838680,  0x3248ed2b,  0x1eac7011,  0x6c4e725a,
+    0xfdfbff0e, 0xf563885,   0x3d1ed5ae,  0x3627392d,
+    0xa64d90f,  0x6821a65c,  0x9bd1545b,  0x243a2e36,
+    0xcb1670a,  0x930fe757,  0xb4d296ee,  0x1b9e919b,
+    0x804fc5c0, 0x61a220dc,  0x5a694b77,  0x1c161a12,
+    0xe20aba93, 0xc0e52aa0,  0x3c43e022,  0x121d171b,
+    0xe0b0d09,  0xf2adc78b,  0x2db9a8b6,  0x14c8a91e,
+    0x578519f1, 0xaf4c0775,  0xeebbdd99,  0xa3fd607f,
+    0xf79f2601, 0x5cbcf572,  0x44c53b66,  0x5b347efb,
+    0x8b762943, 0xcbdcc623,  0xb668fced,  0xb863f1e4,
+    0xd7cadc31, 0x42108563,  0x13402297,  0x842011c6,
+    0x857d244a, 0xd2f83dbb,  0xae1132f9,  0xc76da129,
+    0x1d4b2f9e, 0xdcf330b2,  0xdec5286,   0x77d0e3c1,
+    0x2b6c16b3, 0xa999b970,  0x11fa4894,  0x472264e9,
+    0xa8c48cfc, 0xa01a3ff0,  0x56d82c7d,  0x22ef9033,
+    0x87c74e49, 0xd9c1d138,  0x8cfea2ca,  0x98360bd4,
+    0xa6cf81f5, 0xa528de7a,  0xda268eb7,  0x3fa4bfad,
+    0x2ce49d3a, 0x500d9278,  0x6a9bcc5f,  0x5462467e,
+    0xf6c2138d, 0x90e8b8d8,  0x2e5ef739,  0x82f5afc3,
+    0x9fbe805d, 0x697c93d0,  0x6fa92dd5,  0xcfb31225,
+    0xc83b99ac, 0x10a77d18,  0xe86e639c,  0xdb7bbb3b,
+    0xcd097826, 0x6ef41859,  0xec01b79a,  0x83a89a4f,
+    0xe6656e95, 0xaa7ee6ff,  0x2108cfbc,  0xefe6e815,
+    0xbad99be7, 0x4ace366f,  0xead4099f,  0x29d67cb0,
+    0x31afb2a4, 0x2a31233f,  0xc63094a5,  0x35c066a2,
+    0x7437bc4e, 0xfca6ca82,  0xe0b0d090,  0x3315d8a7,
+    0xf14a9804, 0x41f7daec,  0x7f0e50cd,  0x172ff691,
+    0x768dd64d, 0x434db0ef,  0xcc544daa,  0xe4df0496,
+    0x9ee3b5d1, 0x4c1b886a,  0xc1b81f2c,  0x467f5165,
+    0x9d04ea5e, 0x15d358c,   0xfa737487,  0xfb2e410b,
+    0xb35a1d67, 0x9252d2db,  0xe9335610,  0x6d1347d6,
+    0x9a8c61d7, 0x377a0ca1,  0x598e14f8,  0xeb893c13,
+    0xceee27a9, 0xb735c961,  0xe1ede51c,  0x7a3cb147,
+    0x9c59dfd2, 0x553f73f2,  0x1879ce14,  0x73bf37c7,
+    0x53eacdf7, 0x5f5baafd,  0xdf146f3d,  0x7886db44,
+    0xca81f3af, 0xb93ec468,  0x382c3424,  0xc25f40a3,
+    0x1672c31d, 0xbc0c25e2,  0x288b493c,  0xff41950d,
+    0x397101a8, 0x8deb30c,   0xd89ce4b4,  0x6490c156,
+    0x7b6184cb, 0xd570b632,  0x48745c6c,  0xd04257b8,
 };
+/* clang-format on */
 
 #else /* assume big endian */
-
-static uint32_t T0[256] = {
-  0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 
-  0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, 
-  0x60303050, 0x2010103, 0xce6767a9, 0x562b2b7d, 
-  0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 
-  0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 
-  0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, 
-  0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 
-  0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, 
-  0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 
-  0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 
-  0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 
-  0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, 
-  0x804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 
-  0x30181828, 0x379696a1, 0xa05050f, 0x2f9a9ab5, 
-  0xe070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 
-  0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 
-  0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 
-  0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, 
-  0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 
-  0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, 
-  0xa65353f5, 0xb9d1d168, 0x0, 0xc1eded2c, 
-  0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 
-  0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 
-  0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, 
-  0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 
-  0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, 
-  0x8a4545cf, 0xe9f9f910, 0x4020206, 0xfe7f7f81, 
-  0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 
-  0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x58f8f8a, 
-  0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, 
-  0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 
-  0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, 
-  0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 
-  0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 
-  0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 
-  0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, 
-  0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 
-  0x44222266, 0x542a2a7e, 0x3b9090ab, 0xb888883, 
-  0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 
-  0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 
-  0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 
-  0x924949db, 0xc06060a, 0x4824246c, 0xb85c5ce4, 
-  0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 
-  0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, 
-  0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 
-  0x18d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 
-  0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 
-  0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, 
-  0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 
-  0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, 
-  0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 
-  0x964b4bdd, 0x61bdbddc, 0xd8b8b86, 0xf8a8a85, 
-  0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 
-  0x904848d8, 0x6030305, 0xf7f6f601, 0x1c0e0e12, 
-  0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 
-  0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, 
-  0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 
-  0xd26969bb, 0xa9d9d970, 0x78e8e89, 0x339494a7, 
-  0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 
-  0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, 
-  0x38c8c8f, 0x59a1a1f8, 0x9898980, 0x1a0d0d17, 
-  0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, 
-  0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 
-  0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a, 
+/* clang-format off */
+static const uint32_t T0[256] = {
+    0xc66363a5, 0xf87c7c84,  0xee777799,  0xf67b7b8d,
+    0xfff2f20d, 0xd66b6bbd,  0xde6f6fb1,  0x91c5c554,
+    0x60303050, 0x2010103,   0xce6767a9,  0x562b2b7d,
+    0xe7fefe19, 0xb5d7d762,  0x4dababe6,  0xec76769a,
+    0x8fcaca45, 0x1f82829d,  0x89c9c940,  0xfa7d7d87,
+    0xeffafa15, 0xb25959eb,  0x8e4747c9,  0xfbf0f00b,
+    0x41adadec, 0xb3d4d467,  0x5fa2a2fd,  0x45afafea,
+    0x239c9cbf, 0x53a4a4f7,  0xe4727296,  0x9bc0c05b,
+    0x75b7b7c2, 0xe1fdfd1c,  0x3d9393ae,  0x4c26266a,
+    0x6c36365a, 0x7e3f3f41,  0xf5f7f702,  0x83cccc4f,
+    0x6834345c, 0x51a5a5f4,  0xd1e5e534,  0xf9f1f108,
+    0xe2717193, 0xabd8d873,  0x62313153,  0x2a15153f,
+    0x804040c,  0x95c7c752,  0x46232365,  0x9dc3c35e,
+    0x30181828, 0x379696a1,  0xa05050f,   0x2f9a9ab5,
+    0xe070709,  0x24121236,  0x1b80809b,  0xdfe2e23d,
+    0xcdebeb26, 0x4e272769,  0x7fb2b2cd,  0xea75759f,
+    0x1209091b, 0x1d83839e,  0x582c2c74,  0x341a1a2e,
+    0x361b1b2d, 0xdc6e6eb2,  0xb45a5aee,  0x5ba0a0fb,
+    0xa45252f6, 0x763b3b4d,  0xb7d6d661,  0x7db3b3ce,
+    0x5229297b, 0xdde3e33e,  0x5e2f2f71,  0x13848497,
+    0xa65353f5, 0xb9d1d168,  0x0,         0xc1eded2c,
+    0x40202060, 0xe3fcfc1f,  0x79b1b1c8,  0xb65b5bed,
+    0xd46a6abe, 0x8dcbcb46,  0x67bebed9,  0x7239394b,
+    0x944a4ade, 0x984c4cd4,  0xb05858e8,  0x85cfcf4a,
+    0xbbd0d06b, 0xc5efef2a,  0x4faaaae5,  0xedfbfb16,
+    0x864343c5, 0x9a4d4dd7,  0x66333355,  0x11858594,
+    0x8a4545cf, 0xe9f9f910,  0x4020206,   0xfe7f7f81,
+    0xa05050f0, 0x783c3c44,  0x259f9fba,  0x4ba8a8e3,
+    0xa25151f3, 0x5da3a3fe,  0x804040c0,  0x58f8f8a,
+    0x3f9292ad, 0x219d9dbc,  0x70383848,  0xf1f5f504,
+    0x63bcbcdf, 0x77b6b6c1,  0xafdada75,  0x42212163,
+    0x20101030, 0xe5ffff1a,  0xfdf3f30e,  0xbfd2d26d,
+    0x81cdcd4c, 0x180c0c14,  0x26131335,  0xc3ecec2f,
+    0xbe5f5fe1, 0x359797a2,  0x884444cc,  0x2e171739,
+    0x93c4c457, 0x55a7a7f2,  0xfc7e7e82,  0x7a3d3d47,
+    0xc86464ac, 0xba5d5de7,  0x3219192b,  0xe6737395,
+    0xc06060a0, 0x19818198,  0x9e4f4fd1,  0xa3dcdc7f,
+    0x44222266, 0x542a2a7e,  0x3b9090ab,  0xb888883,
+    0x8c4646ca, 0xc7eeee29,  0x6bb8b8d3,  0x2814143c,
+    0xa7dede79, 0xbc5e5ee2,  0x160b0b1d,  0xaddbdb76,
+    0xdbe0e03b, 0x64323256,  0x743a3a4e,  0x140a0a1e,
+    0x924949db, 0xc06060a,   0x4824246c,  0xb85c5ce4,
+    0x9fc2c25d, 0xbdd3d36e,  0x43acacef,  0xc46262a6,
+    0x399191a8, 0x319595a4,  0xd3e4e437,  0xf279798b,
+    0xd5e7e732, 0x8bc8c843,  0x6e373759,  0xda6d6db7,
+    0x18d8d8c,  0xb1d5d564,  0x9c4e4ed2,  0x49a9a9e0,
+    0xd86c6cb4, 0xac5656fa,  0xf3f4f407,  0xcfeaea25,
+    0xca6565af, 0xf47a7a8e,  0x47aeaee9,  0x10080818,
+    0x6fbabad5, 0xf0787888,  0x4a25256f,  0x5c2e2e72,
+    0x381c1c24, 0x57a6a6f1,  0x73b4b4c7,  0x97c6c651,
+    0xcbe8e823, 0xa1dddd7c,  0xe874749c,  0x3e1f1f21,
+    0x964b4bdd, 0x61bdbddc,  0xd8b8b86,   0xf8a8a85,
+    0xe0707090, 0x7c3e3e42,  0x71b5b5c4,  0xcc6666aa,
+    0x904848d8, 0x6030305,   0xf7f6f601,  0x1c0e0e12,
+    0xc26161a3, 0x6a35355f,  0xae5757f9,  0x69b9b9d0,
+    0x17868691, 0x99c1c158,  0x3a1d1d27,  0x279e9eb9,
+    0xd9e1e138, 0xebf8f813,  0x2b9898b3,  0x22111133,
+    0xd26969bb, 0xa9d9d970,  0x78e8e89,   0x339494a7,
+    0x2d9b9bb6, 0x3c1e1e22,  0x15878792,  0xc9e9e920,
+    0x87cece49, 0xaa5555ff,  0x50282878,  0xa5dfdf7a,
+    0x38c8c8f,  0x59a1a1f8,  0x9898980,   0x1a0d0d17,
+    0x65bfbfda, 0xd7e6e631,  0x844242c6,  0xd06868b8,
+    0x824141c3, 0x299999b0,  0x5a2d2d77,  0x1e0f0f11,
+    0x7bb0b0cb, 0xa85454fc,  0x6dbbbbd6,  0x2c16163a,
 };
+/* clang-format on */
 
-static uint32_t T1[256] = {
-  0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 
-  0xdfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5, 
-  0x50603030, 0x3020101, 0xa9ce6767, 0x7d562b2b, 
-  0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 
-  0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 
-  0x15effafa, 0xebb25959, 0xc98e4747, 0xbfbf0f0, 
-  0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 
-  0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0, 
-  0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 
-  0x5a6c3636, 0x417e3f3f, 0x2f5f7f7, 0x4f83cccc, 
-  0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x8f9f1f1, 
-  0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515, 
-  0xc080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 
-  0x28301818, 0xa1379696, 0xf0a0505, 0xb52f9a9a, 
-  0x90e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 
-  0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 
-  0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 
-  0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0, 
-  0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 
-  0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484, 
-  0xf5a65353, 0x68b9d1d1, 0x0, 0x2cc1eded, 
-  0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 
-  0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 
-  0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf, 
-  0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 
-  0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585, 
-  0xcf8a4545, 0x10e9f9f9, 0x6040202, 0x81fe7f7f, 
-  0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 
-  0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 
-  0xad3f9292, 0xbc219d9d, 0x48703838, 0x4f1f5f5, 
-  0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 
-  0x30201010, 0x1ae5ffff, 0xefdf3f3, 0x6dbfd2d2, 
-  0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 
-  0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 
-  0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 
-  0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373, 
-  0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 
-  0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888, 
-  0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 
-  0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 
-  0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 
-  0xdb924949, 0xa0c0606, 0x6c482424, 0xe4b85c5c, 
-  0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 
-  0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979, 
-  0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 
-  0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 
-  0xb4d86c6c, 0xfaac5656, 0x7f3f4f4, 0x25cfeaea, 
-  0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808, 
-  0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 
-  0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6, 
-  0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 
-  0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 
-  0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 
-  0xd8904848, 0x5060303, 0x1f7f6f6, 0x121c0e0e, 
-  0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 
-  0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e, 
-  0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 
-  0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 
-  0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 
-  0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf, 
-  0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 
-  0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868, 
-  0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 
-  0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616, 
+/* clang-format off */
+static const uint32_t T1[256] = {
+    0xa5c66363, 0x84f87c7c,  0x99ee7777,  0x8df67b7b,
+    0xdfff2f2,  0xbdd66b6b,  0xb1de6f6f,  0x5491c5c5,
+    0x50603030, 0x3020101,   0xa9ce6767,  0x7d562b2b,
+    0x19e7fefe, 0x62b5d7d7,  0xe64dabab,  0x9aec7676,
+    0x458fcaca, 0x9d1f8282,  0x4089c9c9,  0x87fa7d7d,
+    0x15effafa, 0xebb25959,  0xc98e4747,  0xbfbf0f0,
+    0xec41adad, 0x67b3d4d4,  0xfd5fa2a2,  0xea45afaf,
+    0xbf239c9c, 0xf753a4a4,  0x96e47272,  0x5b9bc0c0,
+    0xc275b7b7, 0x1ce1fdfd,  0xae3d9393,  0x6a4c2626,
+    0x5a6c3636, 0x417e3f3f,  0x2f5f7f7,   0x4f83cccc,
+    0x5c683434, 0xf451a5a5,  0x34d1e5e5,  0x8f9f1f1,
+    0x93e27171, 0x73abd8d8,  0x53623131,  0x3f2a1515,
+    0xc080404,  0x5295c7c7,  0x65462323,  0x5e9dc3c3,
+    0x28301818, 0xa1379696,  0xf0a0505,   0xb52f9a9a,
+    0x90e0707,  0x36241212,  0x9b1b8080,  0x3ddfe2e2,
+    0x26cdebeb, 0x694e2727,  0xcd7fb2b2,  0x9fea7575,
+    0x1b120909, 0x9e1d8383,  0x74582c2c,  0x2e341a1a,
+    0x2d361b1b, 0xb2dc6e6e,  0xeeb45a5a,  0xfb5ba0a0,
+    0xf6a45252, 0x4d763b3b,  0x61b7d6d6,  0xce7db3b3,
+    0x7b522929, 0x3edde3e3,  0x715e2f2f,  0x97138484,
+    0xf5a65353, 0x68b9d1d1,  0x0,         0x2cc1eded,
+    0x60402020, 0x1fe3fcfc,  0xc879b1b1,  0xedb65b5b,
+    0xbed46a6a, 0x468dcbcb,  0xd967bebe,  0x4b723939,
+    0xde944a4a, 0xd4984c4c,  0xe8b05858,  0x4a85cfcf,
+    0x6bbbd0d0, 0x2ac5efef,  0xe54faaaa,  0x16edfbfb,
+    0xc5864343, 0xd79a4d4d,  0x55663333,  0x94118585,
+    0xcf8a4545, 0x10e9f9f9,  0x6040202,   0x81fe7f7f,
+    0xf0a05050, 0x44783c3c,  0xba259f9f,  0xe34ba8a8,
+    0xf3a25151, 0xfe5da3a3,  0xc0804040,  0x8a058f8f,
+    0xad3f9292, 0xbc219d9d,  0x48703838,  0x4f1f5f5,
+    0xdf63bcbc, 0xc177b6b6,  0x75afdada,  0x63422121,
+    0x30201010, 0x1ae5ffff,  0xefdf3f3,   0x6dbfd2d2,
+    0x4c81cdcd, 0x14180c0c,  0x35261313,  0x2fc3ecec,
+    0xe1be5f5f, 0xa2359797,  0xcc884444,  0x392e1717,
+    0x5793c4c4, 0xf255a7a7,  0x82fc7e7e,  0x477a3d3d,
+    0xacc86464, 0xe7ba5d5d,  0x2b321919,  0x95e67373,
+    0xa0c06060, 0x98198181,  0xd19e4f4f,  0x7fa3dcdc,
+    0x66442222, 0x7e542a2a,  0xab3b9090,  0x830b8888,
+    0xca8c4646, 0x29c7eeee,  0xd36bb8b8,  0x3c281414,
+    0x79a7dede, 0xe2bc5e5e,  0x1d160b0b,  0x76addbdb,
+    0x3bdbe0e0, 0x56643232,  0x4e743a3a,  0x1e140a0a,
+    0xdb924949, 0xa0c0606,   0x6c482424,  0xe4b85c5c,
+    0x5d9fc2c2, 0x6ebdd3d3,  0xef43acac,  0xa6c46262,
+    0xa8399191, 0xa4319595,  0x37d3e4e4,  0x8bf27979,
+    0x32d5e7e7, 0x438bc8c8,  0x596e3737,  0xb7da6d6d,
+    0x8c018d8d, 0x64b1d5d5,  0xd29c4e4e,  0xe049a9a9,
+    0xb4d86c6c, 0xfaac5656,  0x7f3f4f4,   0x25cfeaea,
+    0xafca6565, 0x8ef47a7a,  0xe947aeae,  0x18100808,
+    0xd56fbaba, 0x88f07878,  0x6f4a2525,  0x725c2e2e,
+    0x24381c1c, 0xf157a6a6,  0xc773b4b4,  0x5197c6c6,
+    0x23cbe8e8, 0x7ca1dddd,  0x9ce87474,  0x213e1f1f,
+    0xdd964b4b, 0xdc61bdbd,  0x860d8b8b,  0x850f8a8a,
+    0x90e07070, 0x427c3e3e,  0xc471b5b5,  0xaacc6666,
+    0xd8904848, 0x5060303,   0x1f7f6f6,   0x121c0e0e,
+    0xa3c26161, 0x5f6a3535,  0xf9ae5757,  0xd069b9b9,
+    0x91178686, 0x5899c1c1,  0x273a1d1d,  0xb9279e9e,
+    0x38d9e1e1, 0x13ebf8f8,  0xb32b9898,  0x33221111,
+    0xbbd26969, 0x70a9d9d9,  0x89078e8e,  0xa7339494,
+    0xb62d9b9b, 0x223c1e1e,  0x92158787,  0x20c9e9e9,
+    0x4987cece, 0xffaa5555,  0x78502828,  0x7aa5dfdf,
+    0x8f038c8c, 0xf859a1a1,  0x80098989,  0x171a0d0d,
+    0xda65bfbf, 0x31d7e6e6,  0xc6844242,  0xb8d06868,
+    0xc3824141, 0xb0299999,  0x775a2d2d,  0x111e0f0f,
+    0xcb7bb0b0, 0xfca85454,  0xd66dbbbb,  0x3a2c1616,
 };
+/* clang-format on */
 
-static uint32_t T2[256] = {
-  0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 
-  0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5, 
-  0x30506030, 0x1030201, 0x67a9ce67, 0x2b7d562b, 
-  0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 
-  0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 
-  0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0, 
-  0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 
-  0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0, 
-  0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 
-  0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 
-  0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 
-  0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15, 
-  0x40c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 
-  0x18283018, 0x96a13796, 0x50f0a05, 0x9ab52f9a, 
-  0x7090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 
-  0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 
-  0x91b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 
-  0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0, 
-  0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 
-  0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384, 
-  0x53f5a653, 0xd168b9d1, 0x0, 0xed2cc1ed, 
-  0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 
-  0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 
-  0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf, 
-  0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 
-  0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185, 
-  0x45cf8a45, 0xf910e9f9, 0x2060402, 0x7f81fe7f, 
-  0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 
-  0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 
-  0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5, 
-  0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 
-  0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2, 
-  0xcd4c81cd, 0xc14180c, 0x13352613, 0xec2fc3ec, 
-  0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 
-  0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 
-  0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673, 
-  0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 
-  0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88, 
-  0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 
-  0xde79a7de, 0x5ee2bc5e, 0xb1d160b, 0xdb76addb, 
-  0xe03bdbe0, 0x32566432, 0x3a4e743a, 0xa1e140a, 
-  0x49db9249, 0x60a0c06, 0x246c4824, 0x5ce4b85c, 
-  0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 
-  0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279, 
-  0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 
-  0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 
-  0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 
-  0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x8181008, 
-  0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 
-  0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6, 
-  0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 
-  0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 
-  0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 
-  0x48d89048, 0x3050603, 0xf601f7f6, 0xe121c0e, 
-  0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 
-  0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e, 
-  0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 
-  0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 
-  0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 
-  0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df, 
-  0x8c8f038c, 0xa1f859a1, 0x89800989, 0xd171a0d, 
-  0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068, 
-  0x41c38241, 0x99b02999, 0x2d775a2d, 0xf111e0f, 
-  0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16, 
+/* clang-format off */
+static const uint32_t T2[256] = {
+    0x63a5c663, 0x7c84f87c,  0x7799ee77,  0x7b8df67b,
+    0xf20dfff2, 0x6bbdd66b,  0x6fb1de6f,  0xc55491c5,
+    0x30506030, 0x1030201,   0x67a9ce67,  0x2b7d562b,
+    0xfe19e7fe, 0xd762b5d7,  0xabe64dab,  0x769aec76,
+    0xca458fca, 0x829d1f82,  0xc94089c9,  0x7d87fa7d,
+    0xfa15effa, 0x59ebb259,  0x47c98e47,  0xf00bfbf0,
+    0xadec41ad, 0xd467b3d4,  0xa2fd5fa2,  0xafea45af,
+    0x9cbf239c, 0xa4f753a4,  0x7296e472,  0xc05b9bc0,
+    0xb7c275b7, 0xfd1ce1fd,  0x93ae3d93,  0x266a4c26,
+    0x365a6c36, 0x3f417e3f,  0xf702f5f7,  0xcc4f83cc,
+    0x345c6834, 0xa5f451a5,  0xe534d1e5,  0xf108f9f1,
+    0x7193e271, 0xd873abd8,  0x31536231,  0x153f2a15,
+    0x40c0804,  0xc75295c7,  0x23654623,  0xc35e9dc3,
+    0x18283018, 0x96a13796,  0x50f0a05,   0x9ab52f9a,
+    0x7090e07,  0x12362412,  0x809b1b80,  0xe23ddfe2,
+    0xeb26cdeb, 0x27694e27,  0xb2cd7fb2,  0x759fea75,
+    0x91b1209,  0x839e1d83,  0x2c74582c,  0x1a2e341a,
+    0x1b2d361b, 0x6eb2dc6e,  0x5aeeb45a,  0xa0fb5ba0,
+    0x52f6a452, 0x3b4d763b,  0xd661b7d6,  0xb3ce7db3,
+    0x297b5229, 0xe33edde3,  0x2f715e2f,  0x84971384,
+    0x53f5a653, 0xd168b9d1,  0x0,         0xed2cc1ed,
+    0x20604020, 0xfc1fe3fc,  0xb1c879b1,  0x5bedb65b,
+    0x6abed46a, 0xcb468dcb,  0xbed967be,  0x394b7239,
+    0x4ade944a, 0x4cd4984c,  0x58e8b058,  0xcf4a85cf,
+    0xd06bbbd0, 0xef2ac5ef,  0xaae54faa,  0xfb16edfb,
+    0x43c58643, 0x4dd79a4d,  0x33556633,  0x85941185,
+    0x45cf8a45, 0xf910e9f9,  0x2060402,   0x7f81fe7f,
+    0x50f0a050, 0x3c44783c,  0x9fba259f,  0xa8e34ba8,
+    0x51f3a251, 0xa3fe5da3,  0x40c08040,  0x8f8a058f,
+    0x92ad3f92, 0x9dbc219d,  0x38487038,  0xf504f1f5,
+    0xbcdf63bc, 0xb6c177b6,  0xda75afda,  0x21634221,
+    0x10302010, 0xff1ae5ff,  0xf30efdf3,  0xd26dbfd2,
+    0xcd4c81cd, 0xc14180c,   0x13352613,  0xec2fc3ec,
+    0x5fe1be5f, 0x97a23597,  0x44cc8844,  0x17392e17,
+    0xc45793c4, 0xa7f255a7,  0x7e82fc7e,  0x3d477a3d,
+    0x64acc864, 0x5de7ba5d,  0x192b3219,  0x7395e673,
+    0x60a0c060, 0x81981981,  0x4fd19e4f,  0xdc7fa3dc,
+    0x22664422, 0x2a7e542a,  0x90ab3b90,  0x88830b88,
+    0x46ca8c46, 0xee29c7ee,  0xb8d36bb8,  0x143c2814,
+    0xde79a7de, 0x5ee2bc5e,  0xb1d160b,   0xdb76addb,
+    0xe03bdbe0, 0x32566432,  0x3a4e743a,  0xa1e140a,
+    0x49db9249, 0x60a0c06,   0x246c4824,  0x5ce4b85c,
+    0xc25d9fc2, 0xd36ebdd3,  0xacef43ac,  0x62a6c462,
+    0x91a83991, 0x95a43195,  0xe437d3e4,  0x798bf279,
+    0xe732d5e7, 0xc8438bc8,  0x37596e37,  0x6db7da6d,
+    0x8d8c018d, 0xd564b1d5,  0x4ed29c4e,  0xa9e049a9,
+    0x6cb4d86c, 0x56faac56,  0xf407f3f4,  0xea25cfea,
+    0x65afca65, 0x7a8ef47a,  0xaee947ae,  0x8181008,
+    0xbad56fba, 0x7888f078,  0x256f4a25,  0x2e725c2e,
+    0x1c24381c, 0xa6f157a6,  0xb4c773b4,  0xc65197c6,
+    0xe823cbe8, 0xdd7ca1dd,  0x749ce874,  0x1f213e1f,
+    0x4bdd964b, 0xbddc61bd,  0x8b860d8b,  0x8a850f8a,
+    0x7090e070, 0x3e427c3e,  0xb5c471b5,  0x66aacc66,
+    0x48d89048, 0x3050603,   0xf601f7f6,  0xe121c0e,
+    0x61a3c261, 0x355f6a35,  0x57f9ae57,  0xb9d069b9,
+    0x86911786, 0xc15899c1,  0x1d273a1d,  0x9eb9279e,
+    0xe138d9e1, 0xf813ebf8,  0x98b32b98,  0x11332211,
+    0x69bbd269, 0xd970a9d9,  0x8e89078e,  0x94a73394,
+    0x9bb62d9b, 0x1e223c1e,  0x87921587,  0xe920c9e9,
+    0xce4987ce, 0x55ffaa55,  0x28785028,  0xdf7aa5df,
+    0x8c8f038c, 0xa1f859a1,  0x89800989,  0xd171a0d,
+    0xbfda65bf, 0xe631d7e6,  0x42c68442,  0x68b8d068,
+    0x41c38241, 0x99b02999,  0x2d775a2d,  0xf111e0f,
+    0xb0cb7bb0, 0x54fca854,  0xbbd66dbb,  0x163a2c16,
 };
+/* clang-format on */
 
-static uint32_t T3[256] = {
-  0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 
-  0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491, 
-  0x30305060, 0x1010302, 0x6767a9ce, 0x2b2b7d56, 
-  0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 
-  0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 
-  0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb, 
-  0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 
-  0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b, 
-  0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 
-  0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 
-  0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 
-  0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a, 
-  0x4040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 
-  0x18182830, 0x9696a137, 0x5050f0a, 0x9a9ab52f, 
-  0x707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 
-  0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 
-  0x9091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 
-  0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b, 
-  0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 
-  0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713, 
-  0x5353f5a6, 0xd1d168b9, 0x0, 0xeded2cc1, 
-  0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 
-  0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 
-  0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85, 
-  0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 
-  0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411, 
-  0x4545cf8a, 0xf9f910e9, 0x2020604, 0x7f7f81fe, 
-  0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 
-  0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 
-  0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1, 
-  0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 
-  0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf, 
-  0xcdcd4c81, 0xc0c1418, 0x13133526, 0xecec2fc3, 
-  0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 
-  0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 
-  0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6, 
-  0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 
-  0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b, 
-  0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 
-  0xdede79a7, 0x5e5ee2bc, 0xb0b1d16, 0xdbdb76ad, 
-  0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0xa0a1e14, 
-  0x4949db92, 0x6060a0c, 0x24246c48, 0x5c5ce4b8, 
-  0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 
-  0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2, 
-  0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 
-  0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 
-  0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 
-  0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x8081810, 
-  0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 
-  0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197, 
-  0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 
-  0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 
-  0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 
-  0x4848d890, 0x3030506, 0xf6f601f7, 0xe0e121c, 
-  0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 
-  0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927, 
-  0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 
-  0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 
-  0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 
-  0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5, 
-  0x8c8c8f03, 0xa1a1f859, 0x89898009, 0xd0d171a, 
-  0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0, 
-  0x4141c382, 0x9999b029, 0x2d2d775a, 0xf0f111e, 
-  0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c, 
+/* clang-format off */
+static const uint32_t T3[256] = {
+    0x6363a5c6, 0x7c7c84f8,  0x777799ee,  0x7b7b8df6,
+    0xf2f20dff, 0x6b6bbdd6,  0x6f6fb1de,  0xc5c55491,
+    0x30305060, 0x1010302,   0x6767a9ce,  0x2b2b7d56,
+    0xfefe19e7, 0xd7d762b5,  0xababe64d,  0x76769aec,
+    0xcaca458f, 0x82829d1f,  0xc9c94089,  0x7d7d87fa,
+    0xfafa15ef, 0x5959ebb2,  0x4747c98e,  0xf0f00bfb,
+    0xadadec41, 0xd4d467b3,  0xa2a2fd5f,  0xafafea45,
+    0x9c9cbf23, 0xa4a4f753,  0x727296e4,  0xc0c05b9b,
+    0xb7b7c275, 0xfdfd1ce1,  0x9393ae3d,  0x26266a4c,
+    0x36365a6c, 0x3f3f417e,  0xf7f702f5,  0xcccc4f83,
+    0x34345c68, 0xa5a5f451,  0xe5e534d1,  0xf1f108f9,
+    0x717193e2, 0xd8d873ab,  0x31315362,  0x15153f2a,
+    0x4040c08,  0xc7c75295,  0x23236546,  0xc3c35e9d,
+    0x18182830, 0x9696a137,  0x5050f0a,   0x9a9ab52f,
+    0x707090e,  0x12123624,  0x80809b1b,  0xe2e23ddf,
+    0xebeb26cd, 0x2727694e,  0xb2b2cd7f,  0x75759fea,
+    0x9091b12,  0x83839e1d,  0x2c2c7458,  0x1a1a2e34,
+    0x1b1b2d36, 0x6e6eb2dc,  0x5a5aeeb4,  0xa0a0fb5b,
+    0x5252f6a4, 0x3b3b4d76,  0xd6d661b7,  0xb3b3ce7d,
+    0x29297b52, 0xe3e33edd,  0x2f2f715e,  0x84849713,
+    0x5353f5a6, 0xd1d168b9,  0x0,         0xeded2cc1,
+    0x20206040, 0xfcfc1fe3,  0xb1b1c879,  0x5b5bedb6,
+    0x6a6abed4, 0xcbcb468d,  0xbebed967,  0x39394b72,
+    0x4a4ade94, 0x4c4cd498,  0x5858e8b0,  0xcfcf4a85,
+    0xd0d06bbb, 0xefef2ac5,  0xaaaae54f,  0xfbfb16ed,
+    0x4343c586, 0x4d4dd79a,  0x33335566,  0x85859411,
+    0x4545cf8a, 0xf9f910e9,  0x2020604,   0x7f7f81fe,
+    0x5050f0a0, 0x3c3c4478,  0x9f9fba25,  0xa8a8e34b,
+    0x5151f3a2, 0xa3a3fe5d,  0x4040c080,  0x8f8f8a05,
+    0x9292ad3f, 0x9d9dbc21,  0x38384870,  0xf5f504f1,
+    0xbcbcdf63, 0xb6b6c177,  0xdada75af,  0x21216342,
+    0x10103020, 0xffff1ae5,  0xf3f30efd,  0xd2d26dbf,
+    0xcdcd4c81, 0xc0c1418,   0x13133526,  0xecec2fc3,
+    0x5f5fe1be, 0x9797a235,  0x4444cc88,  0x1717392e,
+    0xc4c45793, 0xa7a7f255,  0x7e7e82fc,  0x3d3d477a,
+    0x6464acc8, 0x5d5de7ba,  0x19192b32,  0x737395e6,
+    0x6060a0c0, 0x81819819,  0x4f4fd19e,  0xdcdc7fa3,
+    0x22226644, 0x2a2a7e54,  0x9090ab3b,  0x8888830b,
+    0x4646ca8c, 0xeeee29c7,  0xb8b8d36b,  0x14143c28,
+    0xdede79a7, 0x5e5ee2bc,  0xb0b1d16,   0xdbdb76ad,
+    0xe0e03bdb, 0x32325664,  0x3a3a4e74,  0xa0a1e14,
+    0x4949db92, 0x6060a0c,   0x24246c48,  0x5c5ce4b8,
+    0xc2c25d9f, 0xd3d36ebd,  0xacacef43,  0x6262a6c4,
+    0x9191a839, 0x9595a431,  0xe4e437d3,  0x79798bf2,
+    0xe7e732d5, 0xc8c8438b,  0x3737596e,  0x6d6db7da,
+    0x8d8d8c01, 0xd5d564b1,  0x4e4ed29c,  0xa9a9e049,
+    0x6c6cb4d8, 0x5656faac,  0xf4f407f3,  0xeaea25cf,
+    0x6565afca, 0x7a7a8ef4,  0xaeaee947,  0x8081810,
+    0xbabad56f, 0x787888f0,  0x25256f4a,  0x2e2e725c,
+    0x1c1c2438, 0xa6a6f157,  0xb4b4c773,  0xc6c65197,
+    0xe8e823cb, 0xdddd7ca1,  0x74749ce8,  0x1f1f213e,
+    0x4b4bdd96, 0xbdbddc61,  0x8b8b860d,  0x8a8a850f,
+    0x707090e0, 0x3e3e427c,  0xb5b5c471,  0x6666aacc,
+    0x4848d890, 0x3030506,   0xf6f601f7,  0xe0e121c,
+    0x6161a3c2, 0x35355f6a,  0x5757f9ae,  0xb9b9d069,
+    0x86869117, 0xc1c15899,  0x1d1d273a,  0x9e9eb927,
+    0xe1e138d9, 0xf8f813eb,  0x9898b32b,  0x11113322,
+    0x6969bbd2, 0xd9d970a9,  0x8e8e8907,  0x9494a733,
+    0x9b9bb62d, 0x1e1e223c,  0x87879215,  0xe9e920c9,
+    0xcece4987, 0x5555ffaa,  0x28287850,  0xdfdf7aa5,
+    0x8c8c8f03, 0xa1a1f859,  0x89898009,  0xd0d171a,
+    0xbfbfda65, 0xe6e631d7,  0x4242c684,  0x6868b8d0,
+    0x4141c382, 0x9999b029,  0x2d2d775a,  0xf0f111e,
+    0xb0b0cb7b, 0x5454fca8,  0xbbbbd66d,  0x16163a2c,
 };
+/* clang-format on */
 
-static uint32_t U0[256] = {
-  0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 
-  0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, 
-  0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 
-  0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 
-  0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 
-  0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, 
-  0x38f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 
-  0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, 
-  0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 
-  0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 
-  0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 
-  0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, 
-  0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 
-  0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, 
-  0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 
-  0x302887f2, 0x23bfa5b2, 0x2036aba, 0xed16825c, 
-  0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 
-  0x65daf4cd, 0x605bed5, 0xd134621f, 0xc4a6fe8a, 
-  0x342e539d, 0xa2f355a0, 0x58ae132, 0xa4f6eb75, 
-  0xb83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, 
-  0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 
-  0x91548db5, 0x71c45d05, 0x406d46f, 0x605015ff, 
-  0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 
-  0xb0e842bd, 0x7898b88, 0xe7195b38, 0x79c8eedb, 
-  0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x0, 
-  0x9808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, 
-  0xfd0efffb, 0xf853856, 0x3daed51e, 0x362d3927, 
-  0xa0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 
-  0xc0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 
-  0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, 
-  0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 
-  0xe090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, 
-  0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 
-  0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 
-  0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 
-  0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, 
-  0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 
-  0x1d9e2f4b, 0xdcb230f3, 0xd8652ec, 0x77c1e3d0, 
-  0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 
-  0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 
-  0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 
-  0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, 
-  0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 
-  0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, 
-  0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 
-  0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 
-  0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 
-  0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, 
-  0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 
-  0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, 
-  0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 
-  0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 
-  0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 
-  0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, 
-  0x9d5eea04, 0x18c355d, 0xfa877473, 0xfb0b412e, 
-  0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, 
-  0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 
-  0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 
-  0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 
-  0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, 
-  0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 
-  0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, 
-  0x39a80171, 0x80cb3de, 0xd8b4e49c, 0x6456c190, 
-  0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+/* clang-format off */
+static const uint32_t U0[256] = {
+    0x51f4a750, 0x7e416553,  0x1a17a4c3,  0x3a275e96,
+    0x3bab6bcb, 0x1f9d45f1,  0xacfa58ab,  0x4be30393,
+    0x2030fa55, 0xad766df6,  0x88cc7691,  0xf5024c25,
+    0x4fe5d7fc, 0xc52acbd7,  0x26354480,  0xb562a38f,
+    0xdeb15a49, 0x25ba1b67,  0x45ea0e98,  0x5dfec0e1,
+    0xc32f7502, 0x814cf012,  0x8d4697a3,  0x6bd3f9c6,
+    0x38f5fe7,  0x15929c95,  0xbf6d7aeb,  0x955259da,
+    0xd4be832d, 0x587421d3,  0x49e06929,  0x8ec9c844,
+    0x75c2896a, 0xf48e7978,  0x99583e6b,  0x27b971dd,
+    0xbee14fb6, 0xf088ad17,  0xc920ac66,  0x7dce3ab4,
+    0x63df4a18, 0xe51a3182,  0x97513360,  0x62537f45,
+    0xb16477e0, 0xbb6bae84,  0xfe81a01c,  0xf9082b94,
+    0x70486858, 0x8f45fd19,  0x94de6c87,  0x527bf8b7,
+    0xab73d323, 0x724b02e2,  0xe31f8f57,  0x6655ab2a,
+    0xb2eb2807, 0x2fb5c203,  0x86c57b9a,  0xd33708a5,
+    0x302887f2, 0x23bfa5b2,  0x2036aba,   0xed16825c,
+    0x8acf1c2b, 0xa779b492,  0xf307f2f0,  0x4e69e2a1,
+    0x65daf4cd, 0x605bed5,   0xd134621f,  0xc4a6fe8a,
+    0x342e539d, 0xa2f355a0,  0x58ae132,   0xa4f6eb75,
+    0xb83ec39,  0x4060efaa,  0x5e719f06,  0xbd6e1051,
+    0x3e218af9, 0x96dd063d,  0xdd3e05ae,  0x4de6bd46,
+    0x91548db5, 0x71c45d05,  0x406d46f,   0x605015ff,
+    0x1998fb24, 0xd6bde997,  0x894043cc,  0x67d99e77,
+    0xb0e842bd, 0x7898b88,   0xe7195b38,  0x79c8eedb,
+    0xa17c0a47, 0x7c420fe9,  0xf8841ec9,  0x0,
+    0x9808683,  0x322bed48,  0x1e1170ac,  0x6c5a724e,
+    0xfd0efffb, 0xf853856,   0x3daed51e,  0x362d3927,
+    0xa0fd964,  0x685ca621,  0x9b5b54d1,  0x24362e3a,
+    0xc0a67b1,  0x9357e70f,  0xb4ee96d2,  0x1b9b919e,
+    0x80c0c54f, 0x61dc20a2,  0x5a774b69,  0x1c121a16,
+    0xe293ba0a, 0xc0a02ae5,  0x3c22e043,  0x121b171d,
+    0xe090d0b,  0xf28bc7ad,  0x2db6a8b9,  0x141ea9c8,
+    0x57f11985, 0xaf75074c,  0xee99ddbb,  0xa37f60fd,
+    0xf701269f, 0x5c72f5bc,  0x44663bc5,  0x5bfb7e34,
+    0x8b432976, 0xcb23c6dc,  0xb6edfc68,  0xb8e4f163,
+    0xd731dcca, 0x42638510,  0x13972240,  0x84c61120,
+    0x854a247d, 0xd2bb3df8,  0xaef93211,  0xc729a16d,
+    0x1d9e2f4b, 0xdcb230f3,  0xd8652ec,   0x77c1e3d0,
+    0x2bb3166c, 0xa970b999,  0x119448fa,  0x47e96422,
+    0xa8fc8cc4, 0xa0f03f1a,  0x567d2cd8,  0x223390ef,
+    0x87494ec7, 0xd938d1c1,  0x8ccaa2fe,  0x98d40b36,
+    0xa6f581cf, 0xa57ade28,  0xdab78e26,  0x3fadbfa4,
+    0x2c3a9de4, 0x5078920d,  0x6a5fcc9b,  0x547e4662,
+    0xf68d13c2, 0x90d8b8e8,  0x2e39f75e,  0x82c3aff5,
+    0x9f5d80be, 0x69d0937c,  0x6fd52da9,  0xcf2512b3,
+    0xc8ac993b, 0x10187da7,  0xe89c636e,  0xdb3bbb7b,
+    0xcd267809, 0x6e5918f4,  0xec9ab701,  0x834f9aa8,
+    0xe6956e65, 0xaaffe67e,  0x21bccf08,  0xef15e8e6,
+    0xbae79bd9, 0x4a6f36ce,  0xea9f09d4,  0x29b07cd6,
+    0x31a4b2af, 0x2a3f2331,  0xc6a59430,  0x35a266c0,
+    0x744ebc37, 0xfc82caa6,  0xe090d0b0,  0x33a7d815,
+    0xf104984a, 0x41ecdaf7,  0x7fcd500e,  0x1791f62f,
+    0x764dd68d, 0x43efb04d,  0xccaa4d54,  0xe49604df,
+    0x9ed1b5e3, 0x4c6a881b,  0xc12c1fb8,  0x4665517f,
+    0x9d5eea04, 0x18c355d,   0xfa877473,  0xfb0b412e,
+    0xb3671d5a, 0x92dbd252,  0xe9105633,  0x6dd64713,
+    0x9ad7618c, 0x37a10c7a,  0x59f8148e,  0xeb133c89,
+    0xcea927ee, 0xb761c935,  0xe11ce5ed,  0x7a47b13c,
+    0x9cd2df59, 0x55f2733f,  0x1814ce79,  0x73c737bf,
+    0x53f7cdea, 0x5ffdaa5b,  0xdf3d6f14,  0x7844db86,
+    0xcaaff381, 0xb968c43e,  0x3824342c,  0xc2a3405f,
+    0x161dc372, 0xbce2250c,  0x283c498b,  0xff0d9541,
+    0x39a80171, 0x80cb3de,   0xd8b4e49c,  0x6456c190,
+    0x7bcb8461, 0xd532b670,  0x486c5c74,  0xd0b85742
 };
+/* clang-format on */
 
-static uint32_t U1[256] = {
-  0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 
-  0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303, 
-  0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 
-  0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 
-  0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 
-  0x2c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9, 
-  0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 
-  0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8, 
-  0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 
-  0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 
-  0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 
-  0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b, 
-  0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 
-  0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab, 
-  0x7b2eb28, 0x32fb5c2, 0x9a86c57b, 0xa5d33708, 
-  0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 
-  0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 
-  0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe, 
-  0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 
-  0x390b83ec, 0xaa4060ef, 0x65e719f, 0x51bd6e10, 
-  0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 
-  0xb591548d, 0x571c45d, 0x6f0406d4, 0xff605015, 
-  0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 
-  0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee, 
-  0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x0, 
-  0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72, 
-  0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 
-  0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 
-  0xb10c0a67, 0xf9357e7, 0xd2b4ee96, 0x9e1b9b91, 
-  0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a, 
-  0xae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 
-  0xb0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9, 
-  0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 
-  0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 
-  0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 
-  0xcad731dc, 0x10426385, 0x40139722, 0x2084c611, 
-  0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 
-  0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3, 
-  0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 
-  0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 
-  0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 
-  0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf, 
-  0xe42c3a9d, 0xd507892, 0x9b6a5fcc, 0x62547e46, 
-  0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af, 
-  0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 
-  0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 
-  0x9cd2678, 0xf46e5918, 0x1ec9ab7, 0xa8834f9a, 
-  0x65e6956e, 0x7eaaffe6, 0x821bccf, 0xe6ef15e8, 
-  0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 
-  0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266, 
-  0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 
-  0x4af10498, 0xf741ecda, 0xe7fcd50, 0x2f1791f6, 
-  0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 
-  0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551, 
-  0x49d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 
-  0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647, 
-  0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 
-  0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 
-  0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 
-  0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db, 
-  0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 
-  0x72161dc3, 0xcbce225, 0x8b283c49, 0x41ff0d95, 
-  0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 
-  0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857
+/* clang-format off */
+static const uint32_t U1[256] = {
+    0x5051f4a7, 0x537e4165,  0xc31a17a4,  0x963a275e,
+    0xcb3bab6b, 0xf11f9d45,  0xabacfa58,  0x934be303,
+    0x552030fa, 0xf6ad766d,  0x9188cc76,  0x25f5024c,
+    0xfc4fe5d7, 0xd7c52acb,  0x80263544,  0x8fb562a3,
+    0x49deb15a, 0x6725ba1b,  0x9845ea0e,  0xe15dfec0,
+    0x2c32f75,  0x12814cf0,  0xa38d4697,  0xc66bd3f9,
+    0xe7038f5f, 0x9515929c,  0xebbf6d7a,  0xda955259,
+    0x2dd4be83, 0xd3587421,  0x2949e069,  0x448ec9c8,
+    0x6a75c289, 0x78f48e79,  0x6b99583e,  0xdd27b971,
+    0xb6bee14f, 0x17f088ad,  0x66c920ac,  0xb47dce3a,
+    0x1863df4a, 0x82e51a31,  0x60975133,  0x4562537f,
+    0xe0b16477, 0x84bb6bae,  0x1cfe81a0,  0x94f9082b,
+    0x58704868, 0x198f45fd,  0x8794de6c,  0xb7527bf8,
+    0x23ab73d3, 0xe2724b02,  0x57e31f8f,  0x2a6655ab,
+    0x7b2eb28,  0x32fb5c2,   0x9a86c57b,  0xa5d33708,
+    0xf2302887, 0xb223bfa5,  0xba02036a,  0x5ced1682,
+    0x2b8acf1c, 0x92a779b4,  0xf0f307f2,  0xa14e69e2,
+    0xcd65daf4, 0xd50605be,  0x1fd13462,  0x8ac4a6fe,
+    0x9d342e53, 0xa0a2f355,  0x32058ae1,  0x75a4f6eb,
+    0x390b83ec, 0xaa4060ef,  0x65e719f,   0x51bd6e10,
+    0xf93e218a, 0x3d96dd06,  0xaedd3e05,  0x464de6bd,
+    0xb591548d, 0x571c45d,   0x6f0406d4,  0xff605015,
+    0x241998fb, 0x97d6bde9,  0xcc894043,  0x7767d99e,
+    0xbdb0e842, 0x8807898b,  0x38e7195b,  0xdb79c8ee,
+    0x47a17c0a, 0xe97c420f,  0xc9f8841e,  0x0,
+    0x83098086, 0x48322bed,  0xac1e1170,  0x4e6c5a72,
+    0xfbfd0eff, 0x560f8538,  0x1e3daed5,  0x27362d39,
+    0x640a0fd9, 0x21685ca6,  0xd19b5b54,  0x3a24362e,
+    0xb10c0a67, 0xf9357e7,   0xd2b4ee96,  0x9e1b9b91,
+    0x4f80c0c5, 0xa261dc20,  0x695a774b,  0x161c121a,
+    0xae293ba,  0xe5c0a02a,  0x433c22e0,  0x1d121b17,
+    0xb0e090d,  0xadf28bc7,  0xb92db6a8,  0xc8141ea9,
+    0x8557f119, 0x4caf7507,  0xbbee99dd,  0xfda37f60,
+    0x9ff70126, 0xbc5c72f5,  0xc544663b,  0x345bfb7e,
+    0x768b4329, 0xdccb23c6,  0x68b6edfc,  0x63b8e4f1,
+    0xcad731dc, 0x10426385,  0x40139722,  0x2084c611,
+    0x7d854a24, 0xf8d2bb3d,  0x11aef932,  0x6dc729a1,
+    0x4b1d9e2f, 0xf3dcb230,  0xec0d8652,  0xd077c1e3,
+    0x6c2bb316, 0x99a970b9,  0xfa119448,  0x2247e964,
+    0xc4a8fc8c, 0x1aa0f03f,  0xd8567d2c,  0xef223390,
+    0xc787494e, 0xc1d938d1,  0xfe8ccaa2,  0x3698d40b,
+    0xcfa6f581, 0x28a57ade,  0x26dab78e,  0xa43fadbf,
+    0xe42c3a9d, 0xd507892,   0x9b6a5fcc,  0x62547e46,
+    0xc2f68d13, 0xe890d8b8,  0x5e2e39f7,  0xf582c3af,
+    0xbe9f5d80, 0x7c69d093,  0xa96fd52d,  0xb3cf2512,
+    0x3bc8ac99, 0xa710187d,  0x6ee89c63,  0x7bdb3bbb,
+    0x9cd2678,  0xf46e5918,  0x1ec9ab7,   0xa8834f9a,
+    0x65e6956e, 0x7eaaffe6,  0x821bccf,   0xe6ef15e8,
+    0xd9bae79b, 0xce4a6f36,  0xd4ea9f09,  0xd629b07c,
+    0xaf31a4b2, 0x312a3f23,  0x30c6a594,  0xc035a266,
+    0x37744ebc, 0xa6fc82ca,  0xb0e090d0,  0x1533a7d8,
+    0x4af10498, 0xf741ecda,  0xe7fcd50,   0x2f1791f6,
+    0x8d764dd6, 0x4d43efb0,  0x54ccaa4d,  0xdfe49604,
+    0xe39ed1b5, 0x1b4c6a88,  0xb8c12c1f,  0x7f466551,
+    0x49d5eea,  0x5d018c35,  0x73fa8774,  0x2efb0b41,
+    0x5ab3671d, 0x5292dbd2,  0x33e91056,  0x136dd647,
+    0x8c9ad761, 0x7a37a10c,  0x8e59f814,  0x89eb133c,
+    0xeecea927, 0x35b761c9,  0xede11ce5,  0x3c7a47b1,
+    0x599cd2df, 0x3f55f273,  0x791814ce,  0xbf73c737,
+    0xea53f7cd, 0x5b5ffdaa,  0x14df3d6f,  0x867844db,
+    0x81caaff3, 0x3eb968c4,  0x2c382434,  0x5fc2a340,
+    0x72161dc3, 0xcbce225,   0x8b283c49,  0x41ff0d95,
+    0x7139a801, 0xde080cb3,  0x9cd8b4e4,  0x906456c1,
+    0x617bcb84, 0x70d532b6,  0x74486c5c,  0x42d0b857
 };
+/* clang-format on */
 
-static uint32_t U2[256] = {
-  0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 
-  0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x3934be3, 
-  0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 
-  0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 
-  0x5a49deb1, 0x1b6725ba, 0xe9845ea, 0xc0e15dfe, 
-  0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3, 
-  0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 
-  0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9, 
-  0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 
-  0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 
-  0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 
-  0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908, 
-  0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 
-  0xd323ab73, 0x2e2724b, 0x8f57e31f, 0xab2a6655, 
-  0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x8a5d337, 
-  0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 
-  0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 
-  0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6, 
-  0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 
-  0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e, 
-  0x8af93e21, 0x63d96dd, 0x5aedd3e, 0xbd464de6, 
-  0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 
-  0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 
-  0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8, 
-  0xa47a17c, 0xfe97c42, 0x1ec9f884, 0x0, 
-  0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a, 
-  0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 
-  0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 
-  0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 
-  0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12, 
-  0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 
-  0xd0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e, 
-  0x198557f1, 0x74caf75, 0xddbbee99, 0x60fda37f, 
-  0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 
-  0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 
-  0xdccad731, 0x85104263, 0x22401397, 0x112084c6, 
-  0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 
-  0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1, 
-  0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 
-  0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 
-  0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0xb3698d4, 
-  0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad, 
-  0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 
-  0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3, 
-  0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 
-  0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 
-  0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 
-  0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15, 
-  0x9bd9bae7, 0x36ce4a6f, 0x9d4ea9f, 0x7cd629b0, 
-  0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2, 
-  0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 
-  0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 
-  0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x4dfe496, 
-  0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665, 
-  0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 
-  0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6, 
-  0x618c9ad7, 0xc7a37a1, 0x148e59f8, 0x3c89eb13, 
-  0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 
-  0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 
-  0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844, 
-  0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 
-  0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d, 
-  0x17139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 
-  0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8 
+/* clang-format off */
+static const uint32_t U2[256] = {
+    0xa75051f4, 0x65537e41,  0xa4c31a17,  0x5e963a27,
+    0x6bcb3bab, 0x45f11f9d,  0x58abacfa,  0x3934be3,
+    0xfa552030, 0x6df6ad76,  0x769188cc,  0x4c25f502,
+    0xd7fc4fe5, 0xcbd7c52a,  0x44802635,  0xa38fb562,
+    0x5a49deb1, 0x1b6725ba,  0xe9845ea,   0xc0e15dfe,
+    0x7502c32f, 0xf012814c,  0x97a38d46,  0xf9c66bd3,
+    0x5fe7038f, 0x9c951592,  0x7aebbf6d,  0x59da9552,
+    0x832dd4be, 0x21d35874,  0x692949e0,  0xc8448ec9,
+    0x896a75c2, 0x7978f48e,  0x3e6b9958,  0x71dd27b9,
+    0x4fb6bee1, 0xad17f088,  0xac66c920,  0x3ab47dce,
+    0x4a1863df, 0x3182e51a,  0x33609751,  0x7f456253,
+    0x77e0b164, 0xae84bb6b,  0xa01cfe81,  0x2b94f908,
+    0x68587048, 0xfd198f45,  0x6c8794de,  0xf8b7527b,
+    0xd323ab73, 0x2e2724b,   0x8f57e31f,  0xab2a6655,
+    0x2807b2eb, 0xc2032fb5,  0x7b9a86c5,  0x8a5d337,
+    0x87f23028, 0xa5b223bf,  0x6aba0203,  0x825ced16,
+    0x1c2b8acf, 0xb492a779,  0xf2f0f307,  0xe2a14e69,
+    0xf4cd65da, 0xbed50605,  0x621fd134,  0xfe8ac4a6,
+    0x539d342e, 0x55a0a2f3,  0xe132058a,  0xeb75a4f6,
+    0xec390b83, 0xefaa4060,  0x9f065e71,  0x1051bd6e,
+    0x8af93e21, 0x63d96dd,   0x5aedd3e,   0xbd464de6,
+    0x8db59154, 0x5d0571c4,  0xd46f0406,  0x15ff6050,
+    0xfb241998, 0xe997d6bd,  0x43cc8940,  0x9e7767d9,
+    0x42bdb0e8, 0x8b880789,  0x5b38e719,  0xeedb79c8,
+    0xa47a17c,  0xfe97c42,   0x1ec9f884,  0x0,
+    0x86830980, 0xed48322b,  0x70ac1e11,  0x724e6c5a,
+    0xfffbfd0e, 0x38560f85,  0xd51e3dae,  0x3927362d,
+    0xd9640a0f, 0xa621685c,  0x54d19b5b,  0x2e3a2436,
+    0x67b10c0a, 0xe70f9357,  0x96d2b4ee,  0x919e1b9b,
+    0xc54f80c0, 0x20a261dc,  0x4b695a77,  0x1a161c12,
+    0xba0ae293, 0x2ae5c0a0,  0xe0433c22,  0x171d121b,
+    0xd0b0e09,  0xc7adf28b,  0xa8b92db6,  0xa9c8141e,
+    0x198557f1, 0x74caf75,   0xddbbee99,  0x60fda37f,
+    0x269ff701, 0xf5bc5c72,  0x3bc54466,  0x7e345bfb,
+    0x29768b43, 0xc6dccb23,  0xfc68b6ed,  0xf163b8e4,
+    0xdccad731, 0x85104263,  0x22401397,  0x112084c6,
+    0x247d854a, 0x3df8d2bb,  0x3211aef9,  0xa16dc729,
+    0x2f4b1d9e, 0x30f3dcb2,  0x52ec0d86,  0xe3d077c1,
+    0x166c2bb3, 0xb999a970,  0x48fa1194,  0x642247e9,
+    0x8cc4a8fc, 0x3f1aa0f0,  0x2cd8567d,  0x90ef2233,
+    0x4ec78749, 0xd1c1d938,  0xa2fe8cca,  0xb3698d4,
+    0x81cfa6f5, 0xde28a57a,  0x8e26dab7,  0xbfa43fad,
+    0x9de42c3a, 0x920d5078,  0xcc9b6a5f,  0x4662547e,
+    0x13c2f68d, 0xb8e890d8,  0xf75e2e39,  0xaff582c3,
+    0x80be9f5d, 0x937c69d0,  0x2da96fd5,  0x12b3cf25,
+    0x993bc8ac, 0x7da71018,  0x636ee89c,  0xbb7bdb3b,
+    0x7809cd26, 0x18f46e59,  0xb701ec9a,  0x9aa8834f,
+    0x6e65e695, 0xe67eaaff,  0xcf0821bc,  0xe8e6ef15,
+    0x9bd9bae7, 0x36ce4a6f,  0x9d4ea9f,   0x7cd629b0,
+    0xb2af31a4, 0x23312a3f,  0x9430c6a5,  0x66c035a2,
+    0xbc37744e, 0xcaa6fc82,  0xd0b0e090,  0xd81533a7,
+    0x984af104, 0xdaf741ec,  0x500e7fcd,  0xf62f1791,
+    0xd68d764d, 0xb04d43ef,  0x4d54ccaa,  0x4dfe496,
+    0xb5e39ed1, 0x881b4c6a,  0x1fb8c12c,  0x517f4665,
+    0xea049d5e, 0x355d018c,  0x7473fa87,  0x412efb0b,
+    0x1d5ab367, 0xd25292db,  0x5633e910,  0x47136dd6,
+    0x618c9ad7, 0xc7a37a1,   0x148e59f8,  0x3c89eb13,
+    0x27eecea9, 0xc935b761,  0xe5ede11c,  0xb13c7a47,
+    0xdf599cd2, 0x733f55f2,  0xce791814,  0x37bf73c7,
+    0xcdea53f7, 0xaa5b5ffd,  0x6f14df3d,  0xdb867844,
+    0xf381caaf, 0xc43eb968,  0x342c3824,  0x405fc2a3,
+    0xc372161d, 0x250cbce2,  0x498b283c,  0x9541ff0d,
+    0x17139a8,  0xb3de080c,  0xe49cd8b4,  0xc1906456,
+    0x84617bcb, 0xb670d532,  0x5c74486c,  0x5742d0b8
 };
+/* clang-format on */
 
-static uint32_t U3[256] = {
-  0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 
-  0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 
-  0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5, 
-  0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 
-  0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 
-  0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 
-  0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 
-  0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 
-  0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 
-  0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 
-  0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 
-  0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9, 
-  0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 
-  0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 
-  0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 
-  0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced, 
-  0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e, 
-  0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4, 
-  0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 
-  0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 
-  0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 
-  0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60, 
-  0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 
-  0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 
-  0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0, 
-  0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 
-  0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 
-  0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 
-  0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 
-  0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 
-  0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 
-  0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 
-  0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 
-  0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 
-  0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 
-  0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 
-  0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 
-  0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 
-  0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 
-  0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 
-  0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 
-  0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 
-  0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 
-  0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 
-  0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 
-  0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 
-  0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 
-  0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 
-  0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 
-  0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 
-  0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 
-  0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 
-  0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 
-  0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 
-  0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb, 
-  0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 
-  0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 
-  0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 
-  0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 
-  0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 
-  0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 
-  0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff, 
-  0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064, 
-  0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0 
+/* clang-format off */
+static const uint32_t U3[256] = {
+    0xf4a75051, 0x4165537e,  0x17a4c31a,  0x275e963a,
+    0xab6bcb3b, 0x9d45f11f,  0xfa58abac,  0xe303934b,
+    0x30fa5520, 0x766df6ad,  0xcc769188,  0x24c25f5,
+    0xe5d7fc4f, 0x2acbd7c5,  0x35448026,  0x62a38fb5,
+    0xb15a49de, 0xba1b6725,  0xea0e9845,  0xfec0e15d,
+    0x2f7502c3, 0x4cf01281,  0x4697a38d,  0xd3f9c66b,
+    0x8f5fe703, 0x929c9515,  0x6d7aebbf,  0x5259da95,
+    0xbe832dd4, 0x7421d358,  0xe0692949,  0xc9c8448e,
+    0xc2896a75, 0x8e7978f4,  0x583e6b99,  0xb971dd27,
+    0xe14fb6be, 0x88ad17f0,  0x20ac66c9,  0xce3ab47d,
+    0xdf4a1863, 0x1a3182e5,  0x51336097,  0x537f4562,
+    0x6477e0b1, 0x6bae84bb,  0x81a01cfe,  0x82b94f9,
+    0x48685870, 0x45fd198f,  0xde6c8794,  0x7bf8b752,
+    0x73d323ab, 0x4b02e272,  0x1f8f57e3,  0x55ab2a66,
+    0xeb2807b2, 0xb5c2032f,  0xc57b9a86,  0x3708a5d3,
+    0x2887f230, 0xbfa5b223,  0x36aba02,   0x16825ced,
+    0xcf1c2b8a, 0x79b492a7,  0x7f2f0f3,   0x69e2a14e,
+    0xdaf4cd65, 0x5bed506,   0x34621fd1,  0xa6fe8ac4,
+    0x2e539d34, 0xf355a0a2,  0x8ae13205,  0xf6eb75a4,
+    0x83ec390b, 0x60efaa40,  0x719f065e,  0x6e1051bd,
+    0x218af93e, 0xdd063d96,  0x3e05aedd,  0xe6bd464d,
+    0x548db591, 0xc45d0571,  0x6d46f04,   0x5015ff60,
+    0x98fb2419, 0xbde997d6,  0x4043cc89,  0xd99e7767,
+    0xe842bdb0, 0x898b8807,  0x195b38e7,  0xc8eedb79,
+    0x7c0a47a1, 0x420fe97c,  0x841ec9f8,  0x0,
+    0x80868309, 0x2bed4832,  0x1170ac1e,  0x5a724e6c,
+    0xefffbfd,  0x8538560f,  0xaed51e3d,  0x2d392736,
+    0xfd9640a,  0x5ca62168,  0x5b54d19b,  0x362e3a24,
+    0xa67b10c,  0x57e70f93,  0xee96d2b4,  0x9b919e1b,
+    0xc0c54f80, 0xdc20a261,  0x774b695a,  0x121a161c,
+    0x93ba0ae2, 0xa02ae5c0,  0x22e0433c,  0x1b171d12,
+    0x90d0b0e,  0x8bc7adf2,  0xb6a8b92d,  0x1ea9c814,
+    0xf1198557, 0x75074caf,  0x99ddbbee,  0x7f60fda3,
+    0x1269ff7,  0x72f5bc5c,  0x663bc544,  0xfb7e345b,
+    0x4329768b, 0x23c6dccb,  0xedfc68b6,  0xe4f163b8,
+    0x31dccad7, 0x63851042,  0x97224013,  0xc6112084,
+    0x4a247d85, 0xbb3df8d2,  0xf93211ae,  0x29a16dc7,
+    0x9e2f4b1d, 0xb230f3dc,  0x8652ec0d,  0xc1e3d077,
+    0xb3166c2b, 0x70b999a9,  0x9448fa11,  0xe9642247,
+    0xfc8cc4a8, 0xf03f1aa0,  0x7d2cd856,  0x3390ef22,
+    0x494ec787, 0x38d1c1d9,  0xcaa2fe8c,  0xd40b3698,
+    0xf581cfa6, 0x7ade28a5,  0xb78e26da,  0xadbfa43f,
+    0x3a9de42c, 0x78920d50,  0x5fcc9b6a,  0x7e466254,
+    0x8d13c2f6, 0xd8b8e890,  0x39f75e2e,  0xc3aff582,
+    0x5d80be9f, 0xd0937c69,  0xd52da96f,  0x2512b3cf,
+    0xac993bc8, 0x187da710,  0x9c636ee8,  0x3bbb7bdb,
+    0x267809cd, 0x5918f46e,  0x9ab701ec,  0x4f9aa883,
+    0x956e65e6, 0xffe67eaa,  0xbccf0821,  0x15e8e6ef,
+    0xe79bd9ba, 0x6f36ce4a,  0x9f09d4ea,  0xb07cd629,
+    0xa4b2af31, 0x3f23312a,  0xa59430c6,  0xa266c035,
+    0x4ebc3774, 0x82caa6fc,  0x90d0b0e0,  0xa7d81533,
+    0x4984af1,  0xecdaf741,  0xcd500e7f,  0x91f62f17,
+    0x4dd68d76, 0xefb04d43,  0xaa4d54cc,  0x9604dfe4,
+    0xd1b5e39e, 0x6a881b4c,  0x2c1fb8c1,  0x65517f46,
+    0x5eea049d, 0x8c355d01,  0x877473fa,  0xb412efb,
+    0x671d5ab3, 0xdbd25292,  0x105633e9,  0xd647136d,
+    0xd7618c9a, 0xa10c7a37,  0xf8148e59,  0x133c89eb,
+    0xa927eece, 0x61c935b7,  0x1ce5ede1,  0x47b13c7a,
+    0xd2df599c, 0xf2733f55,  0x14ce7918,  0xc737bf73,
+    0xf7cdea53, 0xfdaa5b5f,  0x3d6f14df,  0x44db8678,
+    0xaff381ca, 0x68c43eb9,  0x24342c38,  0xa3405fc2,
+    0x1dc37216, 0xe2250cbc,  0x3c498b28,  0xd9541ff,
+    0xa8017139, 0xcb3de08,   0xb4e49cd8,  0x56c19064,
+    0xcb84617b, 0x32b670d5,  0x6c5c7448,  0xb85742d0
 };
-
+/* clang-format on */
 #endif
 
-/* 
+/*
  * the following tables (aes_sbox, aes_inv_sbox, T4, U4) are
- * endian-neutral 
+ * endian-neutral
  */
-
-static uint8_t
-aes_sbox[256] = {
-  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 
-  0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 
-  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 
-  0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 
-  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 
-  0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 
-  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 
-  0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 
-  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 
-  0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 
-  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 
-  0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 
-  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 
-  0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 
-  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 
-  0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 
-  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 
-  0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 
-  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 
-  0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 
-  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 
-  0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 
-  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 
-  0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 
-  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 
-  0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 
-  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 
-  0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 
-  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 
-  0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 
-  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 
-  0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 
+/* clang-format off */
+static const uint8_t aes_sbox[256] = {
+    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 };
+/* clang-format on */
 
 #ifndef CPU_RISC
-static uint8_t
-aes_inv_sbox[256] = {
-  0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 
-  0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
-  0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
-  0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
-  0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 
-  0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-  0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
-  0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
-  0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 
-  0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
-  0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 
-  0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-  0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 
-  0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
-  0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 
-  0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
-  0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 
-  0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-  0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 
-  0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
-  0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 
-  0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
-  0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 
-  0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-  0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 
-  0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
-  0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 
-  0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
-  0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 
-  0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 
-  0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+/* clang-format off */
+static const uint8_t aes_inv_sbox[256] = {
+    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
+    0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
+    0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
+    0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+    0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
+    0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
+    0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
+    0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
+    0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
+    0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
+    0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
+    0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
 };
+/* clang-format on */
 #endif /* ! CPU_RISC */
 
 #ifdef CPU_RISC
-static uint32_t
-T4[256] = { 
-  0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
-  0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5, 
-  0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b, 
-  0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676, 
-  0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d, 
-  0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
-  0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
-  0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
-  0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
-  0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
-  0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
-  0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
-  0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
-  0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
-  0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
-  0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
-  0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a, 
-  0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
-  0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
-  0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
-  0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
-  0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
-  0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
-  0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
-  0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
-  0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
-  0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
-  0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
-  0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
-  0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
-  0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
-  0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
-  0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
-  0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
-  0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
-  0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
-  0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
-  0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
-  0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414, 
-  0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb, 
-  0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
-  0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
-  0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262, 
-  0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
-  0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
-  0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9, 
-  0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
-  0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808, 
-  0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
-  0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
-  0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
-  0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
-  0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
-  0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
-  0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
-  0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
-  0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111, 
-  0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
-  0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
-  0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
-  0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
-  0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
-  0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
-  0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
+/* clang-format off */
+static const uint32_t T4[256] = {
+    0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
+    0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
+    0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
+    0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
+    0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
+    0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
+    0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
+    0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
+    0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
+    0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
+    0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
+    0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
+    0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
+    0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
+    0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
+    0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
+    0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
+    0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
+    0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
+    0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
+    0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
+    0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
+    0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
+    0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
+    0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
+    0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
+    0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
+    0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
+    0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
+    0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
+    0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
+    0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
+    0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
+    0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
+    0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
+    0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
+    0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
+    0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
+    0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
+    0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
+    0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
+    0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
+    0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
+    0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
+    0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
+    0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
+    0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
+    0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
+    0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
+    0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
+    0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
+    0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
+    0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
+    0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
+    0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
+    0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
+    0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
+    0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
+    0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
+    0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
+    0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
+    0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
+    0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
+    0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616
 };
+/* clang-format on */
 
-static uint32_t U4[256] = {
-  0x52525252, 0x9090909, 0x6a6a6a6a, 0xd5d5d5d5, 
-  0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838, 
-  0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e, 
-  0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb, 
-  0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282, 
-  0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787, 
-  0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444, 
-  0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb, 
-  0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232, 
-  0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d, 
-  0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0xb0b0b0b, 
-  0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e, 
-  0x8080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666, 
-  0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2, 
-  0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949, 
-  0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525, 
-  0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464, 
-  0x86868686, 0x68686868, 0x98989898, 0x16161616, 
-  0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc, 
-  0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292, 
-  0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050, 
-  0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada, 
-  0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757, 
-  0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484, 
-  0x90909090, 0xd8d8d8d8, 0xabababab, 0x0, 
-  0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0xa0a0a0a, 
-  0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x5050505, 
-  0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x6060606, 
-  0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f, 
-  0xcacacaca, 0x3f3f3f3f, 0xf0f0f0f, 0x2020202, 
-  0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x3030303, 
-  0x1010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b, 
-  0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141, 
-  0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea, 
-  0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece, 
-  0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373, 
-  0x96969696, 0xacacacac, 0x74747474, 0x22222222, 
-  0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585, 
-  0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8, 
-  0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e, 
-  0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171, 
-  0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989, 
-  0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0xe0e0e0e, 
-  0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b, 
-  0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b, 
-  0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020, 
-  0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe, 
-  0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4, 
-  0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333, 
-  0x88888888, 0x7070707, 0xc7c7c7c7, 0x31313131, 
-  0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959, 
-  0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f, 
-  0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9, 
-  0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0xd0d0d0d, 
-  0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f, 
-  0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef, 
-  0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d, 
-  0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0, 
-  0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c, 
-  0x83838383, 0x53535353, 0x99999999, 0x61616161, 
-  0x17171717, 0x2b2b2b2b, 0x4040404, 0x7e7e7e7e, 
-  0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626, 
-  0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363, 
-  0x55555555, 0x21212121, 0xc0c0c0c, 0x7d7d7d7d
+/* clang-format off */
+static const uint32_t U4[256] = {
+    0x52525252, 0x9090909,   0x6a6a6a6a,  0xd5d5d5d5,
+    0x30303030, 0x36363636,  0xa5a5a5a5,  0x38383838,
+    0xbfbfbfbf, 0x40404040,  0xa3a3a3a3,  0x9e9e9e9e,
+    0x81818181, 0xf3f3f3f3,  0xd7d7d7d7,  0xfbfbfbfb,
+    0x7c7c7c7c, 0xe3e3e3e3,  0x39393939,  0x82828282,
+    0x9b9b9b9b, 0x2f2f2f2f,  0xffffffff,  0x87878787,
+    0x34343434, 0x8e8e8e8e,  0x43434343,  0x44444444,
+    0xc4c4c4c4, 0xdededede,  0xe9e9e9e9,  0xcbcbcbcb,
+    0x54545454, 0x7b7b7b7b,  0x94949494,  0x32323232,
+    0xa6a6a6a6, 0xc2c2c2c2,  0x23232323,  0x3d3d3d3d,
+    0xeeeeeeee, 0x4c4c4c4c,  0x95959595,  0xb0b0b0b,
+    0x42424242, 0xfafafafa,  0xc3c3c3c3,  0x4e4e4e4e,
+    0x8080808,  0x2e2e2e2e,  0xa1a1a1a1,  0x66666666,
+    0x28282828, 0xd9d9d9d9,  0x24242424,  0xb2b2b2b2,
+    0x76767676, 0x5b5b5b5b,  0xa2a2a2a2,  0x49494949,
+    0x6d6d6d6d, 0x8b8b8b8b,  0xd1d1d1d1,  0x25252525,
+    0x72727272, 0xf8f8f8f8,  0xf6f6f6f6,  0x64646464,
+    0x86868686, 0x68686868,  0x98989898,  0x16161616,
+    0xd4d4d4d4, 0xa4a4a4a4,  0x5c5c5c5c,  0xcccccccc,
+    0x5d5d5d5d, 0x65656565,  0xb6b6b6b6,  0x92929292,
+    0x6c6c6c6c, 0x70707070,  0x48484848,  0x50505050,
+    0xfdfdfdfd, 0xedededed,  0xb9b9b9b9,  0xdadadada,
+    0x5e5e5e5e, 0x15151515,  0x46464646,  0x57575757,
+    0xa7a7a7a7, 0x8d8d8d8d,  0x9d9d9d9d,  0x84848484,
+    0x90909090, 0xd8d8d8d8,  0xabababab,  0x0,
+    0x8c8c8c8c, 0xbcbcbcbc,  0xd3d3d3d3,  0xa0a0a0a,
+    0xf7f7f7f7, 0xe4e4e4e4,  0x58585858,  0x5050505,
+    0xb8b8b8b8, 0xb3b3b3b3,  0x45454545,  0x6060606,
+    0xd0d0d0d0, 0x2c2c2c2c,  0x1e1e1e1e,  0x8f8f8f8f,
+    0xcacacaca, 0x3f3f3f3f,  0xf0f0f0f,   0x2020202,
+    0xc1c1c1c1, 0xafafafaf,  0xbdbdbdbd,  0x3030303,
+    0x1010101,  0x13131313,  0x8a8a8a8a,  0x6b6b6b6b,
+    0x3a3a3a3a, 0x91919191,  0x11111111,  0x41414141,
+    0x4f4f4f4f, 0x67676767,  0xdcdcdcdc,  0xeaeaeaea,
+    0x97979797, 0xf2f2f2f2,  0xcfcfcfcf,  0xcececece,
+    0xf0f0f0f0, 0xb4b4b4b4,  0xe6e6e6e6,  0x73737373,
+    0x96969696, 0xacacacac,  0x74747474,  0x22222222,
+    0xe7e7e7e7, 0xadadadad,  0x35353535,  0x85858585,
+    0xe2e2e2e2, 0xf9f9f9f9,  0x37373737,  0xe8e8e8e8,
+    0x1c1c1c1c, 0x75757575,  0xdfdfdfdf,  0x6e6e6e6e,
+    0x47474747, 0xf1f1f1f1,  0x1a1a1a1a,  0x71717171,
+    0x1d1d1d1d, 0x29292929,  0xc5c5c5c5,  0x89898989,
+    0x6f6f6f6f, 0xb7b7b7b7,  0x62626262,  0xe0e0e0e,
+    0xaaaaaaaa, 0x18181818,  0xbebebebe,  0x1b1b1b1b,
+    0xfcfcfcfc, 0x56565656,  0x3e3e3e3e,  0x4b4b4b4b,
+    0xc6c6c6c6, 0xd2d2d2d2,  0x79797979,  0x20202020,
+    0x9a9a9a9a, 0xdbdbdbdb,  0xc0c0c0c0,  0xfefefefe,
+    0x78787878, 0xcdcdcdcd,  0x5a5a5a5a,  0xf4f4f4f4,
+    0x1f1f1f1f, 0xdddddddd,  0xa8a8a8a8,  0x33333333,
+    0x88888888, 0x7070707,   0xc7c7c7c7,  0x31313131,
+    0xb1b1b1b1, 0x12121212,  0x10101010,  0x59595959,
+    0x27272727, 0x80808080,  0xecececec,  0x5f5f5f5f,
+    0x60606060, 0x51515151,  0x7f7f7f7f,  0xa9a9a9a9,
+    0x19191919, 0xb5b5b5b5,  0x4a4a4a4a,  0xd0d0d0d,
+    0x2d2d2d2d, 0xe5e5e5e5,  0x7a7a7a7a,  0x9f9f9f9f,
+    0x93939393, 0xc9c9c9c9,  0x9c9c9c9c,  0xefefefef,
+    0xa0a0a0a0, 0xe0e0e0e0,  0x3b3b3b3b,  0x4d4d4d4d,
+    0xaeaeaeae, 0x2a2a2a2a,  0xf5f5f5f5,  0xb0b0b0b0,
+    0xc8c8c8c8, 0xebebebeb,  0xbbbbbbbb,  0x3c3c3c3c,
+    0x83838383, 0x53535353,  0x99999999,  0x61616161,
+    0x17171717, 0x2b2b2b2b,  0x4040404,   0x7e7e7e7e,
+    0xbabababa, 0x77777777,  0xd6d6d6d6,  0x26262626,
+    0xe1e1e1e1, 0x69696969,  0x14141414,  0x63636363,
+    0x55555555, 0x21212121,  0xc0c0c0c,   0x7d7d7d7d
 };
+/* clang-format on */
 #endif /* CPU_RISC */
 
+#define gf2_8_field_polynomial 0x1B
+/*
+ * 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))
 
 /* aes internals */
 
-extern debug_module_t mod_aes_icm;
+static void aes_128_expand_encryption_key(const uint8_t *key,
+                                          srtp_aes_expanded_key_t *expanded_key)
+{
+    int i;
+    uint8_t rc;
 
-static void
-aes_128_expand_encryption_key(const uint8_t *key, 
-			      aes_expanded_key_t *expanded_key) {
-  int i;
-  gf2_8 rc;
+    /* initialize round constant */
+    rc = 1;
 
-  /* initialize round constant */
-  rc = 1;
+    expanded_key->num_rounds = 10;
 
-  expanded_key->num_rounds = 10;
-
-  v128_copy_octet_string(&expanded_key->round[0], key);
+    v128_copy_octet_string(&expanded_key->round[0], key);
 
 #if 0
-  debug_print(mod_aes_icm, 
-	      "expanded key[0]:  %s", v128_hex_string(&expanded_key->round[0])); 
+    debug_print(srtp_mod_aes_icm,
+                "expanded key[0]:  %s", v128_hex_string(&expanded_key->round[0]));
 #endif
 
-  /* loop over round keys */
-  for (i=1; i < 11; i++) {
-
-    /* munge first word of round key */
-    expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
-    expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
-    expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
-    expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
-
-    expanded_key->round[i].v32[0] ^=  expanded_key->round[i-1].v32[0];
+    /* loop over round keys */
+    for (i = 1; i < 11; i++) {
+        /* munge first word of round key */
+        expanded_key->round[i].v8[0] =
+            aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
+        expanded_key->round[i].v8[1] =
+            aes_sbox[expanded_key->round[i - 1].v8[14]];
+        expanded_key->round[i].v8[2] =
+            aes_sbox[expanded_key->round[i - 1].v8[15]];
+        expanded_key->round[i].v8[3] =
+            aes_sbox[expanded_key->round[i - 1].v8[12]];
 
-    /* set remaining 32 bit words to the exor of the one previous with
-     * the one four words previous */
+        expanded_key->round[i].v32[0] ^= expanded_key->round[i - 1].v32[0];
 
-    expanded_key->round[i].v32[1] =
-      expanded_key->round[i].v32[0] ^ expanded_key->round[i-1].v32[1];
+        /* set remaining 32 bit words to the exor of the one previous with
+         * the one four words previous */
 
-    expanded_key->round[i].v32[2] =
-      expanded_key->round[i].v32[1] ^ expanded_key->round[i-1].v32[2];
+        expanded_key->round[i].v32[1] =
+            expanded_key->round[i].v32[0] ^ expanded_key->round[i - 1].v32[1];
 
-    expanded_key->round[i].v32[3] =
-      expanded_key->round[i].v32[2] ^ expanded_key->round[i-1].v32[3];
+        expanded_key->round[i].v32[2] =
+            expanded_key->round[i].v32[1] ^ expanded_key->round[i - 1].v32[2];
+
+        expanded_key->round[i].v32[3] =
+            expanded_key->round[i].v32[2] ^ expanded_key->round[i - 1].v32[3];
 
 #if 0
-	debug_print2(mod_aes_icm, 
-				"expanded key[%d]:  %s", i,v128_hex_string(&expanded_key->round[i])); 
+        debug_print2(srtp_mod_aes_icm,
+                     "expanded key[%d]:  %s", i, v128_hex_string(&expanded_key->round[i]));
 #endif
 
-    /* modify round constant */
-    rc = gf2_8_shift(rc);
-
-  }
+        /* modify round constant */
+        rc = gf2_8_shift(rc);
+    }
 }
 
-static void
-aes_256_expand_encryption_key(const unsigned char *key, 
-			      aes_expanded_key_t *expanded_key) {
-  int i;
-  gf2_8 rc;
+static void aes_256_expand_encryption_key(const unsigned char *key,
+                                          srtp_aes_expanded_key_t *expanded_key)
+{
+    int i;
+    uint8_t rc;
 
-  /* initialize round constant */
-  rc = 1;
+    /* initialize round constant */
+    rc = 1;
 
-  expanded_key->num_rounds = 14;
+    expanded_key->num_rounds = 14;
 
-  v128_copy_octet_string(&expanded_key->round[0], key);
-  v128_copy_octet_string(&expanded_key->round[1], key+16);
+    v128_copy_octet_string(&expanded_key->round[0], key);
+    v128_copy_octet_string(&expanded_key->round[1], key + 16);
 
 #if 0
-  debug_print(mod_aes_icm, 
-	      "expanded key[0]:  %s", v128_hex_string(&expanded_key->round[0])); 
-  debug_print(mod_aes_icm, 
-	      "expanded key[1]:  %s", v128_hex_string(&expanded_key->round[1])); 
-#endif
-
-  /* loop over rest of round keys */
-  for (i=2; i < 15; i++) {
-
-    /* munge first word of round key */
-    if ((i & 1) == 0) {
-      expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
-      expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
-      expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
-      expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
-
-      /* modify round constant */
-      rc = gf2_8_shift(rc);
-    }
-    else {
-      expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[12]];
-      expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[13]];
-      expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[14]];
-      expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[15]];
-    }
-
-    expanded_key->round[i].v32[0] ^=  expanded_key->round[i-2].v32[0];
-
-    /* set remaining 32 bit words to the exor of the one previous with
-     * the one eight words previous */
-
-    expanded_key->round[i].v32[1] =
-      expanded_key->round[i].v32[0] ^ expanded_key->round[i-2].v32[1];
-
-    expanded_key->round[i].v32[2] =
-      expanded_key->round[i].v32[1] ^ expanded_key->round[i-2].v32[2];
-
-    expanded_key->round[i].v32[3] =
-      expanded_key->round[i].v32[2] ^ expanded_key->round[i-2].v32[3];
-
-#if 0
-    debug_print2(mod_aes_icm, 
-		 "expanded key[%d]:  %s", i,v128_hex_string(&expanded_key->round[i])); 
+    debug_print(srtp_mod_aes_icm,
+                "expanded key[0]:  %s", v128_hex_string(&expanded_key->round[0]));
+    debug_print(srtp_mod_aes_icm,
+                "expanded key[1]:  %s", v128_hex_string(&expanded_key->round[1]));
 #endif
 
-  }
+    /* loop over rest of round keys */
+    for (i = 2; i < 15; i++) {
+        /* munge first word of round key */
+        if ((i & 1) == 0) {
+            expanded_key->round[i].v8[0] =
+                aes_sbox[expanded_key->round[i - 1].v8[13]] ^ rc;
+            expanded_key->round[i].v8[1] =
+                aes_sbox[expanded_key->round[i - 1].v8[14]];
+            expanded_key->round[i].v8[2] =
+                aes_sbox[expanded_key->round[i - 1].v8[15]];
+            expanded_key->round[i].v8[3] =
+                aes_sbox[expanded_key->round[i - 1].v8[12]];
+
+            /* modify round constant */
+            rc = gf2_8_shift(rc);
+        } else {
+            expanded_key->round[i].v8[0] =
+                aes_sbox[expanded_key->round[i - 1].v8[12]];
+            expanded_key->round[i].v8[1] =
+                aes_sbox[expanded_key->round[i - 1].v8[13]];
+            expanded_key->round[i].v8[2] =
+                aes_sbox[expanded_key->round[i - 1].v8[14]];
+            expanded_key->round[i].v8[3] =
+                aes_sbox[expanded_key->round[i - 1].v8[15]];
+        }
+
+        expanded_key->round[i].v32[0] ^= expanded_key->round[i - 2].v32[0];
+
+        /* set remaining 32 bit words to the exor of the one previous with
+         * the one eight words previous */
+
+        expanded_key->round[i].v32[1] =
+            expanded_key->round[i].v32[0] ^ expanded_key->round[i - 2].v32[1];
+
+        expanded_key->round[i].v32[2] =
+            expanded_key->round[i].v32[1] ^ expanded_key->round[i - 2].v32[2];
+
+        expanded_key->round[i].v32[3] =
+            expanded_key->round[i].v32[2] ^ expanded_key->round[i - 2].v32[3];
+
+#if 0
+        debug_print2(srtp_mod_aes_icm,
+                     "expanded key[%d]:  %s", i, v128_hex_string(&expanded_key->round[i]));
+#endif
+    }
 }
 
-err_status_t
-aes_expand_encryption_key(const uint8_t *key, 
-			  int key_len,
-			  aes_expanded_key_t *expanded_key) {
-  if (key_len == 16) {
-    aes_128_expand_encryption_key(key, expanded_key);
-    return err_status_ok;
-  }
-  else if (key_len == 24) {
-    /* AES-192 not yet supported */
-    return err_status_bad_param;
-  }
-  else if (key_len == 32) {
-    aes_256_expand_encryption_key(key, expanded_key);
-    return err_status_ok;
-  }
-  else
-    return err_status_bad_param;
+srtp_err_status_t srtp_aes_expand_encryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key)
+{
+    if (key_len == 16) {
+        aes_128_expand_encryption_key(key, expanded_key);
+        return srtp_err_status_ok;
+    } else if (key_len == 24) {
+        /* AES-192 not yet supported */
+        return srtp_err_status_bad_param;
+    } else if (key_len == 32) {
+        aes_256_expand_encryption_key(key, expanded_key);
+        return srtp_err_status_ok;
+    } else {
+        return srtp_err_status_bad_param;
+    }
 }
 
-err_status_t
-aes_expand_decryption_key(const uint8_t *key, 
-			  int key_len,
-			  aes_expanded_key_t *expanded_key) {
-  int i;
-  err_status_t status;
-  int num_rounds = expanded_key->num_rounds;
+srtp_err_status_t srtp_aes_expand_decryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key)
+{
+    int i;
+    srtp_err_status_t status;
+    int num_rounds = expanded_key->num_rounds;
 
-  status = aes_expand_encryption_key(key, key_len, expanded_key);
-  if (status)
-    return status;
+    status = srtp_aes_expand_encryption_key(key, key_len, expanded_key);
+    if (status) {
+        return status;
+    }
 
-  /* invert the order of the round keys */
-  for (i=0; i < num_rounds/2; i++) {
-    v128_t tmp;
-    v128_copy(&tmp, &expanded_key->round[num_rounds-i]);
-    v128_copy(&expanded_key->round[num_rounds-i], &expanded_key->round[i]);
-    v128_copy(&expanded_key->round[i], &tmp);
-  }
+    /* invert the order of the round keys */
+    for (i = 0; i < num_rounds / 2; i++) {
+        v128_t tmp;
+        v128_copy(&tmp, &expanded_key->round[num_rounds - i]);
+        v128_copy(&expanded_key->round[num_rounds - i],
+                  &expanded_key->round[i]);
+        v128_copy(&expanded_key->round[i], &tmp);
+    }
 
-  /* 
-   * apply the inverse mixColumn transform to the round keys (except
-   * for the first and the last)  
-   *
-   * mixColumn is implemented by using the tables U0, U1, U2, U3,
-   * followed by the T4 table (which cancels out the use of the sbox
-   * in the U-tables)
-   */
-  for (i=1; i < num_rounds; i++) {
+    /*
+     * apply the inverse mixColumn transform to the round keys (except
+     * for the first and the last)
+     *
+     * mixColumn is implemented by using the tables U0, U1, U2, U3,
+     * followed by the T4 table (which cancels out the use of the sbox
+     * in the U-tables)
+     */
+    for (i = 1; i < num_rounds; i++) {
 #ifdef CPU_RISC
-    uint32_t tmp;
+        uint32_t tmp;
+
+#ifdef WORDS_BIGENDIAN
+        /* clang-format off */
+        tmp = expanded_key->round[i].v32[0];
+        expanded_key->round[i].v32[0] =
+            U0[T4[(tmp >> 24)       ] & 0xff] ^
+            U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U3[T4[(tmp)       & 0xff] & 0xff];
 
-    tmp = expanded_key->round[i].v32[0];
-    expanded_key->round[i].v32[0] = 
-      U0[T4[(tmp >> 24)       ] & 0xff] ^ 
-      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ 
-      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ 
-      U3[T4[(tmp)       & 0xff] & 0xff];
+        tmp = expanded_key->round[i].v32[1];
+        expanded_key->round[i].v32[1] =
+            U0[T4[(tmp >> 24)       ] & 0xff] ^
+            U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U3[T4[(tmp)       & 0xff] & 0xff];
+
+        tmp = expanded_key->round[i].v32[2];
+        expanded_key->round[i].v32[2] =
+            U0[T4[(tmp >> 24)       ] & 0xff] ^
+            U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U3[T4[(tmp)       & 0xff] & 0xff];
 
-    tmp = expanded_key->round[i].v32[1];
-    expanded_key->round[i].v32[1] = 
-      U0[T4[(tmp >> 24)       ] & 0xff] ^ 
-      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ 
-      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ 
-      U3[T4[(tmp)       & 0xff] & 0xff];
+        tmp = expanded_key->round[i].v32[3];
+        expanded_key->round[i].v32[3] =
+            U0[T4[(tmp >> 24)       ] & 0xff] ^
+            U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U3[T4[(tmp)       & 0xff] & 0xff];
+#else
+        tmp = expanded_key->round[i].v32[0];
+        expanded_key->round[i].v32[0] =
+            U3[T4[(tmp >> 24)       ] & 0xff] ^
+            U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U0[T4[(tmp)       & 0xff] & 0xff];
 
-    tmp = expanded_key->round[i].v32[2];
-    expanded_key->round[i].v32[2] = 
-      U0[T4[(tmp >> 24)       ] & 0xff] ^ 
-      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ 
-      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ 
-      U3[T4[(tmp)       & 0xff] & 0xff];
+        tmp = expanded_key->round[i].v32[1];
+        expanded_key->round[i].v32[1] =
+            U3[T4[(tmp >> 24)       ] & 0xff] ^
+            U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U0[T4[(tmp)       & 0xff] & 0xff];
 
-    tmp = expanded_key->round[i].v32[3];
-    expanded_key->round[i].v32[3] = 
-      U0[T4[(tmp >> 24)       ] & 0xff] ^ 
-      U1[T4[(tmp >> 16) & 0xff] & 0xff] ^ 
-      U2[T4[(tmp >> 8)  & 0xff] & 0xff] ^ 
-      U3[T4[(tmp)       & 0xff] & 0xff];
+        tmp = expanded_key->round[i].v32[2];
+        expanded_key->round[i].v32[2] =
+            U3[T4[(tmp >> 24)       ] & 0xff] ^
+            U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U0[T4[(tmp)       & 0xff] & 0xff];
+
+        tmp = expanded_key->round[i].v32[3];
+        expanded_key->round[i].v32[3] =
+            U3[T4[(tmp >> 24)       ] & 0xff] ^
+            U2[T4[(tmp >> 16) & 0xff] & 0xff] ^
+            U1[T4[(tmp >> 8)  & 0xff] & 0xff] ^
+            U0[T4[(tmp)       & 0xff] & 0xff];
+/* clang-format on */
+#endif /* WORDS_BIGENDIAN */
+
 #else /* assume CPU_CISC */
 
-    uint32_t c0, c1, c2, c3;
+        uint32_t c0, c1, c2, c3;
 
-    c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]] 
-       ^ U1[aes_sbox[expanded_key->round[i].v8[1]]] 
-       ^ U2[aes_sbox[expanded_key->round[i].v8[2]]] 
-       ^ U3[aes_sbox[expanded_key->round[i].v8[3]]];
+        c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]] ^
+             U1[aes_sbox[expanded_key->round[i].v8[1]]] ^
+             U2[aes_sbox[expanded_key->round[i].v8[2]]] ^
+             U3[aes_sbox[expanded_key->round[i].v8[3]]];
 
-    c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]] 
-       ^ U1[aes_sbox[expanded_key->round[i].v8[5]]] 
-       ^ U2[aes_sbox[expanded_key->round[i].v8[6]]] 
-       ^ U3[aes_sbox[expanded_key->round[i].v8[7]]];
+        c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]] ^
+             U1[aes_sbox[expanded_key->round[i].v8[5]]] ^
+             U2[aes_sbox[expanded_key->round[i].v8[6]]] ^
+             U3[aes_sbox[expanded_key->round[i].v8[7]]];
 
-    c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]] 
-       ^ U1[aes_sbox[expanded_key->round[i].v8[9]]] 
-       ^ U2[aes_sbox[expanded_key->round[i].v8[10]]] 
-       ^ U3[aes_sbox[expanded_key->round[i].v8[11]]];
+        c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]] ^
+             U1[aes_sbox[expanded_key->round[i].v8[9]]] ^
+             U2[aes_sbox[expanded_key->round[i].v8[10]]] ^
+             U3[aes_sbox[expanded_key->round[i].v8[11]]];
 
-    c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]] 
-       ^ U1[aes_sbox[expanded_key->round[i].v8[13]]] 
-       ^ U2[aes_sbox[expanded_key->round[i].v8[14]]] 
-       ^ U3[aes_sbox[expanded_key->round[i].v8[15]]];
+        c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]] ^
+             U1[aes_sbox[expanded_key->round[i].v8[13]]] ^
+             U2[aes_sbox[expanded_key->round[i].v8[14]]] ^
+             U3[aes_sbox[expanded_key->round[i].v8[15]]];
 
-    expanded_key->round[i].v32[0] = c0;
-    expanded_key->round[i].v32[1] = c1;
-    expanded_key->round[i].v32[2] = c2;
-    expanded_key->round[i].v32[3] = c3;
+        expanded_key->round[i].v32[0] = c0;
+        expanded_key->round[i].v32[1] = c1;
+        expanded_key->round[i].v32[2] = c2;
+        expanded_key->round[i].v32[3] = c3;
 
-#endif     
-  }
+#endif
+    }
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
 #ifdef CPU_CISC
 
-
-static inline void
-aes_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables T0, T1, T2, T3 */
+    /* compute the columns of the output square in terms of the octets
+       of state, using the tables T0, T1, T2, T3 */
 
-  column0 = T0[state->v8[0]] ^ T1[state->v8[5]]
-    ^ T2[state->v8[10]] ^ T3[state->v8[15]];
+    column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
+              T3[state->v8[15]];
 
-  column1 = T0[state->v8[4]] ^ T1[state->v8[9]]
-    ^ T2[state->v8[14]] ^ T3[state->v8[3]];
+    column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
+              T3[state->v8[3]];
 
-  column2 = T0[state->v8[8]] ^ T1[state->v8[13]]
-    ^ T2[state->v8[2]] ^ T3[state->v8[7]];
+    column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
+              T3[state->v8[7]];
 
-  column3 = T0[state->v8[12]] ^ T1[state->v8[1]]
-    ^ T2[state->v8[6]] ^ T3[state->v8[11]];
+    column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
+              T3[state->v8[11]];
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
-
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
-
-static inline void
-aes_inv_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
+static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables U0, U1, U2, U3 */
+    /* compute the columns of the output square in terms of the octets
+       of state, using the tables U0, U1, U2, U3 */
 
-  column0 = U0[state->v8[0]] ^ U1[state->v8[13]]
-    ^ U2[state->v8[10]] ^ U3[state->v8[7]];
+    column0 = U0[state->v8[0]] ^ U1[state->v8[13]] ^ U2[state->v8[10]] ^
+              U3[state->v8[7]];
 
-  column1 = U0[state->v8[4]] ^ U1[state->v8[1]]
-    ^ U2[state->v8[14]] ^ U3[state->v8[11]];
+    column1 = U0[state->v8[4]] ^ U1[state->v8[1]] ^ U2[state->v8[14]] ^
+              U3[state->v8[11]];
 
-  column2 = U0[state->v8[8]] ^ U1[state->v8[5]]
-    ^ U2[state->v8[2]] ^ U3[state->v8[15]];
+    column2 = U0[state->v8[8]] ^ U1[state->v8[5]] ^ U2[state->v8[2]] ^
+              U3[state->v8[15]];
 
-  column3 = U0[state->v8[12]] ^ U1[state->v8[9]]
-    ^ U2[state->v8[6]] ^ U3[state->v8[3]];
+    column3 = U0[state->v8[12]] ^ U1[state->v8[9]] ^ U2[state->v8[6]] ^
+              U3[state->v8[3]];
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
-
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
-static inline void
-aes_final_round(v128_t *state, const v128_t *round_key) {
-  uint8_t tmp;
+static inline void aes_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint8_t tmp;
 
-  /* byte substitutions and row shifts */
-  /* first row - no shift */
-  state->v8[0] = aes_sbox[state->v8[0]];
-  state->v8[4] = aes_sbox[state->v8[4]];
-  state->v8[8] = aes_sbox[state->v8[8]];
-  state->v8[12] = aes_sbox[state->v8[12]];
+    /* byte substitutions and row shifts */
+    /* first row - no shift */
+    state->v8[0] = aes_sbox[state->v8[0]];
+    state->v8[4] = aes_sbox[state->v8[4]];
+    state->v8[8] = aes_sbox[state->v8[8]];
+    state->v8[12] = aes_sbox[state->v8[12]];
 
-  /* second row - shift one left */
-  tmp = aes_sbox[state->v8[1]];
-  state->v8[1] = aes_sbox[state->v8[5]];
-  state->v8[5] = aes_sbox[state->v8[9]];
-  state->v8[9] = aes_sbox[state->v8[13]];
-  state->v8[13] = tmp;
+    /* second row - shift one left */
+    tmp = aes_sbox[state->v8[1]];
+    state->v8[1] = aes_sbox[state->v8[5]];
+    state->v8[5] = aes_sbox[state->v8[9]];
+    state->v8[9] = aes_sbox[state->v8[13]];
+    state->v8[13] = tmp;
 
-  /* third row - shift two left */
-  tmp = aes_sbox[state->v8[10]];
-  state->v8[10] = aes_sbox[state->v8[2]];
-  state->v8[2] = tmp;
-  tmp = aes_sbox[state->v8[14]];
-  state->v8[14] = aes_sbox[state->v8[6]];
-  state->v8[6] = tmp; 
+    /* third row - shift two left */
+    tmp = aes_sbox[state->v8[10]];
+    state->v8[10] = aes_sbox[state->v8[2]];
+    state->v8[2] = tmp;
+    tmp = aes_sbox[state->v8[14]];
+    state->v8[14] = aes_sbox[state->v8[6]];
+    state->v8[6] = tmp;
 
-  /* fourth row - shift three left */
-  tmp = aes_sbox[state->v8[15]];
-  state->v8[15] = aes_sbox[state->v8[11]];
-  state->v8[11] = aes_sbox[state->v8[7]];
-  state->v8[7] = aes_sbox[state->v8[3]];
-  state->v8[3] = tmp;
+    /* fourth row - shift three left */
+    tmp = aes_sbox[state->v8[15]];
+    state->v8[15] = aes_sbox[state->v8[11]];
+    state->v8[11] = aes_sbox[state->v8[7]];
+    state->v8[7] = aes_sbox[state->v8[3]];
+    state->v8[3] = tmp;
 
-  v128_xor_eq(state, round_key);
+    v128_xor_eq(state, round_key);
 }
 
-static inline void
-aes_inv_final_round(v128_t *state, const v128_t *round_key) {
-  uint8_t tmp;
+static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint8_t tmp;
 
-  /* byte substitutions and row shifts */
-  /* first row - no shift */
-  state->v8[0] = aes_inv_sbox[state->v8[0]];
-  state->v8[4] = aes_inv_sbox[state->v8[4]];
-  state->v8[8] = aes_inv_sbox[state->v8[8]];
-  state->v8[12] = aes_inv_sbox[state->v8[12]];
+    /* byte substitutions and row shifts */
+    /* first row - no shift */
+    state->v8[0] = aes_inv_sbox[state->v8[0]];
+    state->v8[4] = aes_inv_sbox[state->v8[4]];
+    state->v8[8] = aes_inv_sbox[state->v8[8]];
+    state->v8[12] = aes_inv_sbox[state->v8[12]];
 
-  /* second row - shift one right */
-  tmp = aes_inv_sbox[state->v8[13]];
-  state->v8[13] = aes_inv_sbox[state->v8[9]];
-  state->v8[9] = aes_inv_sbox[state->v8[5]];
-  state->v8[5] = aes_inv_sbox[state->v8[1]];
-  state->v8[1] = tmp;
+    /* second row - shift one right */
+    tmp = aes_inv_sbox[state->v8[13]];
+    state->v8[13] = aes_inv_sbox[state->v8[9]];
+    state->v8[9] = aes_inv_sbox[state->v8[5]];
+    state->v8[5] = aes_inv_sbox[state->v8[1]];
+    state->v8[1] = tmp;
 
-  /* third row - shift two right */
-  tmp = aes_inv_sbox[state->v8[2]];
-  state->v8[2] = aes_inv_sbox[state->v8[10]];
-  state->v8[10] = tmp;
-  tmp = aes_inv_sbox[state->v8[6]];
-  state->v8[6] = aes_inv_sbox[state->v8[14]];
-  state->v8[14] = tmp; 
+    /* third row - shift two right */
+    tmp = aes_inv_sbox[state->v8[2]];
+    state->v8[2] = aes_inv_sbox[state->v8[10]];
+    state->v8[10] = tmp;
+    tmp = aes_inv_sbox[state->v8[6]];
+    state->v8[6] = aes_inv_sbox[state->v8[14]];
+    state->v8[14] = tmp;
 
-  /* fourth row - shift three right */
-  tmp = aes_inv_sbox[state->v8[3]];
-  state->v8[3] = aes_inv_sbox[state->v8[7]];
-  state->v8[7] = aes_inv_sbox[state->v8[11]];
-  state->v8[11] = aes_inv_sbox[state->v8[15]];
-  state->v8[15] = tmp;
+    /* fourth row - shift three right */
+    tmp = aes_inv_sbox[state->v8[3]];
+    state->v8[3] = aes_inv_sbox[state->v8[7]];
+    state->v8[7] = aes_inv_sbox[state->v8[11]];
+    state->v8[11] = aes_inv_sbox[state->v8[15]];
+    state->v8[15] = tmp;
 
-  v128_xor_eq(state, round_key);
+    v128_xor_eq(state, round_key);
 }
 
-
 #elif CPU_RISC
 
-static inline void
-aes_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
-
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables T0, T1, T2, T3 */
-#ifdef WORDS_BIGENDIAN
-  column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff]
-    ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
-
-  column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff]
-    ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
-
-  column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff]
-    ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-  column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff]
-    ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
-#else
-  column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff]
-	^ T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
+/* compute the columns of the output square in terms of the octets
+   of state, using the tables T0, T1, T2, T3 */
+#ifdef WORDS_BIGENDIAN
+    column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff] ^
+              T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
 
-  column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff]
-	^ T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
-
-  column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff]
-	^ T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];
-
-  column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff]
-	^ T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];
-#endif /* WORDS_BIGENDIAN */
+    column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] ^
+              T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
-
-}
+    column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] ^
+              T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
 
-static inline void
-aes_inv_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
-
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables U0, U1, U2, U3 */
-
-#ifdef WORDS_BIGENDIAN
-  /* FIX!  WRong indexes */
-  column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff]
-    ^ U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
+    column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] ^
+              T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
+#else
+    column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] ^
+              T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
 
-  column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff]
-    ^ U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
-
-  column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff]
-    ^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
+    column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] ^
+              T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
 
-  column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff]
-    ^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
-#else
-  column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff]
-	^ U2[(state->v32[2] >> 16) & 0xff] ^ U3[state->v32[3] >> 24];
+    column2 = T0[state->v32[2] & 0xff] ^ T1[(state->v32[3] >> 8) & 0xff] ^
+              T2[(state->v32[0] >> 16) & 0xff] ^ T3[state->v32[1] >> 24];
 
-  column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff]
-	^ U2[(state->v32[3] >> 16) & 0xff] ^ U3[state->v32[0] >> 24];
-
-  column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff]
-	^ U2[(state->v32[0] >> 16) & 0xff] ^ U3[state->v32[1] >> 24];
-
-  column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff]
-	^ U2[(state->v32[1] >> 16) & 0xff] ^ U3[state->v32[2] >> 24];
+    column3 = T0[state->v32[3] & 0xff] ^ T1[(state->v32[0] >> 8) & 0xff] ^
+              T2[(state->v32[1] >> 16) & 0xff] ^ T3[state->v32[2] >> 24];
 #endif /* WORDS_BIGENDIAN */
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
+}
+
+static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
+
+/* compute the columns of the output square in terms of the octets
+   of state, using the tables U0, U1, U2, U3 */
+
+#ifdef WORDS_BIGENDIAN
+    column0 = U0[state->v32[0] >> 24] ^ U1[(state->v32[3] >> 16) & 0xff] ^
+              U2[(state->v32[2] >> 8) & 0xff] ^ U3[state->v32[1] & 0xff];
+
+    column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] ^
+              U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
+
+    column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] ^
+              U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
 
+    column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff] ^
+              U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
+#else
+    column0 = U0[state->v32[0] & 0xff] ^ U1[(state->v32[3] >> 8) & 0xff] ^
+              U2[(state->v32[2] >> 16) & 0xff] ^
+              U3[(state->v32[1] >> 24) & 0xff];
+
+    column1 = U0[state->v32[1] & 0xff] ^ U1[(state->v32[0] >> 8) & 0xff] ^
+              U2[(state->v32[3] >> 16) & 0xff] ^
+              U3[(state->v32[2] >> 24) & 0xff];
+
+    column2 = U0[state->v32[2] & 0xff] ^ U1[(state->v32[1] >> 8) & 0xff] ^
+              U2[(state->v32[0] >> 16) & 0xff] ^
+              U3[(state->v32[3] >> 24) & 0xff];
+
+    column3 = U0[state->v32[3] & 0xff] ^ U1[(state->v32[2] >> 8) & 0xff] ^
+              U2[(state->v32[1] >> 16) & 0xff] ^
+              U3[(state->v32[0] >> 24) & 0xff];
+#endif /* WORDS_BIGENDIAN */
+
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
-static inline void
-aes_final_round(v128_t *state, const v128_t *round_key) {
-  uint32_t tmp0, tmp1, tmp2, tmp3;
+static inline void aes_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t tmp0, tmp1, tmp2, tmp3;
 
-  tmp0 = (T4[(state->v32[0] >> 24)]        & 0xff000000) 
-       ^ (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) 
-       ^ (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) 
-       ^ (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) 
-       ^ round_key->v32[0];
-
-  tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[0]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[1];
+#ifdef WORDS_BIGENDIAN
+    /* clang-format off */
+    tmp0 = (T4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-  tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[1]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[2];
+    tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[2]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[3];
-
-  state->v32[0] = tmp0;
-  state->v32[1] = tmp1;
-  state->v32[2] = tmp2;
-  state->v32[3] = tmp3;
+    tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-}
-
-static inline void
-aes_inv_final_round(v128_t *state, const v128_t *round_key) {
-  uint32_t tmp0, tmp1, tmp2, tmp3;
+    tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+#else
+    tmp0 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-  tmp0 = (U4[(state->v32[0] >> 24)]        & 0xff000000) 
-       ^ (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) 
-       ^ (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) 
-       ^ (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) 
-       ^ round_key->v32[0];
-
-  tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[2]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[1];
+    tmp1 = (T4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[3]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[2];
+    tmp2 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-  tmp3 = (U4[(state->v32[3] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[0]      ) & 0xff] & 0x000000ff)
-       ^ round_key->v32[3];
+    tmp3 = (T4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+/* clang-format on */
+#endif /* WORDS_BIGENDIAN */
 
-  state->v32[0] = tmp0;
-  state->v32[1] = tmp1;
-  state->v32[2] = tmp2;
-  state->v32[3] = tmp3;
-
+    state->v32[0] = tmp0;
+    state->v32[1] = tmp1;
+    state->v32[2] = tmp2;
+    state->v32[3] = tmp3;
 }
 
-#elif CPU_16  /* assume 16-bit word size on processor */
+static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t tmp0, tmp1, tmp2, tmp3;
+
+#ifdef WORDS_BIGENDIAN
+    /* clang-format off */
+    tmp0 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-static inline void
-aes_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
-  uint16_t c
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables T0, T1, T2, T3 */
+    tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  column0 = T0[state->v8[0]] ^ T1[state->v8[5]]
-    ^ T2[state->v8[10]] ^ T3[state->v8[15]];
+    tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-  column1 = T0[state->v8[4]] ^ T1[state->v8[9]]
-    ^ T2[state->v8[14]] ^ T3[state->v8[3]];
+    tmp3 = (U4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+#else
+    tmp0 = (U4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-  column2 = T0[state->v8[8]] ^ T1[state->v8[13]]
-    ^ T2[state->v8[2]] ^ T3[state->v8[7]];
+    tmp1 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  column3 = T0[state->v8[12]] ^ T1[state->v8[1]]
-    ^ T2[state->v8[6]] ^ T3[state->v8[11]];
+    tmp2 = (U4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
+    tmp3 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+/* clang-format on */
+#endif /* WORDS_BIGENDIAN */
 
+    state->v32[0] = tmp0;
+    state->v32[1] = tmp1;
+    state->v32[2] = tmp2;
+    state->v32[3] = tmp3;
 }
 
-
-static inline void
-aes_inv_round(v128_t *state, const v128_t *round_key) {
-  uint32_t column0, column1, column2, column3;
+#elif CPU_16 /* assume 16-bit word size on processor */
 
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables U0, U1, U2, U3 */
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
+    /* compute the columns of the output square in terms of the octets
+       of state, using the tables T0, T1, T2, T3 */
 
-  column0 = U0[state->v8[0]] ^ U1[state->v8[5]]
-    ^ U2[state->v8[10]] ^ U3[state->v8[15]];
+    column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
+              T3[state->v8[15]];
 
-  column1 = U0[state->v8[4]] ^ U1[state->v8[9]]
-    ^ U2[state->v8[14]] ^ U3[state->v8[3]];
+    column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
+              T3[state->v8[3]];
 
-  column2 = U0[state->v8[8]] ^ U1[state->v8[13]]
-    ^ U2[state->v8[2]] ^ U3[state->v8[7]];
+    column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
+              T3[state->v8[7]];
 
-  column3 = U0[state->v8[12]] ^ U1[state->v8[1]]
-    ^ U2[state->v8[6]] ^ U3[state->v8[11]];
+    column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
+              T3[state->v8[11]];
 
-  state->v32[0] = column0 ^ round_key->v32[0];
-  state->v32[1] = column1 ^ round_key->v32[1];
-  state->v32[2] = column2 ^ round_key->v32[2];
-  state->v32[3] = column3 ^ round_key->v32[3];
-
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
-static inline void
-aes_final_round(v128_t *state, const v128_t *round_key) {
-  uint8_t tmp;
+static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-  /* byte substitutions and row shifts */
-  /* first row - no shift */
-  state->v8[0] = aes_sbox[state->v8[0]];
-  state->v8[4] = aes_sbox[state->v8[4]];
-  state->v8[8] = aes_sbox[state->v8[8]];
-  state->v8[12] = aes_sbox[state->v8[12]];
+    /* compute the columns of the output square in terms of the octets
+       of state, using the tables U0, U1, U2, U3 */
+
+    column0 = U0[state->v8[0]] ^ U1[state->v8[5]] ^ U2[state->v8[10]] ^
+              U3[state->v8[15]];
 
-  /* second row - shift one left */
-  tmp = aes_sbox[state->v8[1]];
-  state->v8[1] = aes_sbox[state->v8[5]];
-  state->v8[5] = aes_sbox[state->v8[9]];
-  state->v8[9] = aes_sbox[state->v8[13]];
-  state->v8[13] = tmp;
+    column1 = U0[state->v8[4]] ^ U1[state->v8[9]] ^ U2[state->v8[14]] ^
+              U3[state->v8[3]];
+
+    column2 = U0[state->v8[8]] ^ U1[state->v8[13]] ^ U2[state->v8[2]] ^
+              U3[state->v8[7]];
 
-  /* third row - shift two left */
-  tmp = aes_sbox[state->v8[10]];
-  state->v8[10] = aes_sbox[state->v8[2]];
-  state->v8[2] = tmp;
-  tmp = aes_sbox[state->v8[14]];
-  state->v8[14] = aes_sbox[state->v8[6]];
-  state->v8[6] = tmp; 
+    column3 = U0[state->v8[12]] ^ U1[state->v8[1]] ^ U2[state->v8[6]] ^
+              U3[state->v8[11]];
 
-  /* fourth row - shift three left */
-  tmp = aes_sbox[state->v8[15]];
-  state->v8[15] = aes_sbox[state->v8[11]];
-  state->v8[11] = aes_sbox[state->v8[7]];
-  state->v8[7] = aes_sbox[state->v8[3]];
-  state->v8[3] = tmp;
-
-  v128_xor_eq(state, round_key);
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
-static inline void
-aes_inv_final_round(v128_t *state, const v128_t *round_key) {
-  uint8_t tmp;
+static inline void aes_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint8_t tmp;
 
-  /* byte substitutions and row shifts */
-  /* first row - no shift */
-  state->v8[0] = aes_inv_sbox[state->v8[0]];
-  state->v8[4] = aes_inv_sbox[state->v8[4]];
-  state->v8[8] = aes_inv_sbox[state->v8[8]];
-  state->v8[12] = aes_inv_sbox[state->v8[12]];
+    /* byte substitutions and row shifts */
+    /* first row - no shift */
+    state->v8[0] = aes_sbox[state->v8[0]];
+    state->v8[4] = aes_sbox[state->v8[4]];
+    state->v8[8] = aes_sbox[state->v8[8]];
+    state->v8[12] = aes_sbox[state->v8[12]];
 
-  /* second row - shift one left */
-  tmp = aes_inv_sbox[state->v8[1]];
-  state->v8[1] = aes_inv_sbox[state->v8[5]];
-  state->v8[5] = aes_inv_sbox[state->v8[9]];
-  state->v8[9] = aes_inv_sbox[state->v8[13]];
-  state->v8[13] = tmp;
+    /* second row - shift one left */
+    tmp = aes_sbox[state->v8[1]];
+    state->v8[1] = aes_sbox[state->v8[5]];
+    state->v8[5] = aes_sbox[state->v8[9]];
+    state->v8[9] = aes_sbox[state->v8[13]];
+    state->v8[13] = tmp;
 
-  /* third row - shift two left */
-  tmp = aes_inv_sbox[state->v8[10]];
-  state->v8[10] = aes_inv_sbox[state->v8[2]];
-  state->v8[2] = tmp;
-  tmp = aes_inv_sbox[state->v8[14]];
-  state->v8[14] = aes_inv_sbox[state->v8[6]];
-  state->v8[6] = tmp; 
+    /* third row - shift two left */
+    tmp = aes_sbox[state->v8[10]];
+    state->v8[10] = aes_sbox[state->v8[2]];
+    state->v8[2] = tmp;
+    tmp = aes_sbox[state->v8[14]];
+    state->v8[14] = aes_sbox[state->v8[6]];
+    state->v8[6] = tmp;
 
-  /* fourth row - shift three left */
-  tmp = aes_inv_sbox[state->v8[15]];
-  state->v8[15] = aes_inv_sbox[state->v8[11]];
-  state->v8[11] = aes_inv_sbox[state->v8[7]];
-  state->v8[7] = aes_inv_sbox[state->v8[3]];
-  state->v8[3] = tmp;
+    /* fourth row - shift three left */
+    tmp = aes_sbox[state->v8[15]];
+    state->v8[15] = aes_sbox[state->v8[11]];
+    state->v8[11] = aes_sbox[state->v8[7]];
+    state->v8[7] = aes_sbox[state->v8[3]];
+    state->v8[3] = tmp;
 
-  v128_xor_eq(state, round_key);
+    v128_xor_eq(state, round_key);
 }
 
-#endif  /* CPU type */
-
+static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint8_t tmp;
 
-void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
-
-  /* add in the subkey */
-  v128_xor_eq(plaintext, &exp_key->round[0]);
+    /* byte substitutions and row shifts */
+    /* first row - no shift */
+    state->v8[0] = aes_inv_sbox[state->v8[0]];
+    state->v8[4] = aes_inv_sbox[state->v8[4]];
+    state->v8[8] = aes_inv_sbox[state->v8[8]];
+    state->v8[12] = aes_inv_sbox[state->v8[12]];
 
-  /* now do the rounds */
-  aes_round(plaintext, &exp_key->round[1]);
-  aes_round(plaintext, &exp_key->round[2]);
-  aes_round(plaintext, &exp_key->round[3]);
-  aes_round(plaintext, &exp_key->round[4]);
-  aes_round(plaintext, &exp_key->round[5]);
-  aes_round(plaintext, &exp_key->round[6]);
-  aes_round(plaintext, &exp_key->round[7]);
-  aes_round(plaintext, &exp_key->round[8]);  
-  aes_round(plaintext, &exp_key->round[9]);
-  if (exp_key->num_rounds == 10) {
-    aes_final_round(plaintext, &exp_key->round[10]);
-  }
-  else if (exp_key->num_rounds == 12) {
-    aes_round(plaintext, &exp_key->round[10]);  
-    aes_round(plaintext, &exp_key->round[11]);
-    aes_final_round(plaintext, &exp_key->round[12]);
-  }
-  else if (exp_key->num_rounds == 14) {
-    aes_round(plaintext, &exp_key->round[10]);  
-    aes_round(plaintext, &exp_key->round[11]);
-    aes_round(plaintext, &exp_key->round[12]);  
-    aes_round(plaintext, &exp_key->round[13]);
-    aes_final_round(plaintext, &exp_key->round[14]);  
-  }
+    /* second row - shift one left */
+    tmp = aes_inv_sbox[state->v8[1]];
+    state->v8[1] = aes_inv_sbox[state->v8[5]];
+    state->v8[5] = aes_inv_sbox[state->v8[9]];
+    state->v8[9] = aes_inv_sbox[state->v8[13]];
+    state->v8[13] = tmp;
+
+    /* third row - shift two left */
+    tmp = aes_inv_sbox[state->v8[10]];
+    state->v8[10] = aes_inv_sbox[state->v8[2]];
+    state->v8[2] = tmp;
+    tmp = aes_inv_sbox[state->v8[14]];
+    state->v8[14] = aes_inv_sbox[state->v8[6]];
+    state->v8[6] = tmp;
+
+    /* fourth row - shift three left */
+    tmp = aes_inv_sbox[state->v8[15]];
+    state->v8[15] = aes_inv_sbox[state->v8[11]];
+    state->v8[11] = aes_inv_sbox[state->v8[7]];
+    state->v8[7] = aes_inv_sbox[state->v8[3]];
+    state->v8[3] = tmp;
+
+    v128_xor_eq(state, round_key);
 }
 
-void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
+#endif /* CPU type */
 
-  /* add in the subkey */
-  v128_xor_eq(plaintext, &exp_key->round[0]);
+void srtp_aes_encrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
+{
+    /* add in the subkey */
+    v128_xor_eq(plaintext, &exp_key->round[0]);
 
-  /* now do the rounds */
-  aes_inv_round(plaintext, &exp_key->round[1]);
-  aes_inv_round(plaintext, &exp_key->round[2]);
-  aes_inv_round(plaintext, &exp_key->round[3]);
-  aes_inv_round(plaintext, &exp_key->round[4]);
-  aes_inv_round(plaintext, &exp_key->round[5]);
-  aes_inv_round(plaintext, &exp_key->round[6]);
-  aes_inv_round(plaintext, &exp_key->round[7]);
-  aes_inv_round(plaintext, &exp_key->round[8]);  
-  aes_inv_round(plaintext, &exp_key->round[9]);
-  if (exp_key->num_rounds == 10) {
-    aes_inv_final_round(plaintext, &exp_key->round[10]);  
-  }
-  else if (exp_key->num_rounds == 12) {
-    aes_inv_round(plaintext, &exp_key->round[10]);  
-    aes_inv_round(plaintext, &exp_key->round[11]);
-    aes_inv_final_round(plaintext, &exp_key->round[12]);  
-  }
-  else if (exp_key->num_rounds == 14) {
-    aes_inv_round(plaintext, &exp_key->round[10]);  
-    aes_inv_round(plaintext, &exp_key->round[11]);
-    aes_inv_round(plaintext, &exp_key->round[12]);  
-    aes_inv_round(plaintext, &exp_key->round[13]);
-    aes_inv_final_round(plaintext, &exp_key->round[14]);  
-  }
+    /* now do the rounds */
+    aes_round(plaintext, &exp_key->round[1]);
+    aes_round(plaintext, &exp_key->round[2]);
+    aes_round(plaintext, &exp_key->round[3]);
+    aes_round(plaintext, &exp_key->round[4]);
+    aes_round(plaintext, &exp_key->round[5]);
+    aes_round(plaintext, &exp_key->round[6]);
+    aes_round(plaintext, &exp_key->round[7]);
+    aes_round(plaintext, &exp_key->round[8]);
+    aes_round(plaintext, &exp_key->round[9]);
+    if (exp_key->num_rounds == 10) {
+        aes_final_round(plaintext, &exp_key->round[10]);
+    } else if (exp_key->num_rounds == 12) {
+        aes_round(plaintext, &exp_key->round[10]);
+        aes_round(plaintext, &exp_key->round[11]);
+        aes_final_round(plaintext, &exp_key->round[12]);
+    } else if (exp_key->num_rounds == 14) {
+        aes_round(plaintext, &exp_key->round[10]);
+        aes_round(plaintext, &exp_key->round[11]);
+        aes_round(plaintext, &exp_key->round[12]);
+        aes_round(plaintext, &exp_key->round[13]);
+        aes_final_round(plaintext, &exp_key->round[14]);
+    }
 }
+
+void srtp_aes_decrypt(v128_t *plaintext, const srtp_aes_expanded_key_t *exp_key)
+{
+    /* add in the subkey */
+    v128_xor_eq(plaintext, &exp_key->round[0]);
+
+    /* now do the rounds */
+    aes_inv_round(plaintext, &exp_key->round[1]);
+    aes_inv_round(plaintext, &exp_key->round[2]);
+    aes_inv_round(plaintext, &exp_key->round[3]);
+    aes_inv_round(plaintext, &exp_key->round[4]);
+    aes_inv_round(plaintext, &exp_key->round[5]);
+    aes_inv_round(plaintext, &exp_key->round[6]);
+    aes_inv_round(plaintext, &exp_key->round[7]);
+    aes_inv_round(plaintext, &exp_key->round[8]);
+    aes_inv_round(plaintext, &exp_key->round[9]);
+    if (exp_key->num_rounds == 10) {
+        aes_inv_final_round(plaintext, &exp_key->round[10]);
+    } else if (exp_key->num_rounds == 12) {
+        aes_inv_round(plaintext, &exp_key->round[10]);
+        aes_inv_round(plaintext, &exp_key->round[11]);
+        aes_inv_final_round(plaintext, &exp_key->round[12]);
+    } else if (exp_key->num_rounds == 14) {
+        aes_inv_round(plaintext, &exp_key->round[10]);
+        aes_inv_round(plaintext, &exp_key->round[11]);
+        aes_inv_round(plaintext, &exp_key->round[12]);
+        aes_inv_round(plaintext, &exp_key->round[13]);
+        aes_inv_final_round(plaintext, &exp_key->round[14]);
+    }
+}
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/cipher/aes_cbc.c
+++ /dev/null
@@ -1,540 +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) {
-  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,
-		     cipher_direction_t dir) {
-  err_status_t status;
-
-  debug_print(mod_aes_cbc, 
-	      "key:  %s", octet_string_hex_string(key, key_len)); 
-
-  /* expand key for the appropriate direction */
-  switch (dir) {
-  case (direction_encrypt):
-    status = aes_expand_encryption_key(key, key_len, &c->expanded_key);
-    if (status)
-      return status;
-    break;
-  case (direction_decrypt):
-    status = aes_expand_decryption_key(key, key_len, &c->expanded_key);
-    if (status)
-      return status;
-    break;
-  default:
-    return err_status_bad_param;
-  }
-
-
-  return err_status_ok;
-}
-
-
-err_status_t
-aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
-  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)); 
-
-  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               */
-  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               */
-  &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               */
-  &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               */
-  &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_encrypt_func_t)        aes_cbc_nist_encrypt,
-  (cipher_decrypt_func_t)        aes_cbc_nist_decrypt,
-  (cipher_set_iv_func_t)         aes_cbc_set_iv,
-  (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
-};
-
-
--- a/netwerk/srtp/src/crypto/cipher/aes_icm.c
+++ b/netwerk/srtp/src/crypto/cipher/aes_icm.c
@@ -3,565 +3,527 @@
  *
  * AES Integer Counter Mode
  *
  * 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
  * 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
 
 #define ALIGN_32 0
 
 #include "aes_icm.h"
 #include "alloc.h"
-
+#include "cipher_types.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       */
 };
 
 /*
  * integer counter mode works as follows:
  *
  * 16 bits
  * <----->
- * +------+------+------+------+------+------+------+------+ 
+ * +------+------+------+------+------+------+------+------+
  * |           nonce           |    pakcet index    |  ctr |---+
  * +------+------+------+------+------+------+------+------+   |
  *                                                             |
  * +------+------+------+------+------+------+------+------+   v
  * |                      salt                      |000000|->(+)
  * +------+------+------+------+------+------+------+------+   |
  *                                                             |
  *                                                        +---------+
  *							  | 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
  * can be a fixed value per key, or can be per-packet randomness
  * (64 bits)
  *
  */
 
-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(srtp_mod_aes_icm, "allocating cipher with key length %d",
+                key_len);
 
-  debug_print(mod_aes_icm, 
-            "allocating cipher with key length %d", key_len);
+    /*
+     * 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 */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        return srtp_err_status_alloc_fail;
+    }
 
-  /*
-   * 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;
+    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;
+    }
+
+    /* set pointers */
+    (*c)->state = icm;
 
-  /* 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;
+    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;
+    }
 
-  /* set pointers */
-  *c = (cipher_t *)pointer;
-  (*c)->type = &aes_icm;
-  (*c)->state = pointer + sizeof(cipher_t);
+    /* set key size        */
+    icm->key_size = key_len;
+    (*c)->key_len = key_len;
 
-  /* increment ref_count */
-  aes_icm.ref_count++;
-
-  /* set key size        */
-  (*c)->key_len = key_len;
-
-  return err_status_ok;  
+    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));
-
-  /* free memory */
-  crypto_free(c);
+    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);
+    }
 
-  /* decrement ref_count */
-  aes_icm.ref_count--;
-  
-  return err_status_ok;  
+    /* free the cipher context */
+    srtp_crypto_free(c);
+
+    return srtp_err_status_ok;
 }
 
-
 /*
  * 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;
-
-  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;
+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;
 
-  /*
-   * 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;
+    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;
+    }
 
-  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;
-
-  return err_status_ok;
-}
-
-/*
- * 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
- */
 
-err_status_t
-aes_icm_set_octet(aes_icm_ctx_t *c,
-		  uint64_t octet_num) {
+    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;
+    }
 
-#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
-  
+    memcpy(&c->counter, key + base_key_len, copy_len);
+    memcpy(&c->offset, key + base_key_len, copy_len);
 
-  /* 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)); 
+    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));
 
-  /* 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);
+    /* 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;
+    }
 
-    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;
 }
 
 /*
  * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
  * the offset
  */
 
-err_status_t
-aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
-  v128_t *nonce = (v128_t *) iv;
+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);
 
-  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));
+
+    v128_xor(&c->counter, &c->offset, &nonce);
 
-  /* indicate that the keystream_buffer is empty */
-  c->bytes_in_buffer = 0;
+    debug_print(srtp_mod_aes_icm, "set_counter: %s",
+                v128_hex_string(&c->counter));
 
-  return err_status_ok;
+    /* indicate that the keystream_buffer is empty */
+    c->bytes_in_buffer = 0;
+
+    return srtp_err_status_ok;
 }
 
-
-
 /*
  * aes_icm_advance(...) refills the keystream_buffer and
  * advances the block index of the sicm_context forward by one
  *
  * this is an internal, hopefully inlined function
  */
-  
-static 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:
  *
  * bytes_to_encr < bytes_in_buffer
  *  - add keystream into data
  *
  * bytes_to_encr > bytes_in_buffer
  *  - 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;
-
-  /* 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;
+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;
 
- 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];
-	}
+    /* check that there's enough segment left*/
+    if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
+        return srtp_err_status_terminus;
+    }
 
-    c->bytes_in_buffer -= bytes_to_encr;
+    debug_print(srtp_mod_aes_icm, "block index: %d", htons(c->counter.v16[7]));
+    if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
+        /* deal with odd case of small bytes_to_encr */
+        for (i = (sizeof(v128_t) - c->bytes_in_buffer);
+             i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++) {
+            *buf++ ^= c->keystream_buffer.v8[i];
+        }
+
+        c->bytes_in_buffer -= bytes_to_encr;
 
-    /* return now to avoid the main loop */
-    return err_status_ok;
+        /* return now to avoid the main loop */
+        return srtp_err_status_ok;
 
-  } else {
-    
-    /* encrypt bytes until the remaining data is 16-byte aligned */    
-    for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++) 
-      *buf++ ^= c->keystream_buffer.v8[i];
-
-    bytes_to_encr -= c->bytes_in_buffer;
-    c->bytes_in_buffer = 0;
+    } 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];
+        }
 
-  }
-  
-  /* now loop over entire 16-byte blocks of keystream */
-  for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
+        bytes_to_encr -= c->bytes_in_buffer;
+        c->bytes_in_buffer = 0;
+    }
 
-    /* fill buffer with new keystream */
-    aes_icm_advance_ismacryp(c, forIsmacryp);
+    /* now loop over entire 16-byte blocks of keystream */
+    for (i = 0; i < (bytes_to_encr / sizeof(v128_t)); i++) {
+        /* fill buffer with new keystream */
+        srtp_aes_icm_advance(c);
 
-    /*
-     * add keystream into the data buffer (this would be a lot faster
-     * if we could assume 32-bit alignment!)
-     */
+/*
+ * add keystream into the data buffer (this would be a lot faster
+ * if we could assume 32-bit alignment!)
+ */
 
 #if ALIGN_32
-    b = (uint32_t *)buf;
-    *b++ ^= 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 ((((uintptr_t) 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 ((((uintptr_t)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) {
+        /* fill buffer with new keystream */
+        srtp_aes_icm_advance(c);
 
-    /* no tail, so just reset the keystream buffer size to zero */
-    c->bytes_in_buffer = 0;
+        for (i = 0; i < (bytes_to_encr & 0xf); i++) {
+            *buf++ ^= c->keystream_buffer.v8[i];
+        }
 
-  }
-
-  return 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);
-}
+        /* 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;
+    }
 
-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);
+    return srtp_err_status_ok;
 }
 
-
-char 
-aes_icm_description[] = "aes integer counter mode";
+static const char srtp_aes_icm_128_description[] =
+    "AES-128 integer counter mode";
+static const char srtp_aes_icm_256_description[] =
+    "AES-256 integer counter mode";
 
-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
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
+    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+    0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
 };
+/* clang-format on */
 
-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
+/* clang-format off */
+static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
+/* clang-format on */
 
-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, 
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
+/* clang-format on */
 
-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
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
+    0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+    0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+    0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+    0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
 };
+/* clang-format on */
 
-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               */
-  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
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
+    0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
+    0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
+    0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
+    0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
 };
+/* clang-format on */
 
-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
+/* clang-format off */
+static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
+/* clang-format on */
 
-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, 
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
+/* clang-format on */
 
-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
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
+    0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+    0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+    0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+    0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
 };
+/* clang-format on */
 
-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               */
-  &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 */
 };
 
-
-
 /*
  * 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_encrypt_func_t)        aes_icm_encrypt,
-  (cipher_decrypt_func_t)        aes_icm_encrypt,
-  (cipher_set_iv_func_t)         aes_icm_set_iv,
-  (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               /* */
+};
--- a/netwerk/srtp/src/crypto/cipher/cipher.c
+++ b/netwerk/srtp/src/crypto/cipher/cipher.c
@@ -1,421 +1,679 @@
 /*
  * cipher.c
  *
  * cipher meta-functions
  *
  * 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
  * 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 "cipher.h"
-#include "rand_source.h"        /* used in invertibiltiy tests        */
-#include "alloc.h"              /* for crypto_alloc(), crypto_free()  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-debug_module_t mod_cipher = {
-  0,                 /* debugging is off by default */
-  "cipher"           /* printable module name       */
+#include "cipher.h"
+#include "crypto_types.h"
+#include "err.h"   /* for srtp_debug */
+#include "alloc.h" /* for crypto_alloc(), crypto_free()  */
+
+srtp_debug_module_t srtp_mod_cipher = {
+    0,       /* debugging is off by default */
+    "cipher" /* printable module name       */
 };
 
-err_status_t
-cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) {
-  
-  /* zeroize the buffer */
-  octet_string_set_to_zero(buffer, num_octets_to_output);
-  
-  /* exor keystream into buffer */
-  return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output);
+srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct,
+                                         srtp_cipher_t **c,
+                                         int key_len,
+                                         int tlen)
+{
+    if (!ct || !ct->alloc) {
+        return (srtp_err_status_bad_param);
+    }
+    return ((ct)->alloc((c), (key_len), (tlen)));
+}
+
+srtp_err_status_t srtp_cipher_dealloc(srtp_cipher_t *c)
+{
+    if (!c || !c->type) {
+        return (srtp_err_status_bad_param);
+    }
+    return (((c)->type)->dealloc(c));
+}
+
+srtp_err_status_t srtp_cipher_init(srtp_cipher_t *c, const uint8_t *key)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+    return (((c)->type)->init(((c)->state), (key)));
+}
+
+srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c,
+                                     uint8_t *iv,
+                                     int direction)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+
+    return (((c)->type)->set_iv(((c)->state), iv, direction));
+}
+
+srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c,
+                                     uint8_t *buffer,
+                                     uint32_t *num_octets_to_output)
+{
+    /* zeroize the buffer */
+    octet_string_set_to_zero(buffer, *num_octets_to_output);
+
+    /* exor keystream into buffer */
+    return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
+}
+
+srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c,
+                                      uint8_t *buffer,
+                                      uint32_t *num_octets_to_output)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+
+    return (((c)->type)->encrypt(((c)->state), buffer, num_octets_to_output));
+}
+
+srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c,
+                                      uint8_t *buffer,
+                                      uint32_t *num_octets_to_output)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+
+    return (((c)->type)->decrypt(((c)->state), buffer, num_octets_to_output));
+}
+
+srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c,
+                                      uint8_t *buffer,
+                                      uint32_t *tag_len)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+    if (!((c)->type)->get_tag) {
+        return (srtp_err_status_no_such_op);
+    }
+
+    return (((c)->type)->get_tag(((c)->state), buffer, tag_len));
+}
+
+srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c,
+                                      const uint8_t *aad,
+                                      uint32_t aad_len)
+{
+    if (!c || !c->type || !c->state) {
+        return (srtp_err_status_bad_param);
+    }
+    if (!((c)->type)->set_aad) {
+        return (srtp_err_status_no_such_op);
+    }
+
+    return (((c)->type)->set_aad(((c)->state), aad, aad_len));
 }
 
 /* some bookkeeping functions */
 
-int
-cipher_get_key_length(const cipher_t *c) {
-  return c->key_len;
+int srtp_cipher_get_key_length(const srtp_cipher_t *c)
+{
+    return c->key_len;
 }
 
-/* 
- * cipher_type_test(ct, test_data) tests a cipher of type ct against
+/*
+ * A trivial platform independent random source.  The random
+ * data is used for some of the cipher self-tests.
+ */
+static srtp_err_status_t srtp_cipher_rand(void *dest, uint32_t len)
+{
+#if defined(HAVE_RAND_S)
+    uint8_t *dst = (uint8_t *)dest;
+    while (len) {
+        unsigned int val;
+        errno_t err = rand_s(&val);
+
+        if (err != 0)
+            return srtp_err_status_fail;
+
+        *dst++ = val & 0xff;
+        len--;
+    }
+#else
+    /* Generic C-library (rand()) version */
+    /* This is a random source of last resort */
+    uint8_t *dst = (uint8_t *)dest;
+    while (len) {
+        int val = rand();
+        /* rand() returns 0-32767 (ugh) */
+        /* Is this a good enough way to get random bytes?
+           It is if it passes FIPS-140... */
+        *dst++ = val & 0xff;
+        len--;
+    }
+#endif
+    return srtp_err_status_ok;
+}
+
+#define SELF_TEST_BUF_OCTETS 128
+#define NUM_RAND_TESTS 128
+#define MAX_KEY_LEN 64
+/*
+ * srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against
  * test cases provided in a list test_data of values of key, salt, iv,
  * plaintext, and ciphertext that is known to be good
  */
-
-#define SELF_TEST_BUF_OCTETS 128
-#define NUM_RAND_TESTS       128
-#define MAX_KEY_LEN          64
-
-err_status_t
-cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
-  const cipher_test_case_t *test_case = test_data;
-  cipher_t *c;
-  err_status_t status;
-  uint8_t buffer[SELF_TEST_BUF_OCTETS];
-  uint8_t buffer2[SELF_TEST_BUF_OCTETS];
-  unsigned int len;
-  int i, j, case_num = 0;
+srtp_err_status_t srtp_cipher_type_test(
+    const srtp_cipher_type_t *ct,
+    const srtp_cipher_test_case_t *test_data)
+{
+    const srtp_cipher_test_case_t *test_case = test_data;
+    srtp_cipher_t *c;
+    srtp_err_status_t status;
+    uint8_t buffer[SELF_TEST_BUF_OCTETS];
+    uint8_t buffer2[SELF_TEST_BUF_OCTETS];
+    uint32_t tag_len;
+    unsigned int len;
+    int i, j, case_num = 0;
+    unsigned k = 0;
 
-  debug_print(mod_cipher, "running self-test for cipher %s", 
-	      ct->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_cipher, "running self-test for cipher %s",
+                ct->description);
 
-  /*
-   * loop over all test cases, perform known-answer tests of both the
-   * encryption and decryption functions
-   */  
-  while (test_case != NULL) {
-
-    /* allocate cipher */
-    status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
-    if (status)
-      return status;
-    
     /*
-     * test the encrypt function 
+     * 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
      */
-    debug_print(mod_cipher, "testing encryption", NULL);    
-    
-    /* initialize cipher */
-    status = cipher_init(c, test_case->key, direction_encrypt);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }
-    
-    /* copy plaintext into test buffer */
-    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
-      cipher_dealloc(c);    
-      return err_status_bad_param;
-    }
-    for (i=0; i < test_case->plaintext_length_octets; i++)
-      buffer[i] = test_case->plaintext[i];
-
-    debug_print(mod_cipher, "plaintext:    %s",
-	     octet_string_hex_string(buffer,
-				     test_case->plaintext_length_octets));
-
-    /* set the initialization vector */
-    status = cipher_set_iv(c, test_case->idx);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    } 
-    
-    /* encrypt */
-    len = test_case->plaintext_length_octets;
-    status = cipher_encrypt(c, buffer, &len);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }
-    
-    debug_print(mod_cipher, "ciphertext:   %s",
-	     octet_string_hex_string(buffer,
-				     test_case->ciphertext_length_octets));
-
-    /* compare the resulting ciphertext with that in the test case */
-    if (len != (unsigned int)test_case->ciphertext_length_octets)
-      return err_status_algo_fail;
-    status = err_status_ok;
-    for (i=0; i < test_case->ciphertext_length_octets; i++)
-      if (buffer[i] != test_case->ciphertext[i]) {
-	status = err_status_algo_fail;
-	debug_print(mod_cipher, "test case %d failed", case_num);
-	debug_print(mod_cipher, "(failure at byte %d)", i);
-	break;
-      }
-    if (status) {
-
-      debug_print(mod_cipher, "c computed: %s",
-	     octet_string_hex_string(buffer,
-		  2*test_case->plaintext_length_octets));
-      debug_print(mod_cipher, "c expected: %s",
-		  octet_string_hex_string(test_case->ciphertext,
-			  2*test_case->plaintext_length_octets));
-
-      cipher_dealloc(c);
-      return err_status_algo_fail;
+    if (test_case == NULL) {
+        return srtp_err_status_cant_check;
     }
 
     /*
-     * test the decrypt function
+     * loop over all test cases, perform known-answer tests of both the
+     * encryption and decryption functions
      */
-    debug_print(mod_cipher, "testing decryption", NULL);    
+    while (test_case != NULL) {
+        /* allocate cipher */
+        status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
+                                        test_case->tag_length_octets);
+        if (status) {
+            return status;
+        }
+
+        /*
+         * test the encrypt function
+         */
+        debug_print(srtp_mod_cipher, "testing encryption", NULL);
 
-    /* re-initialize cipher for decryption */
-    status = cipher_init(c, test_case->key, direction_decrypt);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }
+        /* initialize cipher */
+        status = srtp_cipher_init(c, test_case->key);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        /* copy plaintext into test buffer */
+        if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_bad_param;
+        }
+        for (k = 0; k < test_case->plaintext_length_octets; k++) {
+            buffer[k] = test_case->plaintext[k];
+        }
+
+        debug_print(srtp_mod_cipher, "plaintext:    %s",
+                    srtp_octet_string_hex_string(
+                        buffer, test_case->plaintext_length_octets));
+
+        /* set the initialization vector */
+        status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
+                                    srtp_direction_encrypt);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
 
-    /* copy ciphertext into test buffer */
-    if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
-      cipher_dealloc(c);    
-      return err_status_bad_param;
-    }
-    for (i=0; i < test_case->ciphertext_length_octets; i++)
-      buffer[i] = test_case->ciphertext[i];
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            debug_print(srtp_mod_cipher, "IV:    %s",
+                        srtp_octet_string_hex_string(test_case->idx, 12));
+
+            /*
+             * Set the AAD
+             */
+            status = srtp_cipher_set_aad(c, test_case->aad,
+                                         test_case->aad_length_octets);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            debug_print(srtp_mod_cipher, "AAD:    %s",
+                        srtp_octet_string_hex_string(
+                            test_case->aad, test_case->aad_length_octets));
+        }
 
-    debug_print(mod_cipher, "ciphertext:    %s",
-		octet_string_hex_string(buffer,
-					test_case->plaintext_length_octets));
+        /* encrypt */
+        len = test_case->plaintext_length_octets;
+        status = srtp_cipher_encrypt(c, buffer, &len);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            /*
+             * Get the GCM tag
+             */
+            status = srtp_cipher_get_tag(c, buffer + len, &tag_len);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            len += tag_len;
+        }
+
+        debug_print(srtp_mod_cipher, "ciphertext:   %s",
+                    srtp_octet_string_hex_string(
+                        buffer, test_case->ciphertext_length_octets));
 
-    /* set the initialization vector */
-    status = cipher_set_iv(c, test_case->idx);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    } 
-    
-    /* decrypt */
-    len = test_case->ciphertext_length_octets;
-    status = cipher_decrypt(c, buffer, &len);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }
-    
-    debug_print(mod_cipher, "plaintext:   %s",
-	     octet_string_hex_string(buffer,
-				     test_case->plaintext_length_octets));
+        /* compare the resulting ciphertext with that in the test case */
+        if (len != test_case->ciphertext_length_octets) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
+        status = srtp_err_status_ok;
+        for (k = 0; k < test_case->ciphertext_length_octets; k++) {
+            if (buffer[k] != test_case->ciphertext[k]) {
+                status = srtp_err_status_algo_fail;
+                debug_print(srtp_mod_cipher, "test case %d failed", case_num);
+                debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
+                break;
+            }
+        }
+        if (status) {
+            debug_print(srtp_mod_cipher, "c computed: %s",
+                        srtp_octet_string_hex_string(
+                            buffer, 2 * test_case->plaintext_length_octets));
+            debug_print(srtp_mod_cipher, "c expected: %s",
+                        srtp_octet_string_hex_string(
+                            test_case->ciphertext,
+                            2 * test_case->plaintext_length_octets));
+
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
+
+        /*
+         * test the decrypt function
+         */
+        debug_print(srtp_mod_cipher, "testing decryption", NULL);
+
+        /* re-initialize cipher for decryption */
+        status = srtp_cipher_init(c, test_case->key);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        /* copy ciphertext into test buffer */
+        if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_bad_param;
+        }
+        for (k = 0; k < test_case->ciphertext_length_octets; k++) {
+            buffer[k] = test_case->ciphertext[k];
+        }
+
+        debug_print(srtp_mod_cipher, "ciphertext:    %s",
+                    srtp_octet_string_hex_string(
+                        buffer, test_case->plaintext_length_octets));
+
+        /* set the initialization vector */
+        status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
+                                    srtp_direction_decrypt);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
 
-    /* compare the resulting plaintext with that in the test case */
-    if (len != (unsigned int)test_case->plaintext_length_octets)
-      return err_status_algo_fail;
-    status = err_status_ok;
-    for (i=0; i < test_case->plaintext_length_octets; i++)
-      if (buffer[i] != test_case->plaintext[i]) {
-	status = err_status_algo_fail;
-	debug_print(mod_cipher, "test case %d failed", case_num);
-	debug_print(mod_cipher, "(failure at byte %d)", i);
-      }
-    if (status) {
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            /*
+             * Set the AAD
+             */
+            status = srtp_cipher_set_aad(c, test_case->aad,
+                                         test_case->aad_length_octets);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            debug_print(srtp_mod_cipher, "AAD:    %s",
+                        srtp_octet_string_hex_string(
+                            test_case->aad, test_case->aad_length_octets));
+        }
+
+        /* decrypt */
+        len = test_case->ciphertext_length_octets;
+        status = srtp_cipher_decrypt(c, buffer, &len);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        debug_print(srtp_mod_cipher, "plaintext:   %s",
+                    srtp_octet_string_hex_string(
+                        buffer, test_case->plaintext_length_octets));
 
-      debug_print(mod_cipher, "p computed: %s",
-	     octet_string_hex_string(buffer,
-		  2*test_case->plaintext_length_octets));
-      debug_print(mod_cipher, "p expected: %s",
-		  octet_string_hex_string(test_case->plaintext,
-			  2*test_case->plaintext_length_octets));
+        /* compare the resulting plaintext with that in the test case */
+        if (len != test_case->plaintext_length_octets) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
+        status = srtp_err_status_ok;
+        for (k = 0; k < test_case->plaintext_length_octets; k++) {
+            if (buffer[k] != test_case->plaintext[k]) {
+                status = srtp_err_status_algo_fail;
+                debug_print(srtp_mod_cipher, "test case %d failed", case_num);
+                debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
+            }
+        }
+        if (status) {
+            debug_print(srtp_mod_cipher, "p computed: %s",
+                        srtp_octet_string_hex_string(
+                            buffer, 2 * test_case->plaintext_length_octets));
+            debug_print(srtp_mod_cipher, "p expected: %s",
+                        srtp_octet_string_hex_string(
+                            test_case->plaintext,
+                            2 * test_case->plaintext_length_octets));
 
-      cipher_dealloc(c);
-      return err_status_algo_fail;
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
+
+        /* deallocate the cipher */
+        status = srtp_cipher_dealloc(c);
+        if (status) {
+            return status;
+        }
+
+        /*
+         * the cipher passed the test case, so move on to the next test
+         * case in the list; if NULL, we'l proceed to the next test
+         */
+        test_case = test_case->next_test_case;
+        ++case_num;
     }
 
-    /* deallocate the cipher */
-    status = cipher_dealloc(c);
-    if (status)
-      return status;
-    
-    /* 
-     * the cipher passed the test case, so move on to the next test
-     * case in the list; if NULL, we'l proceed to the next test
-     */   
-    test_case = test_case->next_test_case;
-    ++case_num;
-  }
-  
-  /* now run some random invertibility tests */
-
-  /* allocate cipher, using paramaters from the first test case */
-  test_case = test_data;
-  status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
-  if (status)
-      return status;
-  
-  rand_source_init();
-  
-  for (j=0; j < NUM_RAND_TESTS; j++) {
-    unsigned length;
-    int plaintext_len;
-    uint8_t key[MAX_KEY_LEN];
-    uint8_t  iv[MAX_KEY_LEN];
+    /* now run some random invertibility tests */
 
-    /* choose a length at random (leaving room for IV and padding) */
-    length = rand() % (SELF_TEST_BUF_OCTETS - 64);
-    debug_print(mod_cipher, "random plaintext length %d\n", length);
-    status = rand_source_get_octet_string(buffer, length);
-    if (status) return status;
-
-    debug_print(mod_cipher, "plaintext:    %s",
-		octet_string_hex_string(buffer, length));
-
-    /* copy plaintext into second buffer */
-    for (i=0; (unsigned int)i < length; i++)
-      buffer2[i] = buffer[i];
-    
-    /* choose a key at random */
-    if (test_case->key_length_octets > MAX_KEY_LEN)
-      return err_status_cant_check;
-    status = rand_source_get_octet_string(key, test_case->key_length_octets);
-    if (status) return status;
-
-   /* chose a random initialization vector */
-    status = rand_source_get_octet_string(iv, MAX_KEY_LEN);
-    if (status) return status;
-        
-    /* initialize cipher */
-    status = cipher_init(c, key, direction_encrypt);
+    /* allocate cipher, using paramaters from the first test case */
+    test_case = test_data;
+    status = srtp_cipher_type_alloc(ct, &c, test_case->key_length_octets,
+                                    test_case->tag_length_octets);
     if (status) {
-      cipher_dealloc(c);
-      return status;
+        return status;
     }
 
-    /* set initialization vector */
-    status = cipher_set_iv(c, test_case->idx);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    } 
+    for (j = 0; j < NUM_RAND_TESTS; j++) {
+        unsigned int length;
+        unsigned int plaintext_len;
+        uint8_t key[MAX_KEY_LEN];
+        uint8_t iv[MAX_KEY_LEN];
+
+        /* choose a length at random (leaving room for IV and padding) */
+        length = rand() % (SELF_TEST_BUF_OCTETS - 64);
+        debug_print(srtp_mod_cipher, "random plaintext length %d\n", length);
+        status = srtp_cipher_rand(buffer, length);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        debug_print(srtp_mod_cipher, "plaintext:    %s",
+                    srtp_octet_string_hex_string(buffer, length));
+
+        /* copy plaintext into second buffer */
+        for (i = 0; (unsigned int)i < length; i++) {
+            buffer2[i] = buffer[i];
+        }
+
+        /* choose a key at random */
+        if (test_case->key_length_octets > MAX_KEY_LEN) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_cant_check;
+        }
+        status = srtp_cipher_rand(key, test_case->key_length_octets);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        /* chose a random initialization vector */
+        status = srtp_cipher_rand(iv, MAX_KEY_LEN);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        /* initialize cipher */
+        status = srtp_cipher_init(c, key);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        /* set initialization vector */
+        status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
+                                    srtp_direction_encrypt);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            /*
+             * Set the AAD
+             */
+            status = srtp_cipher_set_aad(c, test_case->aad,
+                                         test_case->aad_length_octets);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            debug_print(srtp_mod_cipher, "AAD:    %s",
+                        srtp_octet_string_hex_string(
+                            test_case->aad, test_case->aad_length_octets));
+        }
 
-    /* encrypt buffer with cipher */
-    plaintext_len = length;
-    status = cipher_encrypt(c, buffer, &length);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
+        /* encrypt buffer with cipher */
+        plaintext_len = length;
+        status = srtp_cipher_encrypt(c, buffer, &length);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            /*
+             * Get the GCM tag
+             */
+            status = srtp_cipher_get_tag(c, buffer + length, &tag_len);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            length += tag_len;
+        }
+        debug_print(srtp_mod_cipher, "ciphertext:   %s",
+                    srtp_octet_string_hex_string(buffer, length));
+
+        /*
+         * re-initialize cipher for decryption, re-set the iv, then
+         * decrypt the ciphertext
+         */
+        status = srtp_cipher_init(c, key);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+        status = srtp_cipher_set_iv(c, (uint8_t *)test_case->idx,
+                                    srtp_direction_decrypt);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+        if (c->algorithm == SRTP_AES_GCM_128 ||
+            c->algorithm == SRTP_AES_GCM_256) {
+            /*
+             * Set the AAD
+             */
+            status = srtp_cipher_set_aad(c, test_case->aad,
+                                         test_case->aad_length_octets);
+            if (status) {
+                srtp_cipher_dealloc(c);
+                return status;
+            }
+            debug_print(srtp_mod_cipher, "AAD:    %s",
+                        srtp_octet_string_hex_string(
+                            test_case->aad, test_case->aad_length_octets));
+        }
+        status = srtp_cipher_decrypt(c, buffer, &length);
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return status;
+        }
+
+        debug_print(srtp_mod_cipher, "plaintext[2]: %s",
+                    srtp_octet_string_hex_string(buffer, length));
+
+        /* compare the resulting plaintext with the original one */
+        if (length != plaintext_len) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
+        status = srtp_err_status_ok;
+        for (k = 0; k < plaintext_len; k++) {
+            if (buffer[k] != buffer2[k]) {
+                status = srtp_err_status_algo_fail;
+                debug_print(srtp_mod_cipher, "random test case %d failed",
+                            case_num);
+                debug_print(srtp_mod_cipher, "(failure at byte %u)", k);
+            }
+        }
+        if (status) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_algo_fail;
+        }
     }
-    debug_print(mod_cipher, "ciphertext:   %s",
-		octet_string_hex_string(buffer, length));
 
-    /* 
-     * re-initialize cipher for decryption, re-set the iv, then
-     * decrypt the ciphertext
-     */
-    status = cipher_init(c, key, direction_decrypt);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }
-    status = cipher_set_iv(c, test_case->idx);
+    status = srtp_cipher_dealloc(c);
     if (status) {
-      cipher_dealloc(c);
-      return status;
-    } 
-    status = cipher_decrypt(c, buffer, &length);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
-    }    
-
-    debug_print(mod_cipher, "plaintext[2]: %s",
-		octet_string_hex_string(buffer, length));    
+        return status;
+    }
 
-    /* compare the resulting plaintext with the original one */
-    if (length != (unsigned)plaintext_len)
-      return err_status_algo_fail;
-    status = err_status_ok;
-    for (i=0; i < plaintext_len; i++)
-      if (buffer[i] != buffer2[i]) {
-	status = err_status_algo_fail;
-	debug_print(mod_cipher, "random test case %d failed", case_num);
-	debug_print(mod_cipher, "(failure at byte %d)", i);
-      }
-    if (status) {
-      cipher_dealloc(c);
-      return err_status_algo_fail;
-    }
-        
-  }
-
-  status = cipher_dealloc(c);
-  if (status)
-    return status;
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
-/* 
- * cipher_type_self_test(ct) performs cipher_type_test on ct's internal
- * list of test data.
+/*
+ * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's
+ * internal list of test data.
  */
-
-err_status_t
-cipher_type_self_test(const cipher_type_t *ct) {
-  return cipher_type_test(ct, ct->test_data);
+srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct)
+{
+    return srtp_cipher_type_test(ct, ct->test_data);
 }
 
 /*
  * 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, the value 0 is returned
  */
-
-uint64_t
-cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {
-  int i;
-  v128_t nonce;
-  clock_t timer;
-  unsigned char *enc_buf;
-  unsigned int len = octets_in_buffer;
+uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
+                                     int octets_in_buffer,
+                                     int num_trials)
+{
+    int i;
+    v128_t nonce;
+    clock_t timer;
+    unsigned char *enc_buf;
+    unsigned int len = octets_in_buffer;
 
-  enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer);
-  if (enc_buf == NULL)
-    return 0;  /* indicate bad parameters by returning null */
-  
-  /* time repeated trials */
-  v128_set_to_zero(&nonce);
-  timer = clock();
-  for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
-    cipher_set_iv(c, &nonce);
-    cipher_encrypt(c, enc_buf, &len);
-  }
-  timer = clock() - timer;
+    enc_buf = (unsigned char *)srtp_crypto_alloc(octets_in_buffer);
+    if (enc_buf == NULL) {
+        return 0; /* indicate bad parameters by returning null */
+    }
+    /* time repeated trials */
+    v128_set_to_zero(&nonce);
+    timer = clock();
+    for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
+        if (srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt) !=
+            srtp_err_status_ok) {
+            srtp_crypto_free(enc_buf);
+            return 0;
+        }
+        if (srtp_cipher_encrypt(c, enc_buf, &len) != srtp_err_status_ok) {
+            srtp_crypto_free(enc_buf);
+            return 0;
+        }
+    }
+    timer = clock() - timer;
 
-  crypto_free(enc_buf);
+    srtp_crypto_free(enc_buf);
 
-  if (timer == 0) {
-    /* Too fast! */
-    return 0;
-  }
-  
-  return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
+    if (timer == 0) {
+        /* Too fast! */
+        return 0;
+    }
+
+    return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
 }
--- a/netwerk/srtp/src/crypto/cipher/null_cipher.c
+++ b/netwerk/srtp/src/crypto/cipher/null_cipher.c
@@ -4,150 +4,150 @@
  * A null cipher implementation.  This cipher leaves the plaintext
  * unchanged.
  *
  * 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
  * 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 "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;
+#include "cipher_types.h"
 
-err_status_t
-null_cipher_alloc(cipher_t **c, int key_len) {
-  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;
+
+    debug_print(srtp_mod_cipher, "allocating cipher with key length %d",
+                key_len);
 
-  /* 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;
+    /* 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;
+    }
 
-  /* set pointers */
-  *c = (cipher_t *)pointer;
-  (*c)->type = &null_cipher;
-  (*c)->state = pointer + sizeof(cipher_t);
+    /* set pointers */
+    (*c)->algorithm = SRTP_NULL_CIPHER;
+    (*c)->type = &srtp_null_cipher;
+    (*c)->state = (void *)0x1; /* The null cipher does not maintain state */
 
-  /* set key size */
-  (*c)->key_len = key_len;
+    /* set key size */
+    (*c)->key_len = key_len;
 
-  /* increment ref_count */
-  null_cipher.ref_count++;
-  
-  return err_status_ok;
-  
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_cipher_dealloc(cipher_t *c) {
-  extern cipher_type_t null_cipher;
-
-  /* zeroize entire state*/
-  octet_string_set_to_zero((uint8_t *)c, 
-			   sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
+static srtp_err_status_t srtp_null_cipher_dealloc(srtp_cipher_t *c)
+{
+    extern const srtp_cipher_type_t srtp_null_cipher;
 
-  /* free memory of type null_cipher */
-  crypto_free(c);
+    /* zeroize entire state*/
+    octet_string_set_to_zero(c, sizeof(srtp_cipher_t));
 
-  /* decrement reference count */
-  null_cipher.ref_count--;
-  
-  return err_status_ok;
-  
+    /* free memory of type null_cipher */
+    srtp_crypto_free(c);
+
+    return srtp_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               */
-  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 */
 };
 
-
 /*
  * 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_encrypt_func_t)       null_cipher_encrypt,
-  (cipher_decrypt_func_t)       null_cipher_encrypt,
-  (cipher_set_iv_func_t)        null_cipher_set_iv,
-  (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              /* */
 };
-
--- a/netwerk/srtp/src/crypto/hash/auth.c
+++ b/netwerk/srtp/src/crypto/hash/auth.c
@@ -3,181 +3,185 @@
  *
  * some bookkeeping functions for authentication functions
  *
  * 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
  * 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 "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
  */
 
 /* 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;
-
-  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;
+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;
 
-  /* loop over all test cases */  
-  while (test_case != NULL) {
+    debug_print(srtp_mod_auth, "running self-test for auth function %s",
+                at->description);
 
-    /* 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 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;
+        }
 
-    /* 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;
+        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
+/*
+ * srtp_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);
 }
-
--- a/netwerk/srtp/src/crypto/hash/hmac.c
+++ b/netwerk/srtp/src/crypto/hash/hmac.c
@@ -1,268 +1,283 @@
 /*
  * 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
  * 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 "hmac.h" 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "hmac.h"
 #include "alloc.h"
+#include "cipher_types.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 key length - note that we don't support keys larger
+     * than 20 bytes yet
+     */
+    if (key_len > 20) {
+        return srtp_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;
+    /* check output length - should be less than 20 bytes */
+    if (out_len > 20) {
+        return srtp_err_status_bad_param;
+    }
 
-  /* 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;
+    /* 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;
+    }
 
-  /* increment global count of all hmac uses */
-  hmac.ref_count++;
+    /* 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 err_status_ok;
+    return srtp_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));
+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));
+
+    /* free memory */
+    srtp_crypto_free(a);
+
+    return srtp_err_status_ok;
+}
+
+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];
 
-  /* free memory */
-  crypto_free(a);
-  
-  /* decrement global count of all hmac uses */
-  hmac.ref_count--;
+    /*
+     * 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_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;
-  }  
+static srtp_err_status_t srtp_hmac_start(void *statev)
+{
+    srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
 
-  debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
-  
-  /* initialize sha1 context */
-  sha1_init(&state->init_ctx);
+    memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
 
-  /* hash ipad ^ key */
-  sha1_update(&state->init_ctx, ipad, 64);
-  memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); 
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-hmac_start(hmac_ctx_t *state) {
-    
-  memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
-
-  return err_status_ok;
-}
+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;
 
-err_status_t
-hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {
+    debug_print(srtp_mod_hmac, "input: %s",
+                srtp_octet_string_hex_string(message, msg_octets));
 
-  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);
+    /* hash message into sha1 context */
+    srtp_sha1_update(&state->ctx, message, msg_octets);
 
-  return err_status_ok;
+    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_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 err_status_bad_param;
-  
-  /* hash message, copy output into H */
-  hmac_update(state, (const uint8_t*)message, msg_octets);
-  sha1_final(&state->ctx, H);
+    /* 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(mod_hmac, "intermediate state: %s", 
-	      octet_string_hex_string((uint8_t *)H, 20));
+    /*
+     * 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 */
-  sha1_init(&state->ctx);
-  
-  /* hash opad ^ key  */
-  sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
+    /* 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 */
-  sha1_update(&state->ctx, (uint8_t *)H, 20);
-  
-  /* the result is returned in the array hash_value[] */
-  sha1_final(&state->ctx, hash_value);
+    /* 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];
+    /* copy hash_value to *result */
+    for (i = 0; i < tag_len; i++) {
+        result[i] = ((uint8_t *)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((uint8_t *)hash_value, tag_len));
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
 /* begin test case 0 */
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_key[20] = {
+    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+    0x0b, 0x0b, 0x0b, 0x0b
+};
+/* clang-format on */
 
-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
+/* clang-format off */
+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_data[8] = {
-  0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65   /* "Hi There" */
-};
+/* clang-format on */
 
-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
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_tag[20] = {
+    0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
+    0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
+    0xf1, 0x46, 0xbe, 0x00
 };
+/* clang-format on */
 
-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          /* */
 };
-
--- a/netwerk/srtp/src/crypto/hash/null_auth.c
+++ b/netwerk/srtp/src/crypto/hash/null_auth.c
@@ -4,159 +4,165 @@
  * implements the do-nothing auth algorithm
  *
  * 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
  * 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 "null_auth.h" 
-#include "alloc.h"
-
-/* null_auth uses the auth debug module */
-
-extern debug_module_t mod_auth;
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-err_status_t
-null_auth_alloc(auth_t **a, int key_len, int out_len) {
-  extern auth_type_t null_auth;
-  uint8_t *pointer;
+#include "null_auth.h"
+#include "err.h" /* for srtp_debug */
+#include "alloc.h"
+#include "cipher_types.h"
 
-  debug_print(mod_auth, "allocating auth func with key length %d", key_len);
-  debug_print(mod_auth, "                          tag length %d", out_len);
+static srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a,
+                                              int key_len,
+                                              int out_len)
+{
+    extern const srtp_auth_type_t srtp_null_auth;
+    uint8_t *pointer;
 
-  /* 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;
+    debug_print(srtp_mod_auth, "allocating auth func with key length %d",
+                key_len);
+    debug_print(srtp_mod_auth, "                          tag length %d",
+                out_len);
 
-  /* 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;
+    /* 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;
+    }
 
-  /* increment global count of all null_auth uses */
-  null_auth.ref_count++;
+    /* 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;
 
-  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;
+
+    /* zeroize entire state*/
+    octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) +
+                                    sizeof(srtp_auth_t));
+
+    /* free memory */
+    srtp_crypto_free(a);
 
-  /* free memory */
-  crypto_free(a);
-  
-  /* decrement global count of all null_auth uses */
-  null_auth.ref_count--;
+    return srtp_err_status_ok;
+}
 
-  return err_status_ok;
+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 */
+
+    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_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; */
 
-  /* 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_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_update(null_auth_ctx_t *state, uint8_t *message,
-		   int msg_octets) {
+static srtp_err_status_t srtp_null_auth_start(void *statev)
+{
+    /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
 
-  return err_status_ok;
-}
-
-err_status_t
-null_auth_start(null_auth_ctx_t *state) {
-  return err_status_ok;
+    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               /* */
 };
-
--- a/netwerk/srtp/src/crypto/hash/sha1.c
+++ b/netwerk/srtp/src/crypto/hash/sha1.c
@@ -4,402 +4,471 @@
  * an implementation of the Secure Hash Algorithm v.1 (SHA-1),
  * specified in FIPS 180-1
  *
  * 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
  * 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 "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 */
-#define S1(X)  ((X << 1)  | (X >> 31))
-#define S5(X)  ((X << 5)  | (X >> 27))
+#define S1(X) ((X << 1) | (X >> 31))
+#define S5(X) ((X << 5) | (X >> 27))
 #define S30(X) ((X << 30) | (X >> 2))
 
-#define f0(B,C,D) ((B & C) | (~B & D))              
-#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
  */
 
-uint32_t SHA_K0 = 0x5A827999;   /* Kt for 0  <= t <= 19 */
-uint32_t SHA_K1 = 0x6ED9EBA1;   /* Kt for 20 <= t <= 39 */
-uint32_t SHA_K2 = 0x8F1BBCDC;   /* Kt for 40 <= t <= 59 */
-uint32_t SHA_K3 = 0xCA62C1D6;   /* Kt for 60 <= t <= 79 */
+uint32_t SHA_K0 = 0x5A827999; /* Kt for 0  <= t <= 19 */
+uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
+uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
+uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
 
-void
-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)
  *
  *  this function does not do any of the padding required in the
  *  complete SHA1 function
  *
  *  this function is used in the SEAL 3.0 key setup routines
  *  (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);      
-  }
+    /* 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;
+    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;
-  }
+    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;
+    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;
+    return;
 }
 
-void
-sha1_init(sha1_ctx_t *ctx) {
+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;
 
-  /* 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;
 
-  /* indicate that message buffer is empty */
-  ctx->octets_in_buffer = 0;
-
-  /* reset message bit-count to zero */
-  ctx->num_bits_in_msg = 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;
+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) {
+    /* update message bit-count */
+    ctx->num_bits_in_msg += octets_in_msg * 8;
 
-      /* 
-       * 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;
+    /* 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);
+            /* process a whole block */
 
-      sha1_core(ctx->M, ctx->H);
+            debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()",
+                        NULL);
 
-    } else {
+            srtp_sha1_core(ctx->M, ctx->H);
 
-      debug_print(mod_sha1, "(update) not running sha1_core()", NULL);
+        } 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;
+            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]);
+        }
 
-  /*
-   * process the remaining octets_in_buffer, padding and terminating as
-   * necessary
-   */
-  {
-    int tail = ctx->octets_in_buffer % 4;
+        /* 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;
+        }
 
-    /* copy/xor message into array */
-    for (i=0; i < (ctx->octets_in_buffer+3)/4; i++) 
-      W[i]  = be32_to_cpu(ctx->M[i]);
+        /* zeroize remaining words */
+        for (i++; i < 15; i++) {
+            W[i] = 0x0;
+        }
 
-    /* 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;
-    }
+        /*
+         * 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];
 
-    /* zeroize remaining words */
-    for (i++   ; i < 15; i++)
-      W[i] = 0x0;
+        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 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);
+        ctx->H[0] += A;
+        ctx->H[1] += B;
+        ctx->H[2] += C;
+        ctx->H[3] += D;
+        ctx->H[4] += E;
     }
 
-    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);
+
+    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;
+        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;
-
-  }
-
-  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];
+    /* 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]);
 
-    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;
-    }
+    /* indicate that message buffer in context is empty */
+    ctx->octets_in_buffer = 0;
 
-    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;
 }
-
-
-
--- a/netwerk/srtp/src/crypto/include/aes.h
+++ b/netwerk/srtp/src/crypto/include/aes.h
@@ -3,87 +3,81 @@
  *
  * header file for the AES block cipher
  *
  * 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
  * 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_H
-#define _AES_H
-
-#include "config.h"
+#ifndef AES_H
+#define AES_H
 
 #include "datatypes.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);
-
-err_status_t
-aes_expand_decryption_key(const uint8_t *key,
-			  int key_len,
-			  aes_expanded_key_t *expanded_key);
-
-void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
+srtp_err_status_t srtp_aes_expand_encryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key);
 
-void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
+srtp_err_status_t srtp_aes_expand_decryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key);
 
-#if 0
-/*
- * internal functions 
- */
+void srtp_aes_encrypt(v128_t *plaintext,
+                      const srtp_aes_expanded_key_t *exp_key);
 
-void
-aes_init_sbox(void);
+void srtp_aes_decrypt(v128_t *plaintext,
+                      const srtp_aes_expanded_key_t *exp_key);
 
-void
-aes_compute_tables(void);
-#endif 
+#ifdef __cplusplus
+}
+#endif
 
-#endif /* _AES_H */
+#endif /* AES_H */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/aes_cbc.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * aes_cbc.h
- *
- * Header for AES Cipher Blobk 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.
- *
- */
-
-#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        */
-  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, cipher_direction_t dir);
-
-err_status_t
-aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv);
-
-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 */
-
--- a/netwerk/srtp/src/crypto/include/aes_icm.h
+++ b/netwerk/srtp/src/crypto/include/aes_icm.h
@@ -2,37 +2,38 @@
  * aes_icm.h
  *
  * Header for AES Integer Counter Mode.
  *
  * 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
  * 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)
@@ -45,48 +46,17 @@
 
 #ifndef AES_ICM_H
 #define AES_ICM_H
 
 #include "aes.h"
 #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);
-
-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);
+    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 */
-
--- a/netwerk/srtp/src/crypto/include/alloc.h
+++ b/netwerk/srtp/src/crypto/include/alloc.h
@@ -1,57 +1,76 @@
 /*
  * alloc.h
  *
- * interface to memory allocation and deallocation, with optional debugging 
+ * interface to memory allocation and deallocation, with optional debugging
  *
  * David A. McGrew
  * Cisco Systems, Inc.
  */
 /*
- *	
- * Copyright (c) 2001-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
  * 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 CRYPTO_ALLOC_H
 #define CRYPTO_ALLOC_H
 
 #include "datatypes.h"
 
-void *
-crypto_alloc(size_t size);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-void
-crypto_free(void *ptr);
+/*
+ * srtp_crypto_alloc
+ *
+ * Allocates a block of memory  of given size. The memory will be
+ * initialized to zero's. Free the memory with a call to srtp_crypto_free.
+ *
+ * returns pointer to memory on success or else NULL
+ */
+void *srtp_crypto_alloc(size_t size);
+
+/*
+ * srtp_crypto_free
+ *
+ * Frees the block of memory  ptr previously  allocated with
+ * srtp_crypto_alloc
+ */
+void srtp_crypto_free(void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* CRYPTO_ALLOC_H */
--- a/netwerk/srtp/src/crypto/include/auth.h
+++ b/netwerk/srtp/src/crypto/include/auth.h
@@ -3,169 +3,171 @@
  *
  * common interface to authentication functions
  *
  * 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
  * 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 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 err_status_t (*auth_init_func)
-     (void *state, const uint8_t *key, int key_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_dealloc_func)(auth_pointer_t ap);
+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_compute_func)
-     (void *state, uint8_t *buffer, int octets_to_auth, 
-      int tag_len, uint8_t *tag);
+typedef srtp_err_status_t (*srtp_auth_init_func)(void *state,
+                                                 const uint8_t *key,
+                                                 int key_len);
+
+typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap);
 
-typedef 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 err_status_t (*auth_start_func)(void *state);
-     
-/* some syntactic sugar on these function types */
+typedef srtp_err_status_t (*srtp_auth_update_func)(void *state,
+                                                   const uint8_t *buffer,
+                                                   int octets_to_auth);
 
-#define auth_type_alloc(at, a, klen, outlen)                        \
-                 ((at)->alloc((a), (klen), (outlen)))
+typedef srtp_err_status_t (*srtp_auth_start_func)(void *state);
 
-#define auth_init(a, key)                                           \
-                 (((a)->type)->init((a)->state, (key), ((a)->key_len)))
+/* some syntactic sugar on these function types */
+#define srtp_auth_type_alloc(at, a, klen, outlen)                              \
+    ((at)->alloc((a), (klen), (outlen)))
 
-#define auth_compute(a, buf, len, res)                              \
-       (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
+#define srtp_auth_init(a, key)                                                 \
+    (((a)->type)->init((a)->state, (key), ((a)->key_len)))
 
-#define auth_update(a, buf, len)                                    \
-       (((a)->type)->update((a)->state, (buf), (len)))
+#define srtp_auth_compute(a, buf, len, res)                                    \
+    (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
 
-#define auth_start(a)(((a)->type)->start((a)->state))
+#define srtp_auth_update(a, buf, len)                                          \
+    (((a)->type)->update((a)->state, (buf), (len)))
 
-#define auth_dealloc(c) (((c)->type)->dealloc(c))
+#define srtp_auth_start(a) (((a)->type)->start((a)->state))
+
+#define srtp_auth_dealloc(c) (((c)->type)->dealloc(c))
 
 /* functions to get information about a particular auth_t */
-
-int
-auth_get_key_length(const struct auth_t *a);
+int srtp_auth_get_key_length(const struct srtp_auth_t *a);
 
-int
-auth_get_tag_length(const struct auth_t *a);
+int srtp_auth_get_tag_length(const struct srtp_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 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;
-
-/* auth_type_t */
+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_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;
+/* 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;
 
-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;
+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_self_test() tests an auth_type against test cases
+/*
+ * 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);
 
-err_status_t
-auth_type_self_test(const auth_type_t *at);
-
-/* 
- * auth_type_test() tests an auth_type against external test cases
+/*
+ * 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
  */
-
-err_status_t
-auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data);
+srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
+                                      const srtp_auth_test_case_t *test_data);
 
 /*
- * auth_type_get_ref_count(at) returns the reference count (the number
- * of instantiations) of the auth_type_t at
+ * 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);
 
-int
-auth_type_get_ref_count(const auth_type_t *at);
+#ifdef __cplusplus
+}
+#endif
 
-#endif /* AUTH_H */
+#endif /* SRTP_AUTH_H */
--- a/netwerk/srtp/src/crypto/include/cipher.h
+++ b/netwerk/srtp/src/crypto/include/cipher.h
@@ -2,229 +2,247 @@
  * cipher.h
  *
  * common interface to ciphers
  *
  * 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
  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
+#ifndef SRTP_CIPHER_H
+#define SRTP_CIPHER_H
 
-#ifndef CIPHER_H
-#define CIPHER_H
+#include "srtp.h"
+#include "crypto_types.h" /* for values of cipher_type_id_t */
 
-#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 */
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-
-/**
- * @brief cipher_direction_t defines a particular cipher operation. 
+/*
+ * 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 {
+    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;
 
-typedef enum { 
-  direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
-  direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
-  direction_any      /**< encryption or decryption                     */
-} cipher_direction_t;
+/*
+ * the srtp_cipher_pointer_t definition is needed
+ * as srtp_cipher_t is not yet defined
+ */
+typedef struct srtp_cipher_t *srtp_cipher_pointer_t;
 
 /*
- * the cipher_pointer and cipher_type_pointer definitions are needed
- * as cipher_t and cipher_type_t are not yet defined
+ *  a srtp_cipher_alloc_func_t allocates (but does not initialize) a
+ * srtp_cipher_t
  */
+typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)(srtp_cipher_pointer_t *cp,
+                                                      int key_len,
+                                                      int tag_len);
 
-typedef struct cipher_type_t *cipher_type_pointer_t;
-typedef struct cipher_t      *cipher_pointer_t;
+/*
+ * 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 cipher_alloc_func_t allocates (but does not initialize) a cipher_t 
- */
-
-typedef err_status_t (*cipher_alloc_func_t)
-     (cipher_pointer_t *cp, int key_len);
-
-/* 
- * a cipher_init_func_t [re-]initializes a cipher_t with a given key
- * and direction (i.e., encrypt or decrypt)
+ * a srtp_cipher_set_aad_func_t processes the AAD data for AEAD ciphers
  */
-
-typedef err_status_t (*cipher_init_func_t)
-(void *state, const uint8_t *key, int key_len, cipher_direction_t dir);
+typedef srtp_err_status_t (*srtp_cipher_set_aad_func_t)(void *state,
+                                                        const uint8_t *aad,
+                                                        uint32_t aad_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 */
+/* a srtp_cipher_encrypt_func_t encrypts data in-place */
+typedef srtp_err_status_t (*srtp_cipher_encrypt_func_t)(
+    void *state,
+    uint8_t *buffer,
+    unsigned int *octets_to_encrypt);
 
-typedef err_status_t (*cipher_set_segment_func_t)
-     (void *state, xtd_seq_num_t idx);
-
-/* 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 */
+/* a srtp_cipher_decrypt_func_t decrypts data in-place */
+typedef srtp_err_status_t (*srtp_cipher_decrypt_func_t)(
+    void *state,
+    uint8_t *buffer,
+    unsigned int *octets_to_decrypt);
 
-typedef err_status_t (*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_set_iv_func_t function sets the current initialization vector
+/*
+ * 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_set_iv_func_t)
-     (cipher_pointer_t cp, void *iv);
+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             */
+    unsigned int plaintext_length_octets;  /* octets in plaintext      */
+    const uint8_t *plaintext;              /* plaintext                */
+    unsigned int ciphertext_length_octets; /* octets in plaintext      */
+    const uint8_t *ciphertext;             /* ciphertext               */
+    int aad_length_octets;                 /* octets in AAD            */
+    const uint8_t *aad;                    /* AAD                      */
+    int tag_length_octets;                 /* Length of AEAD tag       */
+    const struct srtp_cipher_test_case_t
+        *next_test_case; /* pointer to next testcase */
+} srtp_cipher_test_case_t;
 
-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               */
-  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_encrypt_func_t       encrypt;
-  cipher_encrypt_func_t       decrypt;
-  cipher_set_iv_func_t        set_iv;
-  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;
-#ifdef FORCE_64BIT_ALIGN
-  int            pad;
-#endif
-} cipher_t;
-
-/* some syntactic sugar on these function types */
-
-#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen)))
-
-#define cipher_dealloc(c) (((c)->type)->dealloc(c))
-
-#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), ((c)->key_len), (dir)))
-
-#define cipher_encrypt(c, buf, len) \
-        (((c)->type)->encrypt(((c)->state), (buf), (len)))
-
-#define cipher_decrypt(c, buf, len) \
-        (((c)->type)->decrypt(((c)->state), (buf), (len)))
-
-#define cipher_set_iv(c, n)                           \
-  ((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) :   \
-                                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);
+int srtp_cipher_get_key_length(const srtp_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 
+/*
+ * 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
  */
-
-err_status_t
-cipher_type_self_test(const cipher_type_t *ct);
+srtp_err_status_t srtp_cipher_type_self_test(const srtp_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 
+/*
+ * 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
  */
-
-err_status_t
-cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data);
-
+srtp_err_status_t srtp_cipher_type_test(
+    const srtp_cipher_type_t *ct,
+    const srtp_cipher_test_case_t *test_data);
 
 /*
- * cipher_bits_per_second(c, l, t) computes (and estimate of) the
+ * 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 */
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/crypto/include/cipher_types.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * 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 CIHPER_TYPES_H
+#define CIHPER_TYPES_H
+
+#include "cipher.h"
+#include "auth.h"
+
+/*
+ * cipher types that can be included in the kernel
+ */
+
+const srtp_cipher_type_t srtp_null_cipher;
+const srtp_cipher_type_t srtp_aes_icm_128;
+const srtp_cipher_type_t srtp_aes_icm_256;
+#ifdef OPENSSL
+const srtp_cipher_type_t srtp_aes_icm_192;
+const srtp_cipher_type_t srtp_aes_gcm_128_openssl;
+const srtp_cipher_type_t srtp_aes_gcm_256_openssl;
+#endif
+
+/*
+ * auth func types that can be included in the kernel
+ */
+
+const srtp_auth_type_t srtp_null_auth;
+const srtp_auth_type_t srtp_hmac;
+
+/*
+ * other generic debug modules that can be included in the kernel
+ */
+
+srtp_debug_module_t srtp_mod_auth;
+srtp_debug_module_t srtp_mod_cipher;
+srtp_debug_module_t mod_stat;
+srtp_debug_module_t mod_alloc;
+
+/* debug modules for cipher types */
+srtp_debug_module_t srtp_mod_aes_icm;
+#ifdef OPENSSL
+srtp_debug_module_t srtp_mod_aes_gcm;
+#endif
+
+/* debug modules for auth types */
+srtp_debug_module_t srtp_mod_hmac;
+
+#endif
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/crypto.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * crypto.h
- *
- * API for libcrypto
- * 
- * 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 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 */
-
-
--- a/netwerk/srtp/src/crypto/include/crypto_kernel.h
+++ b/netwerk/srtp/src/crypto/include/crypto_kernel.h
@@ -2,279 +2,214 @@
  * crypto_kernel.h
  *
  * header for the cryptographic kernel
  *
  * 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
  * 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 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:
  *
  *    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 
- */
+    srtp_crypto_kernel_state_insecure,
+    srtp_crypto_kernel_state_secure
+} srtp_crypto_kernel_state_t;
 
-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 
+/*
+ * linked list of cipher 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;
+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;
 
 /*
- * linked list of debug modules 
+ * 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;
 
-typedef struct kernel_debug_module {
-  debug_module_t *mod;
-  struct kernel_debug_module *next;
-} kernel_debug_module_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;
 
 /*
  * crypto_kernel_t is the data structure for the crypto kernel
  *
  * 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
- *
- */
-
-err_status_t
-crypto_kernel_list_debug_modules(void);
-
-/*
- * crypto_kernel_load_cipher_type()
+ * srtp_crypto_kernel_list_debug_modules() outputs a list of debugging modules
  *
  */
-
-err_status_t
-crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_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_list_debug_modules(void);
 
 /*
- * 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.
+ * srtp_crypto_kernel_load_cipher_type()
+ *
  */
-err_status_t
-crypto_kernel_replace_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
+srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
+    const srtp_cipher_type_t *ct,
+    srtp_cipher_type_id_t id);
 
+srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct,
+                                                    srtp_auth_type_id_t id);
+
+srtp_err_status_t srtp_crypto_kernel_load_debug_module(
+    srtp_debug_module_t *new_dm);
 
 /*
- * 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);
+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
  */
-
-err_status_t
-crypto_kernel_set_debug_module(char *mod_name, int v);
+srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *mod_name,
+                                                      int v);
 
-/**
- * @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);
-     
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* CRYPTO_KERNEL */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/crypto_math.h
+++ /dev/null
@@ -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 */
-
-
-
--- a/netwerk/srtp/src/crypto/include/crypto_types.h
+++ b/netwerk/srtp/src/crypto/include/crypto_types.h
@@ -2,219 +2,115 @@
  * crypto_types.h
  *
  * constants for cipher types and auth func types
  *
  * 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
  * 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 CRYPTO_TYPES_H
-#define CRYPTO_TYPES_H
+#ifndef SRTP_CRYPTO_TYPES_H
+#define SRTP_CRYPTO_TYPES_H
 
-/**
- * @defgroup Algos Cryptographic Algorithms
- *
- *
- * 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.
+/*
+ * The null cipher performs no encryption.
  *
- * 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 SRTP_AES_ICM_128 1
+
+/*
+ * AES-192 Integer Counter Mode (AES ICM)
+ *
+ * AES-128 ICM is the variant of counter mode that is used by
+ * Secure RTP.  This cipher uses a 24-octet key concatenated with a
  * 14-octet offset (or salt) value.
  */
-#define AES_ICM            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            
+#define SRTP_AES_ICM_192 4
 
-/** 
- * @brief AES Cipher Block Chaining mode (AES CBC)             
+/*
+ * AES-256 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 32-octet key concatenated with a
+ * 14-octet offset (or salt) value.
  */
-#define AES_CBC            3            
+#define SRTP_AES_ICM_256 5
 
-/** 
- * @brief AES-128 Cipher Block Chaining mode (AES CBC)             
- *
- * AES-128 CBC is a deprecated alternate name for AES CBC.
- */
-#define AES_128_CBC        AES_CBC            
-
-/**
- * @brief Strongest available cipher.
+/*
+ * AES-128_GCM Galois Counter Mode (AES GCM)
  *
- * This identifier resolves to the strongest cipher type available.
+ * AES-128 GCM is the variant of galois counter mode that is used by
+ * Secure RTP.  This cipher uses a 16-octet key.
  */
-#define STRONGHOLD_CIPHER  AES_ICM  
-
-/**
- * @}
- */
+#define SRTP_AES_GCM_128 6
 
-
-
-/**
- * @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.
+/*
+ * AES-256_GCM Galois Counter Mode (AES GCM)
  *
- * 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).
- *
- * @{
+ * AES-256 GCM is the variant of galois counter mode that is used by
+ * Secure RTP.  This cipher uses a 32-octet key.
  */
+#define SRTP_AES_GCM_256 7
 
-/**
- * @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           
-
-/**
- * @brief UST with TMMH Version 2
- *
- * 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           
+#define SRTP_NULL_AUTH 0
 
-/**
- * @brief (UST) AES-128 XORMAC  
+/*
+ * HMAC-SHA1
  *
- * 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 */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/cryptoalg.h
+++ /dev/null
@@ -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 */
-
-
--- a/netwerk/srtp/src/crypto/include/datatypes.h
+++ b/netwerk/srtp/src/crypto/include/datatypes.h
@@ -1,508 +1,378 @@
 /*
  * datatypes.h
- * 
+ *
  * data types for bit vectors and finite fields
  *
  * 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
  * 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 DATATYPES_H
+#define DATATYPES_H
 
-#ifndef _DATATYPES_H
-#define _DATATYPES_H
-
-#include "integers.h"           /* definitions of uint32_t, et cetera   */
+#include "integers.h" /* definitions of uint32_t, et cetera   */
 #include "alloc.h"
 
 #include <stdarg.h>
 
-#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>
+#else
+#error "Platform not recognized"
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* if DATATYPES_USE_MACROS is defined, then little functions are macros */
-#define DATATYPES_USE_MACROS  
+#define DATATYPES_USE_MACROS
 
 typedef union {
-  uint8_t  v8[2];
-  uint16_t value;
+    uint8_t v8[2];
+    uint16_t value;
 } v16_t;
 
 typedef union {
-  uint8_t  v8[4];
-  uint16_t v16[2];
-  uint32_t value;
+    uint8_t v8[4];
+    uint16_t v16[2];
+    uint32_t value;
 } v32_t;
 
 typedef union {
-  uint8_t  v8[8];
-  uint16_t v16[4];
-  uint32_t v32[2];
-  uint64_t value;
+    uint8_t v8[8];
+    uint16_t v16[4];
+    uint32_t v32[2];
+    uint64_t value;
 } v64_t;
 
 typedef union {
-  uint8_t  v8[16];
-  uint16_t v16[8];
-  uint32_t v32[4];
-  uint64_t v64[2];
+    uint8_t v8[16];
+    uint16_t v16[8];
+    uint32_t v32[4];
+    uint64_t v64[2];
 } v128_t;
 
-
+typedef union {
+    uint8_t v8[32];
+    uint16_t v16[16];
+    uint32_t v32[8];
+    uint64_t v64[4];
+} v256_t;
 
 /* some useful and simple math functions */
 
-#define pow_2(X) ( (unsigned int)1 << (X) )   /* 2^X     */
+#define pow_2(X) ((unsigned int)1 << (X)) /* 2^X     */
 
-#define pow_minus_one(X) ( (X) ? -1 : 1 )      /* (-1)^X  */
-
+#define pow_minus_one(X) ((X) ? -1 : 1) /* (-1)^X  */
 
 /*
  * octet_get_weight(x) returns the hamming weight (number of bits equal to
  * one) in the octet x
  */
 
-int
-octet_get_weight(uint8_t octet);
-
-char *
-octet_bit_string(uint8_t x);
+int octet_get_weight(uint8_t octet);
 
 #define MAX_PRINT_STRING_LEN 1024
 
-char *
-octet_string_hex_string(const void *str, int length);
-
-char *
-v128_bit_string(v128_t *x);
-
-char *
-v128_hex_string(v128_t *x);
+char *srtp_octet_string_hex_string(const void *str, int length);
 
-uint8_t
-nibble_to_hex_char(uint8_t nibble);
+char *v128_bit_string(v128_t *x);
 
-char *
-char_to_hex_string(char *x, int num_char);
-
-uint8_t
-hex_string_to_octet(char *s);
+char *v128_hex_string(v128_t *x);
 
-/*
- * 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
- */
+void v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
 
-int
-hex_string_to_octet_string(char *raw, char *hex, int len);
-
-v128_t
-hex_string_to_v128(char *s);
+void v128_left_shift(v128_t *x, int shift_index);
 
-void
-v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
-
-void
-v128_left_shift(v128_t *x, int shift_index);
-
-void
-v128_right_shift(v128_t *x, int shift_index);
+void v128_right_shift(v128_t *x, int shift_index);
 
 /*
  * the following macros define the data manipulation functions
- * 
+ *
  * If DATATYPES_USE_MACROS is defined, then these macros are used
  * directly (and function call overhead is avoided).  Otherwise,
  * the macros are used through the functions defined in datatypes.c
  * (and the compiler provides better warnings).
  */
 
-#define _v128_set_to_zero(x)     \
-(                               \
-  (x)->v32[0] = 0,              \
-  (x)->v32[1] = 0,              \
-  (x)->v32[2] = 0,              \
-  (x)->v32[3] = 0               \
-)
+#define _v128_set_to_zero(x)                                                   \
+    ((x)->v32[0] = 0, (x)->v32[1] = 0, (x)->v32[2] = 0, (x)->v32[3] = 0)
 
-#define _v128_copy(x, y)          \
-(                                \
-  (x)->v32[0] = (y)->v32[0],     \
-  (x)->v32[1] = (y)->v32[1],     \
-  (x)->v32[2] = (y)->v32[2],     \
-  (x)->v32[3] = (y)->v32[3]      \
-)
+#define _v128_copy(x, y)                                                       \
+    ((x)->v32[0] = (y)->v32[0], (x)->v32[1] = (y)->v32[1],                     \
+     (x)->v32[2] = (y)->v32[2], (x)->v32[3] = (y)->v32[3])
 
-#define _v128_xor(z, x, y)                       \
-(                                               \
-   (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0],     \
-   (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1],     \
-   (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2],     \
-   (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3]      \
-)
+#define _v128_xor(z, x, y)                                                     \
+    ((z)->v32[0] = (x)->v32[0] ^ (y)->v32[0],                                  \
+     (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1],                                  \
+     (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2],                                  \
+     (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3])
 
-#define _v128_and(z, x, y)                       \
-(                                               \
-   (z)->v32[0] = (x)->v32[0] & (y)->v32[0],     \
-   (z)->v32[1] = (x)->v32[1] & (y)->v32[1],     \
-   (z)->v32[2] = (x)->v32[2] & (y)->v32[2],     \
-   (z)->v32[3] = (x)->v32[3] & (y)->v32[3]      \
-)
+#define _v128_and(z, x, y)                                                     \
+    ((z)->v32[0] = (x)->v32[0] & (y)->v32[0],                                  \
+     (z)->v32[1] = (x)->v32[1] & (y)->v32[1],                                  \
+     (z)->v32[2] = (x)->v32[2] & (y)->v32[2],                                  \
+     (z)->v32[3] = (x)->v32[3] & (y)->v32[3])
 
-#define _v128_or(z, x, y)                        \
-(                                               \
-   (z)->v32[0] = (x)->v32[0] | (y)->v32[0],     \
-   (z)->v32[1] = (x)->v32[1] | (y)->v32[1],     \
-   (z)->v32[2] = (x)->v32[2] | (y)->v32[2],     \
-   (z)->v32[3] = (x)->v32[3] | (y)->v32[3]      \
-)
+#define _v128_or(z, x, y)                                                      \
+    ((z)->v32[0] = (x)->v32[0] | (y)->v32[0],                                  \
+     (z)->v32[1] = (x)->v32[1] | (y)->v32[1],                                  \
+     (z)->v32[2] = (x)->v32[2] | (y)->v32[2],                                  \
+     (z)->v32[3] = (x)->v32[3] | (y)->v32[3])
 
-#define _v128_complement(x)        \
-(                                  \
-   (x)->v32[0] = ~(x)->v32[0],     \
-   (x)->v32[1] = ~(x)->v32[1],     \
-   (x)->v32[2] = ~(x)->v32[2],     \
-   (x)->v32[3] = ~(x)->v32[3]      \
-)
+#define _v128_complement(x)                                                    \
+    ((x)->v32[0] = ~(x)->v32[0], (x)->v32[1] = ~(x)->v32[1],                   \
+     (x)->v32[2] = ~(x)->v32[2], (x)->v32[3] = ~(x)->v32[3])
 
 /* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */
-#define _v128_is_eq(x, y)                                        \
-  (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
-
+#define _v128_is_eq(x, y)                                                      \
+    (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
 
 #ifdef NO_64BIT_MATH
-#define _v128_xor_eq(z, x)         \
-(                                  \
-   (z)->v32[0] ^= (x)->v32[0],     \
-   (z)->v32[1] ^= (x)->v32[1],     \
-   (z)->v32[2] ^= (x)->v32[2],     \
-   (z)->v32[3] ^= (x)->v32[3]      \
-)
+#define _v128_xor_eq(z, x)                                                     \
+    ((z)->v32[0] ^= (x)->v32[0], (z)->v32[1] ^= (x)->v32[1],                   \
+     (z)->v32[2] ^= (x)->v32[2], (z)->v32[3] ^= (x)->v32[3])
 #else
-#define _v128_xor_eq(z, x)         \
-(                                  \
-   (z)->v64[0] ^= (x)->v64[0],     \
-   (z)->v64[1] ^= (x)->v64[1]      \
-)
+#define _v128_xor_eq(z, x)                                                     \
+    ((z)->v64[0] ^= (x)->v64[0], (z)->v64[1] ^= (x)->v64[1])
 #endif
 
 /* NOTE!  This assumes an odd ordering! */
 /* This will not be compatible directly with math on some processors */
 /* bit 0 is first 32-bit word, low order bit. in little-endian, that's
    the first byte of the first 32-bit word.  In big-endian, that's
    the 3rd byte of the first 32-bit word */
 /* The get/set bit code is used by the replay code ONLY, and it doesn't
    really care which bit is which.  AES does care which bit is which, but
    doesn't use the 128-bit get/set or 128-bit shifts  */
 
-#define _v128_get_bit(x, bit)                     \
-(                                                 \
-  ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1)  \
-)
+#define _v128_get_bit(x, bit) (((((x)->v32[(bit) >> 5]) >> ((bit)&31)) & 1))
 
-#define _v128_set_bit(x, bit)                                    \
-(                                                                \
-  (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \
-)
+#define _v128_set_bit(x, bit)                                                  \
+    ((((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit)&31))))
 
-#define _v128_clear_bit(x, bit)                                   \
-(                                                                 \
-  (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \
-)
+#define _v128_clear_bit(x, bit)                                                \
+    ((((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit)&31))))
 
-#define _v128_set_bit_to(x, bit, value)   \
-(                                         \
-   (value) ? _v128_set_bit(x, bit) :      \
-             _v128_clear_bit(x, bit)      \
-)
+#define _v128_set_bit_to(x, bit, value)                                        \
+    ((value) ? _v128_set_bit(x, bit) : _v128_clear_bit(x, bit))
 
-
-#if 0
-/* nothing uses this */
-#ifdef WORDS_BIGENDIAN
+#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
 
-#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)
-#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)
+#define v128_set_to_zero(z) _v128_set_to_zero(z)
+#define v128_copy(z, x) _v128_copy(z, x)
+#define v128_xor(z, x, y) _v128_xor(z, x, y)
+#define v128_and(z, x, y) _v128_and(z, x, y)
+#define v128_or(z, x, y) _v128_or(z, x, y)
+#define v128_complement(x) _v128_complement(x)
+#define v128_is_eq(x, y) _v128_is_eq(x, y)
+#define v128_xor_eq(x, y) _v128_xor_eq(x, y)
+#define v128_get_bit(x, i) _v128_get_bit(x, i)
+#define v128_set_bit(x, i) _v128_set_bit(x, i)
+#define v128_clear_bit(x, i) _v128_clear_bit(x, i)
+#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y)
 
 #else
 
-void
-v128_set_to_zero(v128_t *x);
+void v128_set_to_zero(v128_t *x);
 
-int
-v128_is_eq(const v128_t *x, const v128_t *y);
+int v128_is_eq(const v128_t *x, const v128_t *y);
 
-void
-v128_copy(v128_t *x, const v128_t *y);
+void v128_copy(v128_t *x, const v128_t *y);
 
-void
-v128_xor(v128_t *z, v128_t *x, v128_t *y);
+void v128_xor(v128_t *z, v128_t *x, v128_t *y);
 
-void
-v128_and(v128_t *z, v128_t *x, v128_t *y);
+void v128_and(v128_t *z, v128_t *x, v128_t *y);
 
-void
-v128_or(v128_t *z, v128_t *x, v128_t *y); 
+void v128_or(v128_t *z, v128_t *x, v128_t *y);
 
-void
-v128_complement(v128_t *x);
+void v128_complement(v128_t *x);
 
-int
-v128_get_bit(const v128_t *x, int i);
+int v128_get_bit(const v128_t *x, int i);
 
-void
-v128_set_bit(v128_t *x, int i) ;     
+void v128_set_bit(v128_t *x, int i);
 
-void
-v128_clear_bit(v128_t *x, int i);    
+void v128_clear_bit(v128_t *x, int i);
 
-void
-v128_set_bit_to(v128_t *x, int i, int y);
+void v128_set_bit_to(v128_t *x, int i, int y);
 
 #endif /* DATATYPES_USE_MACROS */
 
 /*
- * 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);
+int octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
+
+/*
+ * A portable way to zero out memory as recommended by
+ * https://cryptocoding.net/index.php/Coding_rules#Clean_memory_of_secret_data
+ * This is used to zero memory when OPENSSL_cleanse() is not available.
+ */
+void srtp_cleanse(void *s, size_t len);
 
-void
-octet_string_set_to_zero(uint8_t *s, int 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.
  */
 #ifdef WORDS_BIGENDIAN
 /* Nothing to do. */
-# define be32_to_cpu(x)	(x)
-# define be64_to_cpu(x)	(x)
+#define be32_to_cpu(x) (x)
+#define be64_to_cpu(x) (x)
 #elif defined(HAVE_BYTESWAP_H)
 /* We have (hopefully) optimized versions in byteswap.h */
-# include <byteswap.h>
-# define be32_to_cpu(x)	bswap_32((x))
-# define be64_to_cpu(x)	bswap_64((x))
-#else
+#include <byteswap.h>
+#define be32_to_cpu(x) bswap_32((x))
+#define be64_to_cpu(x) bswap_64((x))
+#else /* WORDS_BIGENDIAN */
 
 #if defined(__GNUC__) && defined(HAVE_X86)
 /* Fall back. */
-static inline uint32_t be32_to_cpu(uint32_t v) {
-   /* optimized for x86. */
-   asm("bswap %0" : "=r" (v) : "0" (v));
-   return v;
+static inline uint32_t be32_to_cpu(uint32_t v)
+{
+    /* optimized for x86. */
+    asm("bswap %0" : "=r"(v) : "0"(v));
+    return v;
 }
-# else /* HAVE_X86 */
-#  ifdef HAVE_NETINET_IN_H
-#   include <netinet/in.h>
-#  elif defined HAVE_WINSOCK2_H
-#   include <winsock2.h>
-#  else
-#    error "Platform not recognized"
-#  endif
-#  define be32_to_cpu(x)	ntohl((x))
-# endif /* HAVE_X86 */
+#else /* HAVE_X86 */
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif /* HAVE_NETINET_IN_H */
+#define be32_to_cpu(x) ntohl((x))
+#endif /* HAVE_X86 */
 
-static inline uint64_t be64_to_cpu(uint64_t v) {
-# ifdef NO_64BIT_MATH
-   /* use the make64 functions to do 64-bit math */
-   v = make64(htonl(low32(v)),htonl(high32(v)));
-# else
-   /* use the native 64-bit math */
-   v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32));
-# endif
-   return v;
+static inline uint64_t be64_to_cpu(uint64_t v)
+{
+#ifdef NO_64BIT_MATH
+    /* use the make64 functions to do 64-bit math */
+    v = make64(htonl(low32(v)), htonl(high32(v)));
+#else  /* NO_64BIT_MATH */
+    /* use the native 64-bit math */
+    v = (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) |
+                   (((uint64_t)be32_to_cpu((uint32_t)v)) << 32));
+#endif /* NO_64BIT_MATH */
+    return v;
 }
 
-#endif /* ! SRTP_KERNEL_LINUX */
-
 #endif /* WORDS_BIGENDIAN */
 
+#endif /* HAVE_CONFIG_H */
+
 /*
- * functions manipulating bitvector_t 
+ * functions manipulating bitvector_t
  *
  * A bitvector_t consists of an array of words and an integer
  * representing the number of significant bits stored in the array.
  * The bits are packed as follows: the least significant bit is that
  * of word[0], while the most significant bit is the nth most
  * significant bit of word[m], where length = bits_per_word * m + n.
- * 
+ *
  */
 
-#define bits_per_word  32
+#define bits_per_word 32
 #define bytes_per_word 4
 
 typedef struct {
-  uint32_t length;   
-  uint32_t *word;
+    uint32_t length;
+    uint32_t *word;
 } bitvector_t;
 
-
-#define _bitvector_get_bit(v, bit_index)				\
-(									\
- ((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1)		\
-)
+#define _bitvector_get_bit(v, bit_index)                                       \
+    (((((v)->word[((bit_index) >> 5)]) >> ((bit_index)&31)) & 1))
 
-
-#define _bitvector_set_bit(v, bit_index)				\
-(									\
- (((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \
-)
+#define _bitvector_set_bit(v, bit_index)                                       \
+    ((((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index)&31)))))
 
-#define _bitvector_clear_bit(v, bit_index)				\
-(									\
- (((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \
-)
+#define _bitvector_clear_bit(v, bit_index)                                     \
+    ((((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index)&31)))))
 
-#define _bitvector_get_length(v)					\
-(									\
- ((v)->length)								\
-)
+#define _bitvector_get_length(v) (((v)->length))
 
-#ifdef DATATYPES_USE_MACROS  /* little functions are really macros */
+#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
 
 #define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index)
 #define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index)
 #define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index)
 #define bitvector_get_length(v) _bitvector_get_length(v)
 
 #else
 
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index);
+int bitvector_get_bit(const bitvector_t *v, int bit_index);
 
-void
-bitvector_set_bit(bitvector_t *v, int bit_index);
+void bitvector_set_bit(bitvector_t *v, int bit_index);
 
-void
-bitvector_clear_bit(bitvector_t *v, int bit_index);
+void bitvector_clear_bit(bitvector_t *v, int bit_index);
 
-unsigned long
-bitvector_get_length(const bitvector_t *v);
+unsigned long bitvector_get_length(const bitvector_t *v);
 
 #endif
 
-int
-bitvector_alloc(bitvector_t *v, unsigned long length);
+int bitvector_alloc(bitvector_t *v, unsigned long length);
+
+void bitvector_dealloc(bitvector_t *v);
 
-void
-bitvector_dealloc(bitvector_t *v);
+void bitvector_set_to_zero(bitvector_t *x);
+
+void bitvector_left_shift(bitvector_t *x, int index);
 
-void
-bitvector_set_to_zero(bitvector_t *x);
+char *bitvector_bit_string(bitvector_t *x, char *buf, int len);
 
-void
-bitvector_left_shift(bitvector_t *x, int index);
+#ifdef __cplusplus
+}
+#endif
 
-char *
-bitvector_bit_string(bitvector_t *x, char* buf, int len);
-
-#endif /* _DATATYPES_H */
+#endif /* DATATYPES_H */
--- a/netwerk/srtp/src/crypto/include/err.h
+++ b/netwerk/srtp/src/crypto/include/err.h
@@ -1,174 +1,134 @@
 /*
  * 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
  * 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 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 pasring 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.
- *
- * 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);
-
-#ifdef SRTP_KERNEL_LINUX
-extern err_reporting_level_t err_level;
-#else
-
-/*
- * 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.
- *
- * Errors will be reported to ERR_REPORTING_FILE, if defined, and to
- * syslog, if ERR_REPORTING_SYSLOG is defined.
+ * ERR_REPORTING_STDOUT is defined, it will log to stdout.
  *
  */
 
-void
-err_report(int priority, char *format, ...);
-#endif /* ! SRTP_KERNEL_LINUX */
+srtp_err_status_t srtp_err_reporting_init(void);
+
+typedef void(srtp_err_report_handler_func_t)(srtp_err_reporting_level_t level,
+                                             const char *msg);
+
+srtp_err_status_t srtp_install_err_report_handler(
+    srtp_err_report_handler_func_t func);
 
+/*
+ * 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 stdout, if ERR_REPORTING_STDOUT
+ * is defined.
+ *
+ */
+
+void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
 
 /*
  * debug_module_t defines a debug module
  */
 
 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
-
-#define debug_on(mod)  (mod).on = 1
+#ifdef ENABLE_DEBUG_LOGGING
 
-#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)
+#define debug_print(mod, format, arg)                                          \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
+#define debug_print2(mod, format, arg1, arg2)                                  \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name,      \
+                    arg1, arg2)
 
 #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 */
--- a/netwerk/srtp/src/crypto/include/hmac.h
+++ b/netwerk/srtp/src/crypto/include/hmac.h
@@ -1,38 +1,38 @@
 /*
  * 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, 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)
@@ -45,34 +45,14 @@
 
 #ifndef HMAC_H
 #define HMAC_H
 
 #include "auth.h"
 #include "sha1.h"
 
 typedef struct {
-  uint8_t    opad[64];
-  sha1_ctx_t ctx;
-  sha1_ctx_t init_ctx;
-} 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 */
--- a/netwerk/srtp/src/crypto/include/integers.h
+++ b/netwerk/srtp/src/crypto/include/integers.h
@@ -3,153 +3,144 @@
  *
  * defines integer types (or refers to their definitions)
  *
  * 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
  * 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 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
-# include <stdlib.h>
+#include <stdlib.h>
 #endif
-#ifdef INTEGER_TYPES_H
-/* Let configure tell us where to get the equivalent to <stdint.h> */
-#include INTEGER_TYPES_H
-
-#if !defined(HAVE_UINT64_T)
-#define NO_64BIT_MATH 1
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
 #endif
-#else
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#endif /* INTEGER_TYPES_H */
 #ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
+#include <inttypes.h>
 #endif
 #ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <sys/types.h>
 #endif
 #ifdef HAVE_SYS_INT_TYPES_H
-# include <sys/int_types.h>    /* this exists on Sun OS */
+#include <sys/int_types.h> /* this exists on Sun OS */
 #endif
 #ifdef HAVE_MACHINE_TYPES_H
-# include <machine/types.h>
+#include <machine/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
 #endif
 
 /* Can we do 64 bit integers? */
 #if !defined(HAVE_UINT64_T)
-# if SIZEOF_UNSIGNED_LONG == 8
-typedef unsigned long		uint64_t;
-# elif SIZEOF_UNSIGNED_LONG_LONG == 8
-typedef unsigned long long	uint64_t;
-# else
-#  define NO_64BIT_MATH 1
-# endif
+#if SIZEOF_UNSIGNED_LONG == 8
+typedef unsigned long uint64_t;
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+typedef unsigned long long uint64_t;
+#else
+#define NO_64BIT_MATH 1
+#endif
 #endif
 
 /* Reasonable defaults for 32 bit machines - you may need to
  * edit these definitions for your own machine. */
 #ifndef HAVE_UINT8_T
-typedef unsigned char		uint8_t;
+typedef unsigned char uint8_t;
 #endif
 #ifndef HAVE_UINT16_T
-typedef unsigned short int	uint16_t;
+typedef unsigned short int uint16_t;
 #endif
 #ifndef HAVE_UINT32_T
-typedef unsigned int		uint32_t;
+typedef unsigned int uint32_t;
+#endif
+#ifndef HAVE_INT32_T
+typedef int int32_t;
 #endif
 
-#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);
 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
    loads. */
 #ifdef ALIGNMENT_32BIT_REQUIRED
 /* Note that if it's in a variable, you can memcpy it */
 #ifdef WORDS_BIGENDIAN
-#define PUT_32(addr,value) \
-    { \
-        ((unsigned char *) (addr))[0] = (value >> 24); \
-        ((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \
-        ((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \
-        ((unsigned char *) (addr))[3] = (value)      & 0xff; \
+#define PUT_32(addr, value)                                                    \
+    {                                                                          \
+        ((unsigned char *)(addr))[0] = (value >> 24);                          \
+        ((unsigned char *)(addr))[1] = (value >> 16) & 0xff;                   \
+        ((unsigned char *)(addr))[2] = (value >> 8) & 0xff;                    \
+        ((unsigned char *)(addr))[3] = (value)&0xff;                           \
     }
-#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) |  \
-                      (((unsigned char *) (addr))[1] << 16) |  \
-                      (((unsigned char *) (addr))[2] << 8)  |  \
-                      (((unsigned char *) (addr))[3])) 
+#define GET_32(addr)                                                           \
+    ((((unsigned char *)(addr))[0] << 24) |                                    \
+     (((unsigned char *)(addr))[1] << 16) |                                    \
+     (((unsigned char *)(addr))[2] << 8) | (((unsigned char *)(addr))[3]))
 #else
-#define PUT_32(addr,value) \
-    { \
-        ((unsigned char *) (addr))[3] = (value >> 24); \
-        ((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \
-        ((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \
-        ((unsigned char *) (addr))[0] = (value)      & 0xff; \
+#define PUT_32(addr, value)                                                    \
+    {                                                                          \
+        ((unsigned char *)(addr))[3] = (value >> 24);                          \
+        ((unsigned char *)(addr))[2] = (value >> 16) & 0xff;                   \
+        ((unsigned char *)(addr))[1] = (value >> 8) & 0xff;                    \
+        ((unsigned char *)(addr))[0] = (value)&0xff;                           \
     }
-#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) |  \
-                      (((unsigned char *) (addr))[2] << 16) |  \
-                      (((unsigned char *) (addr))[1] << 8)  |  \
-                      (((unsigned char *) (addr))[0])) 
+#define GET_32(addr)                                                           \
+    ((((unsigned char *)(addr))[3] << 24) |                                    \
+     (((unsigned char *)(addr))[2] << 16) |                                    \
+     (((unsigned char *)(addr))[1] << 8) | (((unsigned char *)(addr))[0]))
 #endif // WORDS_BIGENDIAN
 #else
-#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value)
+#define PUT_32(addr, value) *(((uint32_t *) (addr)) = (value)
 #define GET_32(addr) (*(((uint32_t *) (addr)))
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* INTEGERS_H */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/kernel_compat.h
+++ /dev/null
@@ -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 */
--- a/netwerk/srtp/src/crypto/include/key.h
+++ b/netwerk/srtp/src/crypto/include/key.h
@@ -1,37 +1,37 @@
 /*
  * 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
  * 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)
@@ -40,43 +40,49 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
 #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);
+
+srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key);
 
-key_event_t
-key_limit_update(key_limit_t key);
+typedef enum {
+    srtp_key_state_normal,
+    srtp_key_state_past_soft_limit,
+    srtp_key_state_expired
+} srtp_key_state_t;
 
-typedef enum { 
-   key_state_normal,
-   key_state_past_soft_limit,
-   key_state_expired
-} key_state_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;
 
-typedef struct key_limit_ctx_t {
-  xtd_seq_num_t num_left;
-  key_state_t   state;
-} key_limit_ctx_t;
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* KEY_H */
--- a/netwerk/srtp/src/crypto/include/null_auth.h
+++ b/netwerk/srtp/src/crypto/include/null_auth.h
@@ -2,36 +2,36 @@
  * null-auth.h
  *
  * 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
  * 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)
@@ -42,27 +42,32 @@
  *
  */
 
 #ifndef NULL_AUTH_H
 #define NULL_AUTH_H
 
 #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);
+
+srtp_err_status_t srtp_null_auth_init(srtp_null_auth_ctx_t *state, const uint8_t *key, int key_len);
+
+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);
 
-err_status_t
-null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len);
+#endif
 
-err_status_t
-null_auth_compute (null_auth_ctx_t *state, uint8_t *message,
-		   int msg_octets, int tag_len, uint8_t *result);
-
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* NULL_AUTH_H */
--- a/netwerk/srtp/src/crypto/include/null_cipher.h
+++ b/netwerk/srtp/src/crypto/include/null_cipher.h
@@ -4,77 +4,54 @@
  * header file for the null cipher
  *
  *
  * 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
  * 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 NULL_CIPHER_H
 #define NULL_CIPHER_H
 
 #include "datatypes.h"
 #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 */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/prng.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * prng.h
- *
- * 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.
- *
- */
-
-#ifndef PRNG_H
-#define PRNG_H
-
-#include "rand_source.h"  /* for rand_source_func_t definition       */
-#include "aes.h"          /* for aes                                 */
-#include "aes_icm.h"      /* for aes ctr                             */
-
-#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
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/rand_source.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * rand_source.h
- *
- * 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.
- *
- */
-
-
-#ifndef RAND_SOURCE
-#define RAND_SOURCE
-
-#include "err.h"
-#include "datatypes.h"
-
-err_status_t
-rand_source_init(void);
-
-/*
- * rand_source_get_octet_string() writes a random octet string.
- *
- * The function call rand_source_get_octet_string(dest, len) writes
- * len octets of random data to the location to which dest points,
- * and returns an error code.  This error code should be checked,
- * and if a failure is reported, the data in the buffer MUST NOT
- * be used.
- * 
- * warning: If the return code is not checked, then non-random
- *          data may inadvertently be used.
- *
- * returns:
- *     - err_status_ok    if no problems occured.
- *     - [other]          a problem occured, and no assumptions should
- *                        be made about the contents of the destination
- *                        buffer.
- */
-
-err_status_t
-rand_source_get_octet_string(void *dest, uint32_t length);
-
-err_status_t
-rand_source_deinit(void);
-
-/* 
- * function prototype for a random source function
- *
- * A rand_source_func_t writes num_octets at the location indicated by
- * dest and returns err_status_ok.  Any other return value indicates
- * failure.
- */
-
-typedef err_status_t (*rand_source_func_t)
-     (void *dest, uint32_t num_octets);
-
-#endif /* RAND_SOURCE */
--- a/netwerk/srtp/src/crypto/include/rdb.h
+++ b/netwerk/srtp/src/crypto/include/rdb.h
@@ -1,129 +1,125 @@
 /*
  * replay-database.h
  *
  * interface for a replay database for packet security
  *
  * 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
  * 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 "integers.h"  /* for uint32_t     */
+#include "datatypes.h" /* for v128_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
  * window_end-i is in the database
  */
 
 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 srtp_rdb_t (and does *not* check if index appears in db)
+ *
+ * returns srtp_err_status_ok on success, srtp_err_status_fail otherwise
  *
- * adds index to rdb_t (and does *not* check if index appears in db)
- *
- * returns err_status_ok on success, err_status_fail otherwise
- *
+ */
+srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t rdb_index);
+
+/*
+ * 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
+ * srtp_rdb_t upon which srtp_rdb_add_index is used!
  */
 
-err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
-
 /*
- * the functions rdb_increment() and rdb_get_value() are for use by 
- * senders, not receivers - DO NOT use these functions on the same
- * rdb_t upon which 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 srtp_rdb_get_value(const srtp_rdb_t *rdb);
 
-uint32_t
-rdb_get_value(const rdb_t *rdb);
+#ifdef __cplusplus
+}
+#endif
 
-
-#endif /* REPLAY_DB_H */ 
+#endif /* REPLAY_DB_H */
--- a/netwerk/srtp/src/crypto/include/rdbx.h
+++ b/netwerk/srtp/src/crypto/include/rdbx.h
@@ -2,37 +2,38 @@
  * rdbx.h
  *
  * replay database with extended packet indices, using a rollover counter
  *
  * 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
  * 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)
@@ -44,178 +45,165 @@
  */
 
 #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 */
+#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 */
-
-
-
-
-
-
-
-
-
--- a/netwerk/srtp/src/crypto/include/sha1.h
+++ b/netwerk/srtp/src/crypto/include/sha1.h
@@ -4,36 +4,36 @@
  * interface to the Secure Hash Algorithm v.1 (SHA-1), specified in
  * FIPS 180-1
  *
  * 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
  * 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)
@@ -42,67 +42,143 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
 #ifndef SHA1_H
 #define SHA1_H
 
-#include "err.h"
-#include "datatypes.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-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;
+#include "err.h"
+#ifdef OPENSSL
+#include <openssl/evp.h>
+#include <stdint.h>
+#else
+#include "datatypes.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL
 
 /*
- * 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
- * 
+ * 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
+ *
+ * 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
+ * of these functions return void.
+ *
  */
 
-void
-sha1(const uint8_t *message,  int octets_in_msg, uint32_t output[5]);
+/* 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 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_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
+
+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 */
+} srtp_sha1_ctx_t;
 
 /*
- * 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
-sha1_init(sha1_ctx_t *ctx);
+void srtp_sha1_init(srtp_sha1_ctx_t *ctx);
 
-void
-sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
+void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
+                      const uint8_t *M,
+                      int octets_in_msg);
 
-void
-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 srtp_sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
 
-void
-sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
-     
+#endif /* else OPENSSL */
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* SHA1_H */
--- a/netwerk/srtp/src/crypto/include/stat.h
+++ b/netwerk/srtp/src/crypto/include/stat.h
@@ -1,69 +1,66 @@
 /*
  * stats.h
- * 
+ *
  * interface to statistical test functions
  *
  * 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
  * 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 STAT_H
 #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 "datatypes.h" /* for uint8_t                       */
+#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 */
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/include/xfm.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * xfm.h
- *
- * interface for abstract crypto transform
- * 
- * 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 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 */
-
-
--- a/netwerk/srtp/src/crypto/kernel/alloc.c
+++ b/netwerk/srtp/src/crypto/kernel/alloc.c
@@ -1,121 +1,97 @@
 /*
  * alloc.c
  *
- * memory allocation and deallocation 
+ * memory allocation and deallocation
  *
  * 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
  * 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 "alloc.h"
 #include "crypto_kernel.h"
 
 /* the debug module for memory allocation */
 
-debug_module_t mod_alloc = {
-  0,                  /* debugging is off by default */
-  "alloc"             /* printable name for module   */
+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
-
-#include <linux/interrupt.h>
+#if defined(HAVE_STDLIB_H)
 
-void *
-crypto_alloc(size_t size) {
-  void *ptr;
+void *srtp_crypto_alloc(size_t size)
+{
+    void *ptr;
 
-  ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+    ptr = calloc(1, size);
 
-  if (ptr) {
-    debug_print(mod_alloc, "(location: %p) allocated", ptr);
-  } else {
-    debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
-  }
+    if (ptr) {
+        debug_print(mod_alloc, "(location: %p) allocated", ptr);
+    } else {
+        debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n",
+                    size);
+    }
 
-  return ptr;
-}
-
-void 
-crypto_free(void *ptr) {
-
-  debug_print(mod_alloc, "(location: %p) freed", ptr);
-
-  kfree(ptr);
+    return ptr;
 }
 
-
-#elif defined(HAVE_STDLIB_H)
-
-void *
-crypto_alloc(size_t size) {
-  void *ptr;
+void srtp_crypto_free(void *ptr)
+{
+    debug_print(mod_alloc, "(location: %p) freed", 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;
+    free(ptr);
 }
 
-void 
-crypto_free(void *ptr) {
-
-  debug_print(mod_alloc, "(location: %p) freed", ptr);
+#else /* we need to define our own memory allocation routines */
 
-  free(ptr);
-}
-
-#else  /* we need to define our own memory allocation routines */
-
-#error no memory allocation defined yet 
+#error no memory allocation defined yet
 
 #endif
--- a/netwerk/srtp/src/crypto/kernel/crypto_kernel.c
+++ b/netwerk/srtp/src/crypto/kernel/crypto_kernel.c
@@ -2,572 +2,560 @@
  * crypto_kernel.c
  *
  * header for the cryptographic kernel
  *
  * 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
  * 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 "alloc.h"
 
 #include "crypto_kernel.h"
+#include "cipher_types.h"
 
 /* the debug module for the crypto_kernel */
 
-debug_module_t mod_crypto_kernel = {
-  0,                  /* debugging is off by default */
-  "crypto kernel"     /* printable name for module   */
+srtp_debug_module_t srtp_mod_crypto_kernel = {
+    0,              /* debugging is off by default */
+    "crypto kernel" /* printable name for module   */
 };
 
-/*
- * other debug modules that can be included in the kernel
- */
-
-extern debug_module_t mod_auth;
-extern debug_module_t mod_cipher;
-extern debug_module_t mod_stat;
-extern debug_module_t mod_alloc;
-
-/* 
- * cipher types that can be included in the kernel
- */ 
-
-extern cipher_type_t null_cipher;
-extern cipher_type_t aes_icm;
-extern cipher_type_t aes_cbc;
-
-
-/*
- * auth func types that can be included in the kernel
- */
-
-extern auth_type_t null_auth;
-extern auth_type_t hmac;
-
 /* crypto_kernel is a global variable, the only one of its datatype */
 
-crypto_kernel_t
-crypto_kernel = {
-  crypto_kernel_state_insecure,    /* start off in insecure state */
-  NULL,                            /* no cipher types yet         */
-  NULL,                            /* no auth types yet           */
-  NULL                             /* no debug modules yet        */
+srtp_crypto_kernel_t crypto_kernel = {
+    srtp_crypto_kernel_state_insecure, /* start off in insecure state */
+    NULL,                              /* no cipher types yet         */
+    NULL,                              /* no auth types yet           */
+    NULL                               /* no debug modules yet        */
 };
 
 #define MAX_RNG_TRIALS 25
 
-err_status_t
-crypto_kernel_init() {
-  err_status_t status;  
+srtp_err_status_t srtp_crypto_kernel_init()
+{
+    srtp_err_status_t status;
+
+    /* check the security state */
+    if (crypto_kernel.state == srtp_crypto_kernel_state_secure) {
+        /*
+         * we're already in the secure state, but we've been asked to
+         * re-initialize, so we just re-run the self-tests and then return
+         */
+        return srtp_crypto_kernel_status();
+    }
+
+    /* initialize error reporting system */
+    status = srtp_err_reporting_init();
+    if (status) {
+        return status;
+    }
 
-  /* check the security state */
-  if (crypto_kernel.state == crypto_kernel_state_secure) {
-    
-    /*
-     * we're already in the secure state, but we've been asked to
-     * re-initialize, so we just re-run the self-tests and then return
-     */
-    return crypto_kernel_status(); 
-  }
-
-  /* initialize error reporting system */
-  status = err_reporting_init("crypto");
-  if (status)
-    return status;
+    /* load debug modules */
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_crypto_kernel);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_auth);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_cipher);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&mod_stat);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&mod_alloc);
+    if (status) {
+        return status;
+    }
 
-  /* load debug modules */
-  status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
-  if (status)
-    return status;
-  status = crypto_kernel_load_debug_module(&mod_auth);
-  if (status)
-    return status;
-  status = crypto_kernel_load_debug_module(&mod_cipher);
-  if (status)
-    return status;
-  status = crypto_kernel_load_debug_module(&mod_stat);
-  if (status)
-    return status;
-  status = crypto_kernel_load_debug_module(&mod_alloc);
-  if (status)
-    return status;
-  
-  /* initialize random number generator */
-  status = rand_source_init();
-  if (status)
-    return status;
-
-  /* run FIPS-140 statistical tests on rand_source */  
-  status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
-  if (status)
-    return status;
+    /* load cipher types */
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_null_cipher,
+                                                 SRTP_NULL_CIPHER);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_128,
+                                                 SRTP_AES_ICM_128);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_256,
+                                                 SRTP_AES_ICM_256);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_icm);
+    if (status) {
+        return status;
+    }
+#ifdef OPENSSL
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_192,
+                                                 SRTP_AES_ICM_192);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128_openssl,
+                                                 SRTP_AES_GCM_128);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256_openssl,
+                                                 SRTP_AES_GCM_256);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_gcm);
+    if (status) {
+        return status;
+    }
+#endif
 
-  /* initialize pseudorandom number generator */
-  status = ctr_prng_init(rand_source_get_octet_string);
-  if (status)
-    return status;
+    /* load auth func types */
+    status = srtp_crypto_kernel_load_auth_type(&srtp_null_auth, SRTP_NULL_AUTH);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_auth_type(&srtp_hmac, SRTP_HMAC_SHA1);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_hmac);
+    if (status) {
+        return status;
+    }
 
-  /* run FIPS-140 statistical tests on ctr_prng */  
-  status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);
-  if (status)
-    return status;
- 
-  /* load cipher types */
-  status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
-  if (status) 
-    return status;
-  status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
-  if (status) 
-    return status;
-  status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
-  if (status) 
-    return status;
+    /* change state to secure */
+    crypto_kernel.state = srtp_crypto_kernel_state_secure;
 
-  /* load auth func types */
-  status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
-  if (status)
-    return status;
-  status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
-  if (status)
-    return status;
-
-  /* change state to secure */
-  crypto_kernel.state = crypto_kernel_state_secure;
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_status() {
-  err_status_t status;
-  kernel_cipher_type_t  *ctype = crypto_kernel.cipher_type_list;
-  kernel_auth_type_t    *atype = crypto_kernel.auth_type_list;
-  kernel_debug_module_t *dm    = crypto_kernel.debug_module_list;
+srtp_err_status_t srtp_crypto_kernel_status()
+{
+    srtp_err_status_t status;
+    srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
+    srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
 
-  /* run FIPS-140 statistical tests on rand_source */  
-  printf("testing rand_source...");
-  status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
-  if (status) {
-    printf("failed\n");
-    crypto_kernel.state = crypto_kernel_state_insecure;
-    return status;
-  }  
-  printf("passed\n");
-
-  /* for each cipher type, describe and test */
-  while(ctype != NULL) {
-    printf("cipher: %s\n", ctype->cipher_type->description);
-    printf("  instance count: %d\n", ctype->cipher_type->ref_count);
-    printf("  self-test: ");
-    status = cipher_type_self_test(ctype->cipher_type);
-    if (status) {
-      printf("failed with error code %d\n", status);
-      exit(status);
+    /* for each cipher type, describe and test */
+    while (ctype != NULL) {
+        srtp_err_report(srtp_err_level_info, "cipher: %s\n",
+                        ctype->cipher_type->description);
+        srtp_err_report(srtp_err_level_info, "  self-test: ");
+        status = srtp_cipher_type_self_test(ctype->cipher_type);
+        if (status) {
+            srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
+                            status);
+            exit(status);
+        }
+        srtp_err_report(srtp_err_level_info, "passed\n");
+        ctype = ctype->next;
     }
-    printf("passed\n");
-    ctype = ctype->next;
-  }
-  
-  /* for each auth type, describe and test */
-  while(atype != NULL) {
-    printf("auth func: %s\n", atype->auth_type->description);
-    printf("  instance count: %d\n", atype->auth_type->ref_count);
-    printf("  self-test: ");
-    status = auth_type_self_test(atype->auth_type);
-    if (status) {
-      printf("failed with error code %d\n", status);
-      exit(status);
+
+    /* for each auth type, describe and test */
+    while (atype != NULL) {
+        srtp_err_report(srtp_err_level_info, "auth func: %s\n",
+                        atype->auth_type->description);
+        srtp_err_report(srtp_err_level_info, "  self-test: ");
+        status = srtp_auth_type_self_test(atype->auth_type);
+        if (status) {
+            srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
+                            status);
+            exit(status);
+        }
+        srtp_err_report(srtp_err_level_info, "passed\n");
+        atype = atype->next;
     }
-    printf("passed\n");
-    atype = atype->next;
-  }
 
-  /* describe each debug module */
-  printf("debug modules loaded:\n");
-  while (dm != NULL) {
-    printf("  %s ", dm->mod->name);  
-    if (dm->mod->on)
-      printf("(on)\n");
-    else
-      printf("(off)\n");
-    dm = dm->next;
-  }
+    srtp_crypto_kernel_list_debug_modules();
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_list_debug_modules() {
-  kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
+srtp_err_status_t srtp_crypto_kernel_list_debug_modules()
+{
+    srtp_kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
 
-  /* describe each debug module */
-  printf("debug modules loaded:\n");
-  while (dm != NULL) {
-    printf("  %s ", dm->mod->name);  
-    if (dm->mod->on)
-      printf("(on)\n");
-    else
-      printf("(off)\n");
-    dm = dm->next;
-  }
+    /* describe each debug module */
+    srtp_err_report(srtp_err_level_info, "debug modules loaded:\n");
+    while (dm != NULL) {
+        srtp_err_report(srtp_err_level_info, "  %s ", dm->mod->name);
+        if (dm->mod->on) {
+            srtp_err_report(srtp_err_level_info, "(on)\n");
+        } else {
+            srtp_err_report(srtp_err_level_info, "(off)\n");
+        }
+        dm = dm->next;
+    }
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_shutdown() {
-  err_status_t status;
-
-  /*
-   * free dynamic memory used in crypto_kernel at present
-   */
+srtp_err_status_t srtp_crypto_kernel_shutdown()
+{
+    /*
+     * free dynamic memory used in crypto_kernel at present
+     */
 
-  /* walk down cipher type list, freeing memory */
-  while (crypto_kernel.cipher_type_list != NULL) {
-    kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
-    crypto_kernel.cipher_type_list = ctype->next;
-    debug_print(mod_crypto_kernel, 
-		"freeing memory for cipher %s", 
-		ctype->cipher_type->description);
-    crypto_free(ctype);
-  }
+    /* walk down cipher type list, freeing memory */
+    while (crypto_kernel.cipher_type_list != NULL) {
+        srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
+        crypto_kernel.cipher_type_list = ctype->next;
+        debug_print(srtp_mod_crypto_kernel, "freeing memory for cipher %s",
+                    ctype->cipher_type->description);
+        srtp_crypto_free(ctype);
+    }
 
-  /* walk down authetication module list, freeing memory */
-  while (crypto_kernel.auth_type_list != NULL) {
-     kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
-     crypto_kernel.auth_type_list = atype->next;
-     debug_print(mod_crypto_kernel, 
-		"freeing memory for authentication %s",
-		atype->auth_type->description);
-     crypto_free(atype);
-  }
+    /* walk down authetication module list, freeing memory */
+    while (crypto_kernel.auth_type_list != NULL) {
+        srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
+        crypto_kernel.auth_type_list = atype->next;
+        debug_print(srtp_mod_crypto_kernel,
+                    "freeing memory for authentication %s",
+                    atype->auth_type->description);
+        srtp_crypto_free(atype);
+    }
 
-  /* walk down debug module list, freeing memory */
-  while (crypto_kernel.debug_module_list != NULL) {
-    kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
-    crypto_kernel.debug_module_list = kdm->next;
-    debug_print(mod_crypto_kernel, 
-		"freeing memory for debug module %s", 
-		kdm->mod->name);
-    crypto_free(kdm);
-  }
+    /* walk down debug module list, freeing memory */
+    while (crypto_kernel.debug_module_list != NULL) {
+        srtp_kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
+        crypto_kernel.debug_module_list = kdm->next;
+        debug_print(srtp_mod_crypto_kernel,
+                    "freeing memory for debug module %s", kdm->mod->name);
+        srtp_crypto_free(kdm);
+    }
 
-  /* de-initialize random number generator */  status = rand_source_deinit();
-  if (status)
-    return status;
+    /* return to insecure state */
+    crypto_kernel.state = srtp_crypto_kernel_state_insecure;
 
-  /* return to insecure state */
-  crypto_kernel.state = crypto_kernel_state_insecure;
-  
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-static inline err_status_t
-crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id,
-				  int replace) {
-  kernel_cipher_type_t *ctype, *new_ctype;
-  err_status_t status;
-
-  /* defensive coding */
-  if (new_ct == NULL)
-    return err_status_bad_param;
-
-  if (new_ct->id != id)
-    return err_status_bad_param;
+static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type(
+    const srtp_cipher_type_t *new_ct,
+    srtp_cipher_type_id_t id,
+    int replace)
+{
+    srtp_kernel_cipher_type_t *ctype, *new_ctype;
+    srtp_err_status_t status;
 
-  /* check cipher type by running self-test */
-  status = cipher_type_self_test(new_ct);
-  if (status) {
-    return status;
-  }
+    /* defensive coding */
+    if (new_ct == NULL) {
+        return srtp_err_status_bad_param;
+    }
 
-  /* walk down list, checking if this type is in the list already  */
-  ctype = crypto_kernel.cipher_type_list;
-  while (ctype != NULL) {
-    if (id == ctype->id) {
-      if (!replace)
-	return err_status_bad_param;
-      status = cipher_type_test(new_ct, ctype->cipher_type->test_data);
-      if (status)
-	return status;
-      new_ctype = ctype;
-      break;
+    if (new_ct->id != id) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* check cipher type by running self-test */
+    status = srtp_cipher_type_self_test(new_ct);
+    if (status) {
+        return status;
     }
-    else if (new_ct == ctype->cipher_type)
-      return err_status_bad_param;    
-    ctype = ctype->next;
-  }
-
-  /* if not found, put new_ct at the head of the list */
-  if (ctype == NULL) {
-  /* allocate memory */
-    new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
-    if (new_ctype == NULL)
-      return err_status_alloc_fail;
-    new_ctype->next = crypto_kernel.cipher_type_list;
 
-    /* set head of list to new cipher type */
-    crypto_kernel.cipher_type_list = new_ctype;    
-  }
-    
-  /* set fields */
-  new_ctype->cipher_type = new_ct;
-  new_ctype->id = id;
+    /* walk down list, checking if this type is in the list already  */
+    ctype = crypto_kernel.cipher_type_list;
+    while (ctype != NULL) {
+        if (id == ctype->id) {
+            if (!replace) {
+                return srtp_err_status_bad_param;
+            }
+            status =
+                srtp_cipher_type_test(new_ct, ctype->cipher_type->test_data);
+            if (status) {
+                return status;
+            }
+            new_ctype = ctype;
+            break;
+        } else if (new_ct == ctype->cipher_type) {
+            return srtp_err_status_bad_param;
+        }
+        ctype = ctype->next;
+    }
 
-  /* load debug module, if there is one present */
-  if (new_ct->debug != NULL)
-    crypto_kernel_load_debug_module(new_ct->debug);
-  /* we could check for errors here */
+    /* if not found, put new_ct at the head of the list */
+    if (ctype == NULL) {
+        /* allocate memory */
+        new_ctype = (srtp_kernel_cipher_type_t *)srtp_crypto_alloc(
+            sizeof(srtp_kernel_cipher_type_t));
+        if (new_ctype == NULL) {
+            return srtp_err_status_alloc_fail;
+        }
+        new_ctype->next = crypto_kernel.cipher_type_list;
 
-  return err_status_ok;
-}
+        /* set head of list to new cipher type */
+        crypto_kernel.cipher_type_list = new_ctype;
+    }
 
-err_status_t
-crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
-  return crypto_kernel_do_load_cipher_type(new_ct, id, 0);
+    /* set fields */
+    new_ctype->cipher_type = new_ct;
+    new_ctype->id = id;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
-  return crypto_kernel_do_load_cipher_type(new_ct, id, 1);
+srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
+    const srtp_cipher_type_t *new_ct,
+    srtp_cipher_type_id_t id)
+{
+    return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 0);
+}
+
+srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *new_ct,
+                                           srtp_cipher_type_id_t id)
+{
+    return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 1);
 }
 
-err_status_t
-crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id,
-				int replace) {
-  kernel_auth_type_t *atype, *new_atype;
-  err_status_t status;
-
-  /* defensive coding */
-  if (new_at == NULL)
-    return err_status_bad_param;
-
-  if (new_at->id != id)
-    return err_status_bad_param;
+srtp_err_status_t srtp_crypto_kernel_do_load_auth_type(
+    const srtp_auth_type_t *new_at,
+    srtp_auth_type_id_t id,
+    int replace)
+{
+    srtp_kernel_auth_type_t *atype, *new_atype;
+    srtp_err_status_t status;
 
-  /* check auth type by running self-test */
-  status = auth_type_self_test(new_at);
-  if (status) {
-    return status;
-  }
+    /* defensive coding */
+    if (new_at == NULL) {
+        return srtp_err_status_bad_param;
+    }
 
-  /* walk down list, checking if this type is in the list already  */
-  atype = crypto_kernel.auth_type_list;
-  while (atype != NULL) {
-    if (id == atype->id) {
-      if (!replace)
-	return err_status_bad_param;
-      status = auth_type_test(new_at, atype->auth_type->test_data);
-      if (status)
-	return status;
-      new_atype = atype;
-      break;
+    if (new_at->id != id) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* check auth type by running self-test */
+    status = srtp_auth_type_self_test(new_at);
+    if (status) {
+        return status;
     }
-    else if (new_at == atype->auth_type)
-      return err_status_bad_param;    
-    atype = atype->next;
-  }
 
-  /* if not found, put new_at at the head of the list */
-  if (atype == NULL) {
-    /* allocate memory */
-    new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
-    if (new_atype == NULL)
-      return err_status_alloc_fail;
+    /* walk down list, checking if this type is in the list already  */
+    atype = crypto_kernel.auth_type_list;
+    while (atype != NULL) {
+        if (id == atype->id) {
+            if (!replace) {
+                return srtp_err_status_bad_param;
+            }
+            status = srtp_auth_type_test(new_at, atype->auth_type->test_data);
+            if (status) {
+                return status;
+            }
+            new_atype = atype;
+            break;
+        } else if (new_at == atype->auth_type) {
+            return srtp_err_status_bad_param;
+        }
+        atype = atype->next;
+    }
 
-    new_atype->next = crypto_kernel.auth_type_list;
-    /* set head of list to new auth type */
-    crypto_kernel.auth_type_list = new_atype;
-  }
-    
-  /* set fields */
-  new_atype->auth_type = new_at;
-  new_atype->id = id;
+    /* if not found, put new_at at the head of the list */
+    if (atype == NULL) {
+        /* allocate memory */
+        new_atype = (srtp_kernel_auth_type_t *)srtp_crypto_alloc(
+            sizeof(srtp_kernel_auth_type_t));
+        if (new_atype == NULL) {
+            return srtp_err_status_alloc_fail;
+        }
 
-  /* load debug module, if there is one present */
-  if (new_at->debug != NULL)
-    crypto_kernel_load_debug_module(new_at->debug);
-  /* we could check for errors here */
+        new_atype->next = crypto_kernel.auth_type_list;
+        /* set head of list to new auth type */
+        crypto_kernel.auth_type_list = new_atype;
+    }
 
-  return err_status_ok;
-
-}
+    /* set fields */
+    new_atype->auth_type = new_at;
+    new_atype->id = id;
 
-err_status_t
-crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
-  return crypto_kernel_do_load_auth_type(new_at, id, 0);
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) {
-  return crypto_kernel_do_load_auth_type(new_at, id, 1);
+srtp_err_status_t srtp_crypto_kernel_load_auth_type(
+    const srtp_auth_type_t *new_at,
+    srtp_auth_type_id_t id)
+{
+    return srtp_crypto_kernel_do_load_auth_type(new_at, id, 0);
+}
+
+srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *new_at,
+                                         srtp_auth_type_id_t id)
+{
+    return srtp_crypto_kernel_do_load_auth_type(new_at, id, 1);
 }
 
+const srtp_cipher_type_t *srtp_crypto_kernel_get_cipher_type(
+    srtp_cipher_type_id_t id)
+{
+    srtp_kernel_cipher_type_t *ctype;
 
-cipher_type_t *
-crypto_kernel_get_cipher_type(cipher_type_id_t id) {
-  kernel_cipher_type_t *ctype;
-  
-  /* walk down list, looking for id  */
-  ctype = crypto_kernel.cipher_type_list;
-  while (ctype != NULL) {
-    if (id == ctype->id)
-      return ctype->cipher_type; 
-    ctype = ctype->next;
-  } 
+    /* walk down list, looking for id  */
+    ctype = crypto_kernel.cipher_type_list;
+    while (ctype != NULL) {
+        if (id == ctype->id) {
+            return ctype->cipher_type;
+        }
+        ctype = ctype->next;
+    }
 
-  /* haven't found the right one, indicate failure by returning NULL */
-  return NULL;
+    /* haven't found the right one, indicate failure by returning NULL */
+    return NULL;
 }
 
-
-err_status_t
-crypto_kernel_alloc_cipher(cipher_type_id_t id, 
-			      cipher_pointer_t *cp, 
-			      int key_len) {
-  cipher_type_t *ct;
+srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id,
+                                                  srtp_cipher_pointer_t *cp,
+                                                  int key_len,
+                                                  int tag_len)
+{
+    const srtp_cipher_type_t *ct;
 
-  /* 
-   * if the crypto_kernel is not yet initialized, we refuse to allocate
-   * any ciphers - this is a bit extra-paranoid
-   */
-  if (crypto_kernel.state != crypto_kernel_state_secure)
-    return err_status_init_fail;
+    /*
+     * if the crypto_kernel is not yet initialized, we refuse to allocate
+     * any ciphers - this is a bit extra-paranoid
+     */
+    if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
+        return srtp_err_status_init_fail;
+    }
 
-  ct = crypto_kernel_get_cipher_type(id);
-  if (!ct)
-    return err_status_fail;
-  
-  return ((ct)->alloc(cp, key_len));
+    ct = srtp_crypto_kernel_get_cipher_type(id);
+    if (!ct) {
+        return srtp_err_status_fail;
+    }
+
+    return ((ct)->alloc(cp, key_len, tag_len));
 }
 
-
+const srtp_auth_type_t *srtp_crypto_kernel_get_auth_type(srtp_auth_type_id_t id)
+{
+    srtp_kernel_auth_type_t *atype;
 
-auth_type_t *
-crypto_kernel_get_auth_type(auth_type_id_t id) {
-  kernel_auth_type_t *atype;
-  
-  /* walk down list, looking for id  */
-  atype = crypto_kernel.auth_type_list;
-  while (atype != NULL) {
-    if (id == atype->id)
-      return atype->auth_type; 
-    atype = atype->next;
-  } 
+    /* walk down list, looking for id  */
+    atype = crypto_kernel.auth_type_list;
+    while (atype != NULL) {
+        if (id == atype->id) {
+            return atype->auth_type;
+        }
+        atype = atype->next;
+    }
 
-  /* haven't found the right one, indicate failure by returning NULL */
-  return NULL;
+    /* haven't found the right one, indicate failure by returning NULL */
+    return NULL;
 }
 
-err_status_t
-crypto_kernel_alloc_auth(auth_type_id_t id, 
-			 auth_pointer_t *ap, 
-			 int key_len,
-			 int tag_len) {
-  auth_type_t *at;
+srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id,
+                                                srtp_auth_pointer_t *ap,
+                                                int key_len,
+                                                int tag_len)
+{
+    const srtp_auth_type_t *at;
 
-  /* 
-   * if the crypto_kernel is not yet initialized, we refuse to allocate
-   * any auth functions - this is a bit extra-paranoid
-   */
-  if (crypto_kernel.state != crypto_kernel_state_secure)
-    return err_status_init_fail;
+    /*
+     * if the crypto_kernel is not yet initialized, we refuse to allocate
+     * any auth functions - this is a bit extra-paranoid
+     */
+    if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
+        return srtp_err_status_init_fail;
+    }
 
-  at = crypto_kernel_get_auth_type(id);
-  if (!at)
-    return err_status_fail;
-  
-  return ((at)->alloc(ap, key_len, tag_len));
+    at = srtp_crypto_kernel_get_auth_type(id);
+    if (!at) {
+        return srtp_err_status_fail;
+    }
+
+    return ((at)->alloc(ap, key_len, tag_len));
 }
 
-err_status_t
-crypto_kernel_load_debug_module(debug_module_t *new_dm) {
-  kernel_debug_module_t *kdm, *new;
+srtp_err_status_t srtp_crypto_kernel_load_debug_module(
+    srtp_debug_module_t *new_dm)
+{
+    srtp_kernel_debug_module_t *kdm, *new;
 
-  /* defensive coding */
-  if (new_dm == NULL)
-    return err_status_bad_param;
+    /* defensive coding */
+    if (new_dm == NULL) {
+        return srtp_err_status_bad_param;
+    }
 
-  /* walk down list, checking if this type is in the list already  */
-  kdm = crypto_kernel.debug_module_list;
-  while (kdm != NULL) {
-    if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)
-      return err_status_bad_param;    
-    kdm = kdm->next;
-  }
+    /* walk down list, checking if this type is in the list already  */
+    kdm = crypto_kernel.debug_module_list;
+    while (kdm != NULL) {
+        if (strncmp(new_dm->name, kdm->mod->name, 64) == 0) {
+            return srtp_err_status_bad_param;
+        }
+        kdm = kdm->next;
+    }
 
-  /* put new_dm at the head of the list */
-  /* allocate memory */
-  new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));
-  if (new == NULL)
-    return err_status_alloc_fail;
-    
-  /* set fields */
-  new->mod = new_dm;
-  new->next = crypto_kernel.debug_module_list;
+    /* put new_dm at the head of the list */
+    /* allocate memory */
+    new = (srtp_kernel_debug_module_t *)srtp_crypto_alloc(
+        sizeof(srtp_kernel_debug_module_t));
+    if (new == NULL) {
+        return srtp_err_status_alloc_fail;
+    }
 
-  /* set head of list to new cipher type */
-  crypto_kernel.debug_module_list = new;    
+    /* set fields */
+    new->mod = new_dm;
+    new->next = crypto_kernel.debug_module_list;
 
-  return err_status_ok;
+    /* set head of list to new cipher type */
+    crypto_kernel.debug_module_list = new;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-crypto_kernel_set_debug_module(char *name, int on) {
-  kernel_debug_module_t *kdm;
-  
-  /* walk down list, checking if this type is in the list already  */
-  kdm = crypto_kernel.debug_module_list;
-  while (kdm != NULL) {
-    if (strncmp(name, kdm->mod->name, 64) == 0) {
-      kdm->mod->on = on;
-      return err_status_ok;
+srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *name, int on)
+{
+    srtp_kernel_debug_module_t *kdm;
+
+    /* walk down list, checking if this type is in the list already  */
+    kdm = crypto_kernel.debug_module_list;
+    while (kdm != NULL) {
+        if (strncmp(name, kdm->mod->name, 64) == 0) {
+            kdm->mod->on = on;
+            return srtp_err_status_ok;
+        }
+        kdm = kdm->next;
     }
-    kdm = kdm->next;
-  }
 
-  return err_status_fail;
+    return srtp_err_status_fail;
 }
-
-err_status_t
-crypto_get_random(unsigned char *buffer, unsigned int length) {
-  if (crypto_kernel.state == crypto_kernel_state_secure)
-    return ctr_prng_get_octet_string(buffer, length);
-  else
-    return err_status_fail;
-}
--- a/netwerk/srtp/src/crypto/kernel/err.c
+++ b/netwerk/srtp/src/crypto/kernel/err.c
@@ -2,148 +2,107 @@
  * err.c
  *
  * error status reporting functions
  *
  * 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
  * 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 "err.h"
-
-#ifdef ERR_REPORTING_SYSLOG
-# ifdef HAVE_SYSLOG_H
-#  include <syslog.h>
-# endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
 #endif
 
-
-/*  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) {
+#include "err.h"
+#include "datatypes.h"
+#include <string.h>
 
-  return err_status_ok;
-}
+/* srtp_err_file is the FILE to which errors are reported */
 
-#else /* SRTP_KERNEL_LINUX */	
-
-/* err_file is the FILE to which errors are reported */
-
-static FILE *err_file = NULL;
+static FILE *srtp_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;
+    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;
+    }
 #endif
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-void
-err_report(int priority, char *format, ...) {
-  va_list args;
-
-  if ((err_reporting_level_t)priority <= err_level) {
+static srtp_err_report_handler_func_t *srtp_err_report_handler = NULL;
 
-    va_start(args, format);
-    if (err_file != NULL) {
-      vfprintf(err_file, format, args);
-	  /*      fprintf(err_file, "\n"); */
-    }
-#ifdef ERR_REPORTING_SYSLOG
-    if (1) { /* FIXME: Make this a runtime option. */
-      int syslogpri;
+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;
+}
 
-      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);
+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);
     }
-#endif
-    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);
+    }
 }
-#endif /* SRTP_KERNEL_LINUX */	
-
-void
-err_reporting_set_level(err_reporting_level_t lvl) { 
-  err_level = lvl;
-}
--- a/netwerk/srtp/src/crypto/kernel/key.c
+++ b/netwerk/srtp/src/crypto/kernel/key.c
@@ -1,115 +1,122 @@
 /*
  * 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
  * 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 "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;
 }
-
--- a/netwerk/srtp/src/crypto/math/datatypes.c
+++ b/netwerk/srtp/src/crypto/math/datatypes.c
@@ -3,720 +3,486 @@
  *
  * data types for finite fields and functions for input, output, and
  * manipulation
  *
  * 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
  * 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
+
+#ifdef OPENSSL
+#include <openssl/crypto.h>
+#endif
+
 #include "datatypes.h"
 
-// MOZILLA: upstream code lacks |static const| and uses |int| elements, which
-// means it isn't read-only and so cannot be shared between processes, and is
-// four times bigger than necessary. Please preserve these changes until they
-// are upstreamed.
-static const int8_t
-octet_weight[256] = {
-  0, 1, 1, 2, 1, 2, 2, 3,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  5, 6, 6, 7, 6, 7, 7, 8
+static const int8_t octet_weight[256] = {
+    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
+    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
 };
 
-int
-octet_get_weight(uint8_t octet) {
-  // MOZILLA: upstream code here is slightly different due to the changes we've
-  // made to octet_weight's declaration above
-  return (int)octet_weight[octet];
+int octet_get_weight(uint8_t octet)
+{
+    return (int)octet_weight[octet];
 }
 
 /*
  * bit_string is a buffer that is used to hold output strings, e.g.
  * for printing.
  */
 
 /* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */
 
 char bit_string[MAX_PRINT_STRING_LEN];
 
-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_string_hex_string(const void *s, int length) {
-  const uint8_t *str = (const uint8_t *)s;
-  int i;
-  
-  /* double length, since one octet takes two hex characters */
-  length *= 2;
-
-  /* truncate string if it would be too long */
-  if (length > MAX_PRINT_STRING_LEN)
-    length = MAX_PRINT_STRING_LEN-1;
-  
-  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] = 0; /* null terminate string */
-  return bit_string;
+uint8_t srtp_nibble_to_hex_char(uint8_t nibble)
+{
+    char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+    return buf[nibble & 0xF];
 }
 
-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 */
-  return -1;  /* this keeps compilers from complaining */
+char *srtp_octet_string_hex_string(const void *s, int length)
+{
+    const uint8_t *str = (const uint8_t *)s;
+    int i;
+
+    /* double length, since one octet takes two hex characters */
+    length *= 2;
+
+    /* truncate string if it would be too long */
+    if (length > MAX_PRINT_STRING_LEN)
+        length = MAX_PRINT_STRING_LEN - 2;
+
+    for (i = 0; i < length; i += 2) {
+        bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
+        bit_string[i + 1] = srtp_nibble_to_hex_char(*str++ & 0xF);
+    }
+    bit_string[i] = 0; /* null terminate string */
+    return bit_string;
 }
 
-int
-is_hex_string(char *s) {
-  while(*s != 0)
-    if (hex_char_to_nibble(*s++) == -1)
-      return 0;
-  return 1;
+char *v128_hex_string(v128_t *x)
+{
+    int i, j;
+
+    for (i = j = 0; i < 16; i++) {
+        bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
+        bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
+    }
+
+    bit_string[j] = 0; /* null terminate string */
+    return bit_string;
 }
 
-/*
- * 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;
+char *v128_bit_string(v128_t *x)
+{
+    int j, i;
+    uint32_t mask;
 
-  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;
-}
+    for (j = i = 0; j < 4; j++) {
+        for (mask = 0x80000000; mask > 0; mask >>= 1) {
+            if (x->v32[j] & mask)
+                bit_string[i] = '1';
+            else
+                bit_string[i] = '0';
+            ++i;
+        }
+    }
+    bit_string[128] = 0; /* null terminate string */
 
-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;
+    return bit_string;
 }
 
-char *
-v128_bit_string(v128_t *x) {
-  int j, i;
-  uint32_t mask;
-  
-  for (j=i=0; j < 4; j++) {
-    for (mask=0x80000000; mask > 0; mask >>= 1) {
-      if (x->v32[j] & mask)
-	bit_string[i] = '1';
-      else
-	bit_string[i] = '0';
-      ++i;
-    }
-  }
-  bit_string[128] = 0; /* null terminate string */
-
-  return bit_string;
-}
-
-void
-v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
+void v128_copy_octet_string(v128_t *x, const uint8_t s[16])
+{
 #ifdef ALIGNMENT_32BIT_REQUIRED
-  if ((((uint32_t) &s[0]) & 0x3) != 0)
+    if ((((uint32_t)&s[0]) & 0x3) != 0)
 #endif
-  {
-	  x->v8[0]  = s[0];
-	  x->v8[1]  = s[1];
-	  x->v8[2]  = s[2];
-	  x->v8[3]  = s[3];
-	  x->v8[4]  = s[4];
-	  x->v8[5]  = s[5];
-	  x->v8[6]  = s[6];
-	  x->v8[7]  = s[7];
-	  x->v8[8]  = s[8];
-	  x->v8[9]  = s[9];
-	  x->v8[10] = s[10];
-	  x->v8[11] = s[11];
-	  x->v8[12] = s[12];
-	  x->v8[13] = s[13];
-	  x->v8[14] = s[14];
-	  x->v8[15] = s[15];
-  }
+    {
+        x->v8[0] = s[0];
+        x->v8[1] = s[1];
+        x->v8[2] = s[2];
+        x->v8[3] = s[3];
+        x->v8[4] = s[4];
+        x->v8[5] = s[5];
+        x->v8[6] = s[6];
+        x->v8[7] = s[7];
+        x->v8[8] = s[8];
+        x->v8[9] = s[9];
+        x->v8[10] = s[10];
+        x->v8[11] = s[11];
+        x->v8[12] = s[12];
+        x->v8[13] = s[13];
+        x->v8[14] = s[14];
+        x->v8[15] = s[15];
+    }
 #ifdef ALIGNMENT_32BIT_REQUIRED
-  else 
-  {
-	  v128_t *v = (v128_t *) &s[0];
+    else {
+        v128_t *v = (v128_t *)&s[0];
 
-	  v128_copy(x,v);
-  }
+        v128_copy(x, v);
+    }
 #endif
 }
 
 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */
 
-void
-v128_set_to_zero(v128_t *x) {
-  _v128_set_to_zero(x);
+void v128_set_to_zero(v128_t *x)
+{
+    _v128_set_to_zero(x);
 }
 
-void
-v128_copy(v128_t *x, const v128_t *y) {
-  _v128_copy(x, y);
+void v128_copy(v128_t *x, const v128_t *y)
+{
+    _v128_copy(x, y);
 }
 
-void
-v128_xor(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_xor(z, x, y);
-} 
-
-void
-v128_and(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_and(z, x, y);
+void v128_xor(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_xor(z, x, y);
 }
 
-void
-v128_or(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_or(z, x, y);
+void v128_and(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_and(z, x, y);
 }
 
-void
-v128_complement(v128_t *x) {
-  _v128_complement(x);
+void v128_or(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_or(z, x, y);
+}
+
+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_is_eq(const v128_t *x, const v128_t *y)
+{
+    return _v128_is_eq(x, y);
 }
 
-int
-v128_xor_eq(v128_t *x, const v128_t *y) {
-  return _v128_xor_eq(x, y);
+int v128_xor_eq(v128_t *x, const v128_t *y)
+{
+    return _v128_xor_eq(x, y);
 }
 
-int
-v128_get_bit(const v128_t *x, int i) {
-  return _v128_get_bit(x, i);
+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);
+void v128_set_bit(v128_t *x, int i)
+{
+    _v128_set_bit(x, i);
 }
 
+void v128_clear_bit(v128_t *x, int i)
+{
+    _v128_clear_bit(x, i);
+}
+
+void v128_set_bit_to(v128_t *x, int i, int y)
+{
+    _v128_set_bit_to(x, i, y);
+}
 
 #endif /* DATATYPES_USE_MACROS */
 
-void
-v128_right_shift(v128_t *x, int shift) {
-  const int base_index = shift >> 5;
-  const int bit_index = shift & 31;
-  int i, from;
-  uint32_t b;
-    
-  if (shift > 127) {
-    v128_set_to_zero(x);
-    return;
-  }
+void v128_right_shift(v128_t *x, int shift)
+{
+    const int base_index = shift >> 5;
+    const int bit_index = shift & 31;
+    int i, from;
+    uint32_t b;
 
-  if (bit_index == 0) {
+    if (shift > 127) {
+        v128_set_to_zero(x);
+        return;
+    }
 
-    /* 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];
+    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;
+    } 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;
-  
+    /* now wrap up the final portion */
+    for (i = 0; i < base_index; i++)
+        x->v32[i] = 0;
 }
 
-void
-v128_left_shift(v128_t *x, int shift) {
-  int i;
-  const int base_index = shift >> 5;
-  const int bit_index = shift & 31;
+void v128_left_shift(v128_t *x, int shift)
+{
+    int i;
+    const int base_index = shift >> 5;
+    const int bit_index = shift & 31;
+
+    if (shift > 127) {
+        v128_set_to_zero(x);
+        return;
+    }
 
-  if (shift > 127) {
-    v128_set_to_zero(x);
-    return;
-  } 
-  
-  if (bit_index == 0) {
-    for (i=0; i < 4 - base_index; i++)
-      x->v32[i] = x->v32[i+base_index];
-  } else {
-    for (i=0; i < 4 - base_index - 1; i++)
-      x->v32[i] = (x->v32[i+base_index] >> bit_index) ^
-	(x->v32[i+base_index+1] << (32 - bit_index));
-    x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index;
-  }
+    if (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;
-
+    /* now wrap up the final portion */
+    for (i = 4 - base_index; i < 4; i++)
+        x->v32[i] = 0;
 }
 
 /* functions manipulating bitvector_t */
 
 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */
 
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index)
+int bitvector_get_bit(const bitvector_t *v, int bit_index)
 {
-  return _bitvector_get_bit(v, bit_index);
+    return _bitvector_get_bit(v, bit_index);
 }
 
-void
-bitvector_set_bit(bitvector_t *v, int bit_index)
+void bitvector_set_bit(bitvector_t *v, int bit_index)
 {
-  _bitvector_set_bit(v, bit_index);
+    _bitvector_set_bit(v, bit_index);
 }
 
-void
-bitvector_clear_bit(bitvector_t *v, int bit_index)
+void bitvector_clear_bit(bitvector_t *v, int bit_index)
 {
-  _bitvector_clear_bit(v, bit_index);
+    _bitvector_clear_bit(v, bit_index);
 }
 
-
 #endif /* DATATYPES_USE_MACROS */
 
-int
-bitvector_alloc(bitvector_t *v, unsigned long length) {
-  unsigned long l;
+int bitvector_alloc(bitvector_t *v, unsigned long length)
+{
+    unsigned long l;
 
-  /* Round length up to a multiple of bits_per_word */
-  length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
+    /* Round length up to a multiple of bits_per_word */
+    length =
+        (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
 
-  l = length / bits_per_word * bytes_per_word;
+    l = length / bits_per_word * bytes_per_word;
 
-  /* allocate memory, then set parameters */
-  if (l == 0)
-    v->word = NULL;
-  else {
-    v->word = (uint32_t*)crypto_alloc(l);
-    if (v->word == NULL) {
-      v->word = NULL;
-      v->length = 0;
-      return -1;
+    /* allocate memory, then set parameters */
+    if (l == 0)
+        v->word = NULL;
+    else {
+        v->word = (uint32_t *)srtp_crypto_alloc(l);
+        if (v->word == NULL) {
+            v->length = 0;
+            return -1;
+        }
     }
-  }
-  v->length = length;
-
-  /* initialize bitvector to zero */
-  bitvector_set_to_zero(v);
-
-  return 0;
-}
-
+    v->length = length;
 
-void
-bitvector_dealloc(bitvector_t *v) {
-  if (v->word != NULL)
-    crypto_free(v->word);
-  v->word = NULL;
-  v->length = 0;
-}
+    /* initialize bitvector to zero */
+    bitvector_set_to_zero(v);
 
-void
-bitvector_set_to_zero(bitvector_t *x)
-{
-  /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
-  memset(x->word, 0, x->length >> 3);
+    return 0;
 }
 
-char *
-bitvector_bit_string(bitvector_t *x, char* buf, int len) {
-  int j, i;
-  uint32_t mask;
-  
-  for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) {
-    for (mask=0x80000000; mask > 0; mask >>= 1) {
-      if (x->word[j] & mask)
-	buf[i] = '1';
-      else
-	buf[i] = '0';
-      ++i;
-      if (i >= len-1)
-        break;
-    }
-  }
-  buf[i] = 0; /* null terminate string */
+void bitvector_dealloc(bitvector_t *v)
+{
+    if (v->word != NULL)
+        srtp_crypto_free(v->word);
+    v->word = NULL;
+    v->length = 0;
+}
 
-  return buf;
+void bitvector_set_to_zero(bitvector_t *x)
+{
+    /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
+    memset(x->word, 0, x->length >> 3);
 }
 
-void
-bitvector_left_shift(bitvector_t *x, int shift) {
-  int i;
-  const int base_index = shift >> 5;
-  const int bit_index = shift & 31;
-  const int word_length = x->length >> 5;
-
-  if (shift >= (int)x->length) {
-    bitvector_set_to_zero(x);
-    return;
-  } 
-  
-  if (bit_index == 0) {
-    for (i=0; i < word_length - base_index; i++)
-      x->word[i] = x->word[i+base_index];
-  } else {
-    for (i=0; i < word_length - base_index - 1; i++)
-      x->word[i] = (x->word[i+base_index] >> bit_index) ^
-	(x->word[i+base_index+1] << (32 - bit_index));
-    x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index;
-  }
+char *bitvector_bit_string(bitvector_t *x, char *buf, int len)
+{
+    int j, i;
+    uint32_t mask;
 
-  /* now wrap up the final portion */
-  for (i = word_length - base_index; i < word_length; i++) 
-    x->word[i] = 0;
-
-}
-
+    for (j = i = 0; j < (int)(x->length >> 5) && i < len - 1; j++) {
+        for (mask = 0x80000000; mask > 0; mask >>= 1) {
+            if (x->word[j] & mask)
+                buf[i] = '1';
+            else
+                buf[i] = '0';
+            ++i;
+            if (i >= len - 1)
+                break;
+        }
+    }
+    buf[i] = 0; /* null terminate string */
 
-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);
-  
+    return buf;
 }
 
+void bitvector_left_shift(bitvector_t *x, int shift)
+{
+    int i;
+    const int base_index = shift >> 5;
+    const int bit_index = shift & 31;
+    const int word_length = x->length >> 5;
 
-/*
- *  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
- */
+    if (shift >= (int)x->length) {
+        bitvector_set_to_zero(x);
+        return;
+    }
+
+    if (bit_index == 0) {
+        for (i = 0; i < word_length - base_index; i++)
+            x->word[i] = x->word[i + base_index];
+    } else {
+        for (i = 0; i < word_length - base_index - 1; i++)
+            x->word[i] = (x->word[i + base_index] >> bit_index) ^
+                         (x->word[i + base_index + 1] << (32 - bit_index));
+        x->word[word_length - base_index - 1] =
+            x->word[word_length - 1] >> bit_index;
+    }
 
-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;
+    /* now wrap up the final portion */
+    for (i = word_length - base_index; i < word_length; i++)
+        x->word[i] = 0;
+}
+
+int octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
+{
+    uint8_t *end = b + len;
+    uint8_t accumulator = 0;
+
+    /*
+     * We use this somewhat obscure implementation to try to ensure the running
+     * time only depends on len, even accounting for compiler optimizations.
+     * The accumulator ends up zero iff the strings are equal.
+     */
+    while (b < end)
+        accumulator |= (*a++ ^ *b++);
+
+    /* Return 1 if *not* equal. */
+    return accumulator != 0;
+}
+
+void srtp_cleanse(void *s, size_t len)
+{
+    volatile unsigned char *p = (volatile unsigned char *)s;
+    while (len--)
+        *p++ = 0;
 }
 
-/*
- * base64_string_to_octet_string converts a hexadecimal string
- * of length 2 * len to a raw octet string of length len
- */
+void octet_string_set_to_zero(void *s, size_t len)
+{
+#ifdef OPENSSL
+    OPENSSL_cleanse(s, len);
+#else
+    srtp_cleanse(s, len);
+#endif
+}
 
-int
-base64_string_to_octet_string(char *raw, char *base64, int len) {
-  uint8_t x;
-  int tmp;
-  int base64_len;
+#ifdef TESTAPP_SOURCE
+
+static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                               "abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int base64_block_to_octet_triple(char *out, char *in)
+{
+    unsigned char sextets[4] = { 0 };
+    int j = 0;
+    int i;
 
-  base64_len = 0;
-  while (base64_len < len) {
-    tmp = base64_char_to_sextet(base64[0]);
-    if (tmp == -1)
-      return base64_len;
-    x = (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;
-  }
-  return base64_len;
+    for (i = 0; i < 4; i++) {
+        char *p = strchr(b64chars, in[i]);
+        if (p != NULL)
+            sextets[i] = p - b64chars;
+        else
+            j++;
+    }
+
+    out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
+    if (j < 2)
+        out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
+    if (j < 1)
+        out[2] = (sextets[2] << 6) | sextets[3];
+    return j;
 }
+
+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
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/math/math.c
+++ /dev/null
@@ -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 */
-
-
-
-
-
--- a/netwerk/srtp/src/crypto/math/stat.c
+++ b/netwerk/srtp/src/crypto/math/stat.c
@@ -1,402 +1,213 @@
 /*
  * stats.c
  *
- * statistical tests for randomness (FIPS 140-2, Section 4.9)
- * 
+ * statistical tests
+ *
  * 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
  * 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 = {
-  0,                 /* debugging is off by default */
-  (char *)"stat test"        /* printable module name       */
+srtp_debug_module_t mod_stat = {
+    0,                  /* debugging is off by default */
+    (char *)"stat test" /* printable module name       */
 };
 
 /*
  * each test assumes that 20,000 bits (2500 octets) of data is
  * provided as input
  */
 
 #define STAT_TEST_DATA_LEN 2500
 
-err_status_t
-stat_test_monobit(uint8_t *data) {
-  uint8_t *data_end = data + STAT_TEST_DATA_LEN;
-  uint16_t ones_count;
+srtp_err_status_t stat_test_monobit(uint8_t *data)
+{
+    uint8_t *data_end = data + STAT_TEST_DATA_LEN;
+    uint16_t ones_count;
 
-  ones_count = 0;
-  while (data < data_end) {
-    ones_count += octet_get_weight(*data);
-    data++;
-  }
+    ones_count = 0;
+    while (data < data_end) {
+        ones_count += octet_get_weight(*data);
+        data++;
+    }
 
-  debug_print(mod_stat, "bit count: %d", ones_count);
-  
-  if ((ones_count < 9725) || (ones_count > 10275))
-    return err_status_algo_fail;
+    debug_print(mod_stat, "bit count: %d", ones_count);
 
-  return err_status_ok;
+    if ((ones_count < 9725) || (ones_count > 10275))
+        return srtp_err_status_algo_fail;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-stat_test_poker(uint8_t *data) {
-  int i;
-  uint8_t *data_end = data + STAT_TEST_DATA_LEN;
-  double poker;
-  uint16_t f[16] = {
-    0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0
-  };
-  
-  while (data < data_end) {
-    f[*data & 0x0f]++;    /* increment freq. count for low nibble  */
-    f[(*data) >> 4]++;    /* increment freq. count for high nibble */
-    data++;
-  }
+srtp_err_status_t stat_test_poker(uint8_t *data)
+{
+    int i;
+    uint8_t *data_end = data + STAT_TEST_DATA_LEN;
+    double poker;
+    uint16_t f[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+    while (data < data_end) {
+        f[*data & 0x0f]++; /* increment freq. count for low nibble  */
+        f[(*data) >> 4]++; /* increment freq. count for high nibble */
+        data++;
+    }
 
-  poker = 0.0;
-  for (i=0; i < 16; i++) 
-    poker += (double) f[i] * f[i];
+    poker = 0.0;
+    for (i = 0; i < 16; i++)
+        poker += (double)f[i] * f[i];
 
-  poker *= (16.0 / 5000.0);
-  poker -= 5000.0;
+    poker *= (16.0 / 5000.0);
+    poker -= 5000.0;
 
-  debug_print(mod_stat, "poker test: %f\n", poker);
-    
-  if ((poker < 2.16) || (poker > 46.17))
-    return err_status_algo_fail;
-  
-  return err_status_ok;
+    debug_print(mod_stat, "poker test: %f\n", poker);
+
+    if ((poker < 2.16) || (poker > 46.17))
+        return srtp_err_status_algo_fail;
+
+    return srtp_err_status_ok;
 }
 
-
 /*
  * runs[i] holds the number of runs of size (i-1)
  */
 
-err_status_t
-stat_test_runs(uint8_t *data) {
-  uint8_t *data_end = data + STAT_TEST_DATA_LEN;
-  uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; 
-  uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
-  uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
-  uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
-  int state = 0;
-  uint16_t mask;
-  int i;
-  
-  /*
-   * the state variable holds the number of bits in the
-   * current run (or gap, if negative)
-   */
-  
-  while (data < data_end) {
+srtp_err_status_t stat_test_runs(uint8_t *data)
+{
+    uint8_t *data_end = data + STAT_TEST_DATA_LEN;
+    uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
+    uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
+    uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
+    uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
+    int state = 0;
+    uint16_t mask;
+    int i;
 
-    /* loop over the bits of this byte */
-    for (mask = 1; mask < 256; mask <<= 1) {
-      if (*data & mask) {
-
- 	/* next bit is a one  */
-	if (state > 0) {
+    /*
+     * the state variable holds the number of bits in the
+     * current run (or gap, if negative)
+     */
 
-	  /* prefix is a run, so increment the run-count  */
-	  state++;                          
+    while (data < data_end) {
+        /* loop over the bits of this byte */
+        for (mask = 1; mask < 256; mask <<= 1) {
+            if (*data & mask) {
+                /* next bit is a one  */
+                if (state > 0) {
+                    /* prefix is a run, so increment the run-count  */
+                    state++;
 
-	  /* check for long runs */ 
-	  if (state > 25) {
-		debug_print(mod_stat, ">25 runs: %d", state);
-		return err_status_algo_fail;
-	  }
-
-	} else if (state < 0) {
+                    /* check for long runs */
+                    if (state > 25) {
+                        debug_print(mod_stat, ">25 runs: %d", state);
+                        return srtp_err_status_algo_fail;
+                    }
 
-	  /* prefix is a gap  */
-	  if (state < -25) {
-		debug_print(mod_stat, ">25 gaps: %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) {
+                } else if (state < 0) {
+                    /* prefix is a gap  */
+                    if (state < -25) {
+                        debug_print(mod_stat, ">25 gaps: %d", state);
+                        return srtp_err_status_algo_fail; /* long-runs test
+                                                             failed   */
+                    }
+                    if (state < -6) {
+                        state = -6; /* group together gaps > 5 */
+                    }
+                    gaps[-1 - state]++; /* increment gap count      */
+                    state = 1;          /* set state at one set bit */
+                } else {
+                    /* state is zero; this happens only at initialization */
+                    state = 1;
+                }
+            } else {
+                /* next bit is a zero  */
+                if (state > 0) {
+                    /* prefix is a run */
+                    if (state > 25) {
+                        debug_print(mod_stat, ">25 runs (2): %d", state);
+                        return srtp_err_status_algo_fail; /* long-runs test
+                                                             failed   */
+                    }
+                    if (state > 6) {
+                        state = 6; /* group together runs > 5 */
+                    }
+                    runs[state - 1]++; /* increment run count       */
+                    state = -1;        /* set state at one zero bit */
+                } else if (state < 0) {
+                    /* prefix is a gap, so increment gap-count (decrement state)
+                     */
+                    state--;
 
-	  /* 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   */
-	  }
-	  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) {
+                    /* check for long gaps */
+                    if (state < -25) {
+                        debug_print(mod_stat, ">25 gaps (2): %d", state);
+                        return srtp_err_status_algo_fail;
+                    }
 
-	  /* prefix is a gap, so increment gap-count (decrement state) */
-	  state--;
+                } else {
+                    /* state is zero; this happens only at initialization */
+                    state = -1;
+                }
+            }
+        }
 
-	  /* check for long gaps */ 
-	  if (state < -25) {
-		debug_print(mod_stat, ">25 gaps (2): %d", state);
-	    return err_status_algo_fail;
-	  }
-
-	} else {
-
-	  /* state is zero; this happens only at initialization        */
-	  state = -1;
-	}
-      }
+        /* move along to next octet */
+        data++;
     }
 
-    /* move along to next octet */
-    data++;
-  }
-
-  if (mod_stat.on) {
-    debug_print(mod_stat, "runs test", NULL);
-    for (i=0; i < 6; i++)
-      debug_print(mod_stat, "  runs[]: %d", runs[i]);
-    for (i=0; i < 6; i++)
-      debug_print(mod_stat, "  gaps[]: %d", gaps[i]);
-  }
-
-  /* check run and gap counts against the fixed limits */
-  for (i=0; i < 6; i++) 
-    if (   (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
-	|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
-      return err_status_algo_fail;
-
-  
-  return 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; 
+    if (mod_stat.on) {
+        debug_print(mod_stat, "runs test", NULL);
+        for (i = 0; i < 6; i++)
+            debug_print(mod_stat, "  runs[]: %d", runs[i]);
+        for (i = 0; i < 6; i++)
+            debug_print(mod_stat, "  gaps[]: %d", gaps[i]);
     }
 
-  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;
+    /* check run and gap counts against the fixed limits */
+    for (i = 0; i < 6; i++)
+        if ((runs[i] < lo_value[i]) || (runs[i] > hi_value[i]) ||
+            (gaps[i] < lo_value[i]) || (gaps[i] > hi_value[i]))
+            return srtp_err_status_algo_fail;
 
-  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;
+    return srtp_err_status_ok;
 }
--- a/netwerk/srtp/src/crypto/replay/rdb.c
+++ b/netwerk/srtp/src/crypto/replay/rdb.c
@@ -3,135 +3,135 @@
  *
  * Implements a replay database for packet security
  *
  * 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
  * 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 "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;
-}
-
-/*
- * rdb_check checks to see if index appears in rdb
- */
-
-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;
-
-  /* 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;
+/* 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_add_index adds index to rdb_t (and does *not* check if
+ * 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)
+{
+    /* 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;
+    }
+
+    /* 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;
+}
+
+/*
+ * 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
  */
-
-err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t p_index) {
-  int delta;  
+srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t p_index)
+{
+    unsigned int delta;
 
-  /* here we *assume* that p_index > rdb->window_start */
-
-  delta = (p_index - rdb->window_start);    
-  if (delta < (int)rdb_bits_in_bitmask) {
-
-    /* if the p_index is within the window, set the appropriate bit */
-    v128_set_bit(&rdb->bitmask, delta);
+    if (p_index < rdb->window_start)
+        return srtp_err_status_replay_fail;
 
-  } else { 
-    
-    delta -= rdb_bits_in_bitmask - 1;
+    delta = (p_index - rdb->window_start);
+    if (delta < rdb_bits_in_bitmask) {
+        /* if the p_index is within the window, set the appropriate bit */
+        v128_set_bit(&rdb->bitmask, delta);
+
+    } else {
+        delta -= rdb_bits_in_bitmask - 1;
 
-    /* shift the window forward by delta bits*/
-    v128_left_shift(&rdb->bitmask, delta);
-    v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1);
-    rdb->window_start += delta;
+        /* 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) {
-
-  if (rdb->window_start++ > 0x7fffffff)
-    return err_status_key_expired;
-  return err_status_ok;
+srtp_err_status_t srtp_rdb_increment(srtp_rdb_t *rdb)
+{
+    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;
 }
--- a/netwerk/srtp/src/crypto/replay/rdbx.c
+++ b/netwerk/srtp/src/crypto/replay/rdbx.c
@@ -3,344 +3,384 @@
  *
  * a replay database with extended range, using a rollover counter
  *
  * 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
  * 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 "rdbx.h"
 
-
 /*
  * from RFC 3711:
  *
  * A receiver reconstructs the index i of a packet with sequence
  *  number SEQ using the estimate
  *
  * i = 2^16 * v + SEQ,
  *
  * where v is chosen from the set { ROC-1, ROC, ROC+1 } such that i is
  * closest to the value 2^16 * ROC + s_l.  If the value r+1 is used,
  * then the rollover counter r in the cryptographic context is
  * incremented by one (if the packet containing s is authentic).
  */
 
-
-
 /*
  * 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
- * sequence number that has been received, and the bitmask indicates
+ *
+ * A srtp_rdbx_t consists of a srtp_xtd_seq_num_t and a bitmask.  The index is
+ * highest sequence number that has been received, and the bitmask indicates
  * which of the recent indicies have been received as well.  The
  * highest bit in the bitmask corresponds to the index in the bitmask.
  */
 
-
-void
-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
-  uint32_t guess_roc;
-  uint16_t guess_seq;
-  int difference;
+    uint32_t guess_roc;
+    uint16_t guess_seq;
+    int32_t difference;
 
-  if (local_seq < seq_num_median) {
-    if (s - local_seq > seq_num_median) {
-      guess_roc = local_roc - 1;
-      difference = seq_num_max - s + local_seq;
+    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 = seq_num_max - local_seq + s;
-    } else {
-      difference = s - local_seq;
-      guess_roc = local_roc;
-    }
-  }
-  guess_seq = s;
+    guess_seq = s;
 
-  /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
+/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
 #ifdef NO_64BIT_MATH
-  *guess = make64(guess_roc >> 16,
-				  (guess_roc << 16) | guess_seq);
+    *guess = make64(guess_roc >> 16, (guess_roc << 16) | guess_seq);
 #else
-  *guess = (((uint64_t) guess_roc) << 16) | guess_seq;
+    *guess = (((uint64_t)guess_roc) << 16) | guess_seq;
 #endif
 
-  return difference;
+    return difference;
 }
 
 /*
  * rdbx
  *
  */
 
-
 /*
- *  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
+#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)
+{
+    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 */
 
-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 */
-
-  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)
+{
+    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);
+    }
 
-err_status_t
-rdbx_add_index(rdbx_t *rdbx, int delta) {
-  
-  if (delta > 0) {
-    /* shift forward by delta */
-    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 */
 
-  /* note that we need not consider the case that delta == 0 */
-  
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
-
 /*
- * rdbx_estimate_index(rdbx, guess, s)
- * 
+ * srtp_rdbx_estimate_index(rdbx, guess, s)
+ *
  * given an rdbx and a sequence number s (from a newly arrived packet),
  * 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) {
-
-  /*
-   * 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)
-   */
+int32_t srtp_rdbx_estimate_index(const srtp_rdbx_t *rdbx,
+                                 srtp_xtd_seq_num_t *guess,
+                                 srtp_sequence_number_t s)
+{
+/*
+ * if the sequence number and rollover counter in the rdbx are
+ * non-zero, then use the srtp_index_guess(...) function, otherwise, just
+ * set the rollover counter to zero (since the srtp_index_guess(...)
+ * function might incorrectly guess that the rollover counter is
+ * 0xffffffff)
+ */
 
 #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;
+}
--- a/netwerk/srtp/src/crypto/replay/ut_sim.c
+++ b/netwerk/srtp/src/crypto/replay/ut_sim.c
@@ -1,105 +1,104 @@
 /*
  * ut_sim.c
  *
  * an unreliable transport simulator
  * (for testing replay databases and suchlike)
- * 
+ *
  * 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
  * 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 "ut_sim.h"
 
-
-int
-ut_compar(const void *a, const void *b) {
-  return rand() > (RAND_MAX/2) ? -1 : 1;
+int ut_compar(const void *a, const void *b)
+{
+    return rand() > (RAND_MAX / 2) ? -1 : 1;
 }
 
-void
-ut_init(ut_connection *utc) {
-  int i;
-  utc->index = 0;
+void ut_init(ut_connection *utc)
+{
+    int i;
+    utc->index = 0;
 
-  for (i=0; i < UT_BUF; i++)
-    utc->buffer[i] = i;
-  
-  qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
+    for (i = 0; i < UT_BUF; i++)
+        utc->buffer[i] = i;
 
-  utc->index = UT_BUF - 1;
+    qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
+
+    utc->index = UT_BUF - 1;
 }
 
-uint32_t
-ut_next_index(ut_connection *utc) {
-  uint32_t tmp;
+uint32_t ut_next_index(ut_connection *utc)
+{
+    uint32_t tmp;
 
-  tmp = utc->buffer[0];
-  utc->index++;
-  utc->buffer[0] = utc->index;
+    tmp = utc->buffer[0];
+    utc->index++;
+    utc->buffer[0] = utc->index;
 
-  qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
-  
-  return tmp;
+    qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
+
+    return tmp;
 }
 
-
-
 #ifdef UT_TEST
 
 #include <stdio.h>
 
-int
-main() {
-  uint32_t i, irecvd, idiff;
-  ut_connection utc;
+int main()
+{
+    uint32_t i, irecvd, idiff;
+    ut_connection utc;
 
-  ut_init(&utc);
+    ut_init(&utc);
 
-  for (i=0; i < 1000; i++) {
-    irecvd = ut_next_index(&utc);
-    idiff = i - irecvd;
-    printf("%lu\t%lu\t%d\n", i, irecvd, idiff);
-  }
-  
-  return 0;
+    for (i = 0; i < 1000; i++) {
+        irecvd = ut_next_index(&utc);
+        idiff = i - irecvd;
+        printf("%lu\t%lu\t%d\n", i, irecvd, idiff);
+    }
+
+    return 0;
 }
 
-
 #endif
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/rng/ctr_prng.c
+++ /dev/null
@@ -1,108 +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 */
-  status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30);
-  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 
-   *
-   * avoid 32-bit overflows by subtracting instead of adding
-   */
-  if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
-    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;  
-}
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/rng/prng.c
+++ /dev/null
@@ -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;  
-}
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/rng/rand_linux_kernel.c
+++ /dev/null
@@ -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;  
-}
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/rng/rand_source.c
+++ /dev/null
@@ -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;  
-}
--- a/netwerk/srtp/src/crypto/test/aes_calc.c
+++ b/netwerk/srtp/src/crypto/test/aes_calc.c
@@ -1,154 +1,157 @@
 /*
  * aes_calc.c
- * 
+ *
  * A simple AES calculator for generating AES encryption values
  *
  * 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
  * 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):
- 
-[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v
+
+ [sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f \
+       00112233445566778899aabbccddeeff -v
+
  plaintext:      00112233445566778899aabbccddeeff
  key:            000102030405060708090a0b0c0d0e0f
  ciphertext:     69c4e0d86a7b0430d8cdb78070b4c55a
 
  */
 
+#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) {
-  printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
-  exit(255);
+void usage(char *prog_name)
+{
+    printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
+    exit(255);
 }
 
 #define AES_MAX_KEY_LEN 32
 
-int
-main (int argc, char *argv[]) {
-  v128_t data;
-  uint8_t key[AES_MAX_KEY_LEN];
-  aes_expanded_key_t exp_key;
-  int key_len, len;
-  int verbose;
-  err_status_t status;
+int main(int argc, char *argv[])
+{
+    v128_t data;
+    uint8_t key[AES_MAX_KEY_LEN];
+    srtp_aes_expanded_key_t exp_key;
+    int key_len, len;
+    int verbose = 0;
+    srtp_err_status_t status;
 
-  if (argc == 3) {
-    /* we're not in verbose mode */
-    verbose = 0;
-  } else if (argc == 4) {
-    if (strncmp(argv[3], "-v", 2) == 0) {
-      /* we're in verbose mode */
-      verbose = 1;
+    if (argc == 3) {
+        /* we're not in verbose mode */
+        verbose = 0;
+    } else if (argc == 4) {
+        if (strncmp(argv[3], "-v", 2) == 0) {
+            /* we're in verbose mode */
+            verbose = 1;
+        } else {
+            /* unrecognized flag, complain and exit */
+            usage(argv[0]);
+        }
     } else {
-      /* unrecognized flag, complain and exit */
-      usage(argv[0]);
+        /* we've been fed the wrong number of arguments - compain and exit */
+        usage(argv[0]);
+    }
+
+    /* read in key, checking length */
+    if (strlen(argv[1]) > AES_MAX_KEY_LEN * 2) {
+        fprintf(stderr, "error: too many digits in key "
+                        "(should be at most %d hexadecimal digits, found %u)\n",
+                AES_MAX_KEY_LEN * 2, (unsigned)strlen(argv[1]));
+        exit(1);
+    }
+    len = hex_string_to_octet_string((char *)key, argv[1], AES_MAX_KEY_LEN * 2);
+    /* check that hex string is the right length */
+    if (len != 32 && len != 48 && len != 64) {
+        fprintf(stderr, "error: bad number of digits in key "
+                        "(should be 32/48/64 hexadecimal digits, found %d)\n",
+                len);
+        exit(1);
     }
-  } else {
-    /* we've been fed the wrong number of arguments - compain and exit */
-    usage(argv[0]);
-  }
-  
-  /* read in key, checking length */
-  if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) {
-    fprintf(stderr, 
-	    "error: too many digits in key "
-	    "(should be at most %d hexadecimal digits, found %u)\n",
-	    AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2);
-  /* check that hex string is the right length */
-  if (len != 32 && len != 48 && len != 64) {
-    fprintf(stderr, 
-	    "error: bad number of digits in key "
-	    "(should be 32/48/64 hexadecimal digits, found %d)\n",
-	    len);
-    exit(1);    
-  } 
-  key_len = len/2;
-      
-  /* read in plaintext, checking length */
-  if (strlen(argv[2]) > 16*2) {
-    fprintf(stderr, 
-	    "error: too many digits in plaintext "
-	    "(should be %d hexadecimal digits, found %u)\n",
-	    16*2, (unsigned)strlen(argv[2]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2);
-  /* check that hex string is the right length */
-  if (len < 16*2) {
-    fprintf(stderr, 
-	    "error: too few digits in plaintext "
-	    "(should be %d hexadecimal digits, found %d)\n",
-	    16*2, len);
-    exit(1);    
-  }
+    key_len = len / 2;
+
+    /* read in plaintext, checking length */
+    if (strlen(argv[2]) > 16 * 2) {
+        fprintf(stderr, "error: too many digits in plaintext "
+                        "(should be %d hexadecimal digits, found %u)\n",
+                16 * 2, (unsigned)strlen(argv[2]));
+        exit(1);
+    }
+    len = hex_string_to_octet_string((char *)(&data), argv[2], 16 * 2);
+    /* check that hex string is the right length */
+    if (len < 16 * 2) {
+        fprintf(stderr, "error: too few digits in plaintext "
+                        "(should be %d hexadecimal digits, found %d)\n",
+                16 * 2, len);
+        exit(1);
+    }
 
-  if (verbose) {
-    /* print out plaintext */
-    printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16));
-  }
-
-  /* encrypt plaintext */
-  status = aes_expand_encryption_key(key, key_len, &exp_key);
-  if (status) {
-    fprintf(stderr,
-	    "error: AES key expansion failed.\n");
-    exit(1);
-  }
+    if (verbose) {
+        /* print out plaintext */
+        printf("plaintext:\t%s\n",
+               octet_string_hex_string((uint8_t *)&data, 16));
+    }
 
-  aes_encrypt(&data, &exp_key);
+    /* encrypt plaintext */
+    status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
+    if (status) {
+        fprintf(stderr, "error: AES key expansion failed.\n");
+        exit(1);
+    }
+
+    srtp_aes_encrypt(&data, &exp_key);
 
-  /* write ciphertext to output */
-  if (verbose) {
-    printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
-    printf("ciphertext:\t");
-  }
-  printf("%s\n", v128_hex_string(&data));
+    /* write ciphertext to output */
+    if (verbose) {
+        printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
+        printf("ciphertext:\t");
+    }
+    printf("%s\n", v128_hex_string(&data));
 
-  return 0;
+    return 0;
 }
-
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/test/auth_driver.c
+++ /dev/null
@@ -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;
-}
-
-
--- a/netwerk/srtp/src/crypto/test/cipher_driver.c
+++ b/netwerk/srtp/src/crypto/test/cipher_driver.c
@@ -3,529 +3,608 @@
  *
  * A driver for the generic cipher type
  *
  * 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
  * 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 rand() */
-#include <string.h>          /* for memset() */
-#include <unistd.h>          /* for getopt() */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>  /* for printf() */
+#include <stdlib.h> /* for rand() */
+#include "getopt_s.h"
 #include "cipher.h"
+#ifdef OPENSSL
+#include "aes_icm_ossl.h"
+#include "aes_gcm_ossl.h"
+#else
 #include "aes_icm.h"
-#include "null_cipher.h"
+#endif
 
 #define PRINT_DEBUG 0
 
-void
-cipher_driver_test_throughput(cipher_t *c);
+void 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);
 
 /*
  * cipher_driver_test_buffering(ct) tests the cipher's output
  * buffering for correctness by checking the consistency of succesive
  * 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, 
-				    int klen, int num_cipher);
+srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
+                                                      int klen,
+                                                      int num_cipher);
 
-void
-cipher_array_test_throughput(cipher_t *ca[], int num_cipher);
+void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
 
-uint64_t
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			     unsigned octets_in_buffer, int num_trials);
+uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
+                                      int num_cipher,
+                                      unsigned octets_in_buffer,
+                                      int num_trials);
 
-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) {
-  printf("usage: %s [ -t | -v | -a ]\n", prog_name);
-  exit(255);
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -t | -v | -a ]\n", prog_name);
+    exit(255);
 }
 
-void
-check_status(err_status_t s) {
-  if (s) {
-    printf("error (code %d)\n", s);
-    exit(s);
-  }
-  return;
+void check_status(srtp_err_status_t s)
+{
+    if (s) {
+        printf("error (code %d)\n", s);
+        exit(s);
+    }
+    return;
 }
 
 /*
- * 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;
-extern cipher_type_t aes_cbc;
-
-int
-main(int argc, char *argv[]) {
-  cipher_t *c = NULL;
-  err_status_t status;
-  unsigned char test_key[48] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-  };
-  int q;
-  unsigned do_timing_test = 0;
-  unsigned do_validation = 0;
-  unsigned do_array_timing_test = 0;
-
-  /* process input arguments */
-  while (1) {
-    q = getopt(argc, argv, "tva");
-    if (q == -1) 
-      break;
-    switch (q) {
-    case 't':
-      do_timing_test = 1;
-      break;
-    case 'v':
-      do_validation = 1;
-      break;
-    case 'a':
-      do_array_timing_test = 1;
-      break;
-    default:
-      usage(argv[0]);
-    }    
-  }
-   
-  printf("cipher test driver\n"
-	 "David A. McGrew\n"
-	 "Cisco Systems, Inc.\n");
-
-  if (!do_validation && !do_timing_test && !do_array_timing_test)
-    usage(argv[0]);
+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
 
-   /* arry timing (cache thrash) test */
-  if (do_array_timing_test) {
-    int max_num_cipher = 1 << 16;   /* number of ciphers in cipher_array */
-    int num_cipher;
-    
-    for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
-      cipher_driver_test_array_throughput(&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); 
-
-    for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
-      cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher); 
-
-    for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
-      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); 
-  }
+int main(int argc, char *argv[])
+{
+    srtp_cipher_t *c = NULL;
+    srtp_err_status_t status;
+    /* clang-format off */
+    unsigned char test_key[48] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    };
+    /* clang-format on */
+    int q;
+    unsigned do_timing_test = 0;
+    unsigned do_validation = 0;
+    unsigned do_array_timing_test = 0;
 
-  if (do_validation) {
-    cipher_driver_self_test(&null_cipher);
-    cipher_driver_self_test(&aes_icm);
-    cipher_driver_self_test(&aes_cbc);
-  }
-
-  /* do timing and/or buffer_test on null_cipher */
-  status = cipher_type_alloc(&null_cipher, &c, 0); 
-  check_status(status);
-
-  status = cipher_init(c, NULL, direction_encrypt);
-  check_status(status);
-
-  if (do_timing_test) 
-    cipher_driver_test_throughput(c);
-  if (do_validation) {
-    status = cipher_driver_test_buffering(c);
-    check_status(status);
-  }
-  status = 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);  
-    if (status) {
-      fprintf(stderr, "error: can't allocate cipher\n");
-      exit(status);
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "tva");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 't':
+            do_timing_test = 1;
+            break;
+        case 'v':
+            do_validation = 1;
+            break;
+        case 'a':
+            do_array_timing_test = 1;
+            break;
+        default:
+            usage(argv[0]);
+        }
     }
 
-    status = cipher_init(c, test_key, direction_encrypt);
+    printf("cipher test driver\n"
+           "David A. McGrew\n"
+           "Cisco Systems, Inc.\n");
+
+    if (!do_validation && !do_timing_test && !do_array_timing_test)
+        usage(argv[0]);
+
+    /* arry timing (cache thrash) test */
+    if (do_array_timing_test) {
+        int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */
+        int num_cipher;
+
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
+            cipher_driver_test_array_throughput(&srtp_null_cipher, 0,
+                                                num_cipher);
+
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
+            cipher_driver_test_array_throughput(
+                &srtp_aes_icm_128, SRTP_AES_ICM_128_KEY_LEN_WSALT, num_cipher);
+
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
+            cipher_driver_test_array_throughput(
+                &srtp_aes_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
+
+#ifdef OPENSSL
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
+            cipher_driver_test_array_throughput(
+                &srtp_aes_icm_192, SRTP_AES_ICM_192_KEY_LEN_WSALT, num_cipher);
+
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
+            cipher_driver_test_array_throughput(&srtp_aes_gcm_128_openssl,
+                                                SRTP_AES_GCM_128_KEY_LEN_WSALT,
+                                                num_cipher);
+        }
+
+        for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
+            cipher_driver_test_array_throughput(&srtp_aes_gcm_256_openssl,
+                                                SRTP_AES_GCM_256_KEY_LEN_WSALT,
+                                                num_cipher);
+        }
+#endif
+    }
+
+    if (do_validation) {
+        cipher_driver_self_test(&srtp_null_cipher);
+        cipher_driver_self_test(&srtp_aes_icm_128);
+        cipher_driver_self_test(&srtp_aes_icm_256);
+#ifdef OPENSSL
+        cipher_driver_self_test(&srtp_aes_icm_192);
+        cipher_driver_self_test(&srtp_aes_gcm_128_openssl);
+        cipher_driver_self_test(&srtp_aes_gcm_256_openssl);
+#endif
+    }
+
+    /* do timing and/or buffer_test on srtp_null_cipher */
+    status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
+    check_status(status);
+
+    status = srtp_cipher_init(c, NULL);
     check_status(status);
 
     if (do_timing_test)
-      cipher_driver_test_throughput(c);
-    
+        cipher_driver_test_throughput(c);
     if (do_validation) {
-      status = cipher_driver_test_buffering(c);
-      check_status(status);
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
     }
-    
-    status = cipher_dealloc(c);
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+
+    /* run the throughput test on the aes_icm cipher (128-bit key) */
+    status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
+                                    SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
+    if (status) {
+        fprintf(stderr, "error: can't allocate cipher\n");
+        exit(status);
+    }
+
+    status = srtp_cipher_init(c, test_key);
     check_status(status);
 
-  /* repeat the tests with 256-bit keys */
-    status = cipher_type_alloc(&aes_icm, &c, 46);  
-    if (status) {
-      fprintf(stderr, "error: can't allocate cipher\n");
-      exit(status);
+    if (do_timing_test)
+        cipher_driver_test_throughput(c);
+
+    if (do_validation) {
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
     }
 
-    status = cipher_init(c, test_key, direction_encrypt);
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+
+    /* repeat the tests with 256-bit keys */
+    status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
+                                    SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
+    if (status) {
+        fprintf(stderr, "error: can't allocate cipher\n");
+        exit(status);
+    }
+
+    status = srtp_cipher_init(c, test_key);
     check_status(status);
 
     if (do_timing_test)
-      cipher_driver_test_throughput(c);
-    
+        cipher_driver_test_throughput(c);
+
     if (do_validation) {
-      status = cipher_driver_test_buffering(c);
-      check_status(status);
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
+    }
+
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+
+#ifdef OPENSSL
+    /* run the throughput test on the aes_gcm_128_openssl cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c,
+                                    SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
+    if (status) {
+        fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
+        exit(status);
+    }
+    status = srtp_cipher_init(c, test_key);
+    check_status(status);
+    if (do_timing_test) {
+        cipher_driver_test_throughput(c);
     }
-    
-    status = cipher_dealloc(c);
+
+    if (do_validation) {
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
+    }
+    status = srtp_cipher_dealloc(c);
     check_status(status);
-  
-  return 0;
+
+    /* run the throughput test on the aes_gcm_256_openssl cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
+                                    SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
+    if (status) {
+        fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
+        exit(status);
+    }
+    status = srtp_cipher_init(c, test_key);
+    check_status(status);
+    if (do_timing_test) {
+        cipher_driver_test_throughput(c);
+    }
+
+    if (do_validation) {
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
+    }
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+#endif
+
+    return 0;
 }
 
-void
-cipher_driver_test_throughput(cipher_t *c) {
-  int i;
-  int min_enc_len = 32;     
-  int max_enc_len = 2048;   /* should be a power of two */
-  int num_trials = 1000000;  
-  
-  printf("timing %s throughput, key length %d:\n", c->type->description, c->key_len);
-  fflush(stdout);
-  for (i=min_enc_len; i <= max_enc_len; i = i * 2)
-    printf("msg len: %d\tgigabits per second: %f\n",
-	   i, cipher_bits_per_second(c, i, num_trials) / 1e9);
+void cipher_driver_test_throughput(srtp_cipher_t *c)
+{
+    int i;
+    int min_enc_len = 32;
+    int max_enc_len = 2048; /* should be a power of two */
+    int num_trials = 1000000;
 
+    printf("timing %s throughput, key length %d:\n", c->type->description,
+           c->key_len);
+    fflush(stdout);
+    for (i = min_enc_len; i <= max_enc_len; i = i * 2)
+        printf("msg len: %d\tgigabits per second: %f\n", i,
+               srtp_cipher_bits_per_second(c, i, num_trials) / 1e9);
 }
 
-err_status_t
-cipher_driver_self_test(cipher_type_t *ct) {
-  err_status_t status;
-  
-  printf("running cipher self-test for %s...", ct->description);
-  status = cipher_type_self_test(ct);
-  if (status) {
-    printf("failed with error code %d\n", status);
-    exit(status);
-  }
-  printf("passed\n");
-  
-  return err_status_ok;
+srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct)
+{
+    srtp_err_status_t status;
+
+    printf("running cipher self-test for %s...", ct->description);
+    status = srtp_cipher_type_self_test(ct);
+    if (status) {
+        printf("failed with error code %d\n", status);
+        exit(status);
+    }
+    printf("passed\n");
+
+    return srtp_err_status_ok;
 }
 
 /*
  * cipher_driver_test_buffering(ct) tests the cipher's output
  * buffering for correctness by checking the consistency of succesive
  * calls
  */
 
-err_status_t
-cipher_driver_test_buffering(cipher_t *c) {
-  int i, j, num_trials = 1000;
-  unsigned len, buflen = 1024;
-  uint8_t buffer0[buflen], buffer1[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;
-  
-  printf("testing output buffering for cipher %s...",
-	 c->type->description);
+#define INITIAL_BUFLEN 1024
+srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c)
+{
+    int i, j, num_trials = 1000;
+    unsigned len, buflen = INITIAL_BUFLEN;
+    uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
+    uint8_t idx[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 };
+    srtp_err_status_t status;
+
+    printf("testing output buffering for cipher %s...", c->type->description);
 
-  for (i=0; i < num_trials; i++) {
+    for (i = 0; i < num_trials; i++) {
+        /* set buffers to zero */
+        for (j = 0; j < (int)buflen; j++) {
+            buffer0[j] = buffer1[j] = 0;
+        }
 
-   /* set buffers to zero */
-    for (j=0; j < buflen; j++) 
-      buffer0[j] = buffer1[j] = 0;
-    
-    /* initialize cipher  */
-    status = cipher_set_iv(c, idx);
-    if (status)
-      return status;
+        /* initialize cipher  */
+        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 = srtp_cipher_encrypt(c, buffer0, &buflen);
+        if (status)
+            return status;
+
+        /* re-initialize cipher */
+        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);
-    if (status)
-      return status;
+        /* now loop over short lengths until buffer1 is encrypted */
+        current = buffer1;
+        end = buffer1 + buflen;
+        while (current < end) {
+            /* choose a short length */
+            len = rand() & 0x01f;
 
-    /* re-initialize cipher */
-    status = cipher_set_iv(c, idx);
-    if (status)
-      return status;
-    
-    /* now loop over short lengths until buffer1 is encrypted */
-    current = buffer1;
-    end = buffer1 + buflen;
-    while (current < end) {
+            /* make sure that len doesn't cause us to overreach the buffer */
+            if (current + len > end)
+                len = end - current;
+
+            status = srtp_cipher_encrypt(c, current, &len);
+            if (status)
+                return status;
+
+            /* advance pointer into buffer1 to reflect encryption */
+            current += len;
 
-      /* choose a short length */
-      len = rand() & 0x01f;
-
-      /* make sure that len doesn't cause us to overreach the buffer */
-      if (current + len > end)
-	len = end - current;
+            /* if buffer1 is all encrypted, break out of loop */
+            if (current == end)
+                break;
+        }
 
-      status = cipher_encrypt(c, current, &len);
-      if (status) 
-	return status;
-      
-      /* advance pointer into buffer1 to reflect encryption */
-      current += len;
-      
-      /* if buffer1 is all encrypted, break out of loop */
-      if (current == end)
-	break;
+        /* compare buffers */
+        for (j = 0; j < (int)buflen; j++) {
+            if (buffer0[j] != buffer1[j]) {
+#if PRINT_DEBUG
+                printf("test case %d failed at byte %d\n", i, j);
+                printf("computed: %s\n",
+                       octet_string_hex_string(buffer1, buflen));
+                printf("expected: %s\n",
+                       octet_string_hex_string(buffer0, buflen));
+#endif
+                return srtp_err_status_algo_fail;
+            }
+        }
     }
 
-    /* compare buffers */
-    for (j=0; j < 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;
-      }
-  }
-  
-  printf("passed\n");
+    printf("passed\n");
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
 /*
  * The function cipher_test_throughput_array() tests the effect of CPU
- * cache thrash on cipher throughput.  
+ * cache thrash on cipher throughput.
  *
  * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
- * of 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) {
-  int i, j;
-  err_status_t status;
-  uint8_t *key;
-  cipher_t **cipher_array;
-  /* pad klen allocation, to handle aes_icm reading 16 bytes for the
-     14-byte salt */
-  int klen_pad = ((klen + 15) >> 4) << 4;
+srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***ca,
+                                          int num_ciphers,
+                                          srtp_cipher_type_t *ctype,
+                                          int klen)
+{
+    int i, j;
+    srtp_err_status_t status;
+    uint8_t *key;
+    srtp_cipher_t **cipher_array;
+    /* pad klen allocation, to handle aes_icm reading 16 bytes for the
+       14-byte salt */
+    int klen_pad = ((klen + 15) >> 4) << 4;
 
-  /* allocate array of pointers to ciphers */
-  cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers);
-  if (cipher_array == NULL)
-    return err_status_alloc_fail;
+    /* allocate array of pointers to ciphers */
+    cipher_array = (srtp_cipher_t **)srtp_crypto_alloc(sizeof(srtp_cipher_t *) *
+                                                       num_ciphers);
+    if (cipher_array == NULL)
+        return srtp_err_status_alloc_fail;
 
-  /* set ca to location of cipher_array */
-  *ca = cipher_array;
+    /* set ca to location of cipher_array */
+    *ca = cipher_array;
 
-  /* allocate key */
-  key = crypto_alloc(klen_pad);
-  if (key == NULL) {
-    free(cipher_array);
-    return err_status_alloc_fail;
-  }
-  
-  /* allocate and initialize an array of ciphers */
-  for (i=0; i < num_ciphers; i++) {
+    /* allocate key */
+    key = srtp_crypto_alloc(klen_pad);
+    if (key == NULL) {
+        srtp_crypto_free(cipher_array);
+        return srtp_err_status_alloc_fail;
+    }
+
+    /* allocate and initialize an array of ciphers */
+    for (i = 0; i < num_ciphers; i++) {
+        /* allocate cipher */
+        status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
+        if (status)
+            return status;
 
-    /* allocate cipher */
-    status = cipher_type_alloc(ctype, cipher_array, klen);
-    if (status)
-      return status;
-    
-    /* generate random key and initialize cipher */
-    for (j=0; j < klen; j++)
-      key[j] = (uint8_t) rand();
-    for (; j < klen_pad; j++)
-      key[j] = 0;
-    status = cipher_init(*cipher_array, key, direction_encrypt);
-    if (status)
-      return status;
+        /* generate random key and initialize cipher */
+        for (j = 0; j < klen; j++)
+            key[j] = (uint8_t)rand();
+        for (; j < klen_pad; j++)
+            key[j] = 0;
+        status = srtp_cipher_init(*cipher_array, key);
+        if (status)
+            return status;
 
-/*     printf("%dth cipher is at %p\n", i, *cipher_array); */
-/*     printf("%dth cipher description: %s\n", i,  */
-/* 	   (*cipher_array)->type->description); */
-    
-    /* advance cipher array pointer */
-    cipher_array++;
-  }
+        /*     printf("%dth cipher is at %p\n", i, *cipher_array); */
+        /*     printf("%dth cipher description: %s\n", i,  */
+        /* 	   (*cipher_array)->type->description); */
 
-  crypto_free(key);
+        /* advance cipher array pointer */
+        cipher_array++;
+    }
 
-  return err_status_ok;
+    srtp_crypto_free(key);
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-cipher_array_delete(cipher_t *cipher_array[], int num_cipher) {
-  int i;
-  
-  for (i=0; i < num_cipher; i++) {
-    cipher_dealloc(cipher_array[i]);
-  }
+srtp_err_status_t cipher_array_delete(srtp_cipher_t *cipher_array[],
+                                      int num_cipher)
+{
+    int i;
 
-  free(cipher_array);
-  
-  return err_status_ok;
+    for (i = 0; i < num_cipher; i++) {
+        srtp_cipher_dealloc(cipher_array[i]);
+    }
+
+    srtp_crypto_free(cipher_array);
+
+    return srtp_err_status_ok;
 }
 
-
 /*
  * cipher_array_bits_per_second(c, l, t) computes (an estimate of) the
  * number of bits that a cipher implementation can encrypt in a second
  * when distinct keys are used to encrypt distinct messages
- * 
+ *
  * c is a cipher (which MUST be allocated an initialized already), l
  * is the length in octets of the test data to be encrypted, and t is
  * the number of trials
  *
  * if an error is encountered, the value 0 is returned
  */
 
-uint64_t
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			      unsigned octets_in_buffer, int num_trials) {
-  int i;
-  v128_t nonce;
-  clock_t timer;
-  unsigned char *enc_buf;
-  int cipher_index = rand() % num_cipher;
+uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
+                                      int num_cipher,
+                                      unsigned octets_in_buffer,
+                                      int num_trials)
+{
+    int i;
+    v128_t nonce;
+    clock_t timer;
+    unsigned char *enc_buf;
+    int cipher_index = rand() % num_cipher;
+
+    /* Over-alloc, for NIST CBC padding */
+    enc_buf = srtp_crypto_alloc(octets_in_buffer + 17);
+    if (enc_buf == NULL)
+        return 0; /* indicate bad parameters by returning null */
 
-  /* Over-alloc, for NIST CBC padding */
-  enc_buf = crypto_alloc(octets_in_buffer+17);
-  if (enc_buf == NULL)
-    return 0;  /* indicate bad parameters by returning null */
-  memset(enc_buf, 0, octets_in_buffer);
-  
-  /* time repeated trials */
-  v128_set_to_zero(&nonce);
-  timer = clock();
-  for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
-    /* length parameter to cipher_encrypt is in/out -- out is total, padded
-     * length -- so reset it each time. */
-    unsigned octets_to_encrypt = octets_in_buffer;
+    /* time repeated trials */
+    v128_set_to_zero(&nonce);
+    timer = clock();
+    for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
+        /* length parameter to srtp_cipher_encrypt is in/out -- out is total,
+         * padded
+         * length -- so reset it each time. */
+        unsigned octets_to_encrypt = octets_in_buffer;
 
-    /* encrypt buffer with cipher */
-    cipher_set_iv(cipher_array[cipher_index], &nonce);
-    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;
-  }
-  timer = clock() - timer;
+        /* encrypt buffer with cipher */
+        srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t *)&nonce,
+                           srtp_direction_encrypt);
+        srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf,
+                            &octets_to_encrypt);
 
-  free(enc_buf);
+        /* choose a cipher at random from the array*/
+        cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
+    }
+    timer = clock() - timer;
+
+    srtp_crypto_free(enc_buf);
 
-  if (timer == 0) {
-    /* Too fast! */
-    return 0;
-  }
+    if (timer == 0) {
+        /* Too fast! */
+        return 0;
+    }
 
-  return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
+    return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
 }
 
-void
-cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
-  int i;
-  int min_enc_len = 16;     
-  int max_enc_len = 2048;   /* should be a power of two */
-  int num_trials = 1000000;
+void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher)
+{
+    int i;
+    int min_enc_len = 16;
+    int max_enc_len = 2048; /* should be a power of two */
+    int num_trials = 1000000;
 
-  printf("timing %s throughput with key length %d, array size %d:\n", 
-	 (ca[0])->type->description, (ca[0])->key_len, num_cipher);
-  fflush(stdout);
-  for (i=min_enc_len; i <= max_enc_len; i = i * 4)
-    printf("msg len: %d\tgigabits per second: %f\n", i,
-	   cipher_array_bits_per_second(ca, num_cipher, i, num_trials) / 1e9);
-
+    printf("timing %s throughput with key length %d, array size %d:\n",
+           (ca[0])->type->description, (ca[0])->key_len, num_cipher);
+    fflush(stdout);
+    for (i = min_enc_len; i <= max_enc_len; i = i * 4)
+        printf("msg len: %d\tgigabits per second: %f\n", i,
+               cipher_array_bits_per_second(ca, num_cipher, i, num_trials) /
+                   1e9);
 }
 
-err_status_t
-cipher_driver_test_array_throughput(cipher_type_t *ct, 
-				    int klen, int num_cipher) {
-  cipher_t **ca = NULL;
-  err_status_t status;
+srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
+                                                      int klen,
+                                                      int num_cipher)
+{
+    srtp_cipher_t **ca = NULL;
+    srtp_err_status_t status;
 
-  status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
-  if (status) {
-    printf("error: cipher_array_alloc_init() failed with error code %d\n",
-	   status);
-    return status;
-  }
-  
-  cipher_array_test_throughput(ca, num_cipher);
-  
-  cipher_array_delete(ca, num_cipher);    
- 
-  return err_status_ok;
+    status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
+    if (status) {
+        printf("error: cipher_array_alloc_init() failed with error code %d\n",
+               status);
+        return status;
+    }
+
+    cipher_array_test_throughput(ca, num_cipher);
+
+    cipher_array_delete(ca, num_cipher);
+
+    return srtp_err_status_ok;
 }
--- a/netwerk/srtp/src/crypto/test/datatypes_driver.c
+++ b/netwerk/srtp/src/crypto/test/datatypes_driver.c
@@ -3,157 +3,153 @@
  *
  * a test driver for crypto/math datatypes
  *
  * 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
  * 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 <string.h>           /* for strlen() */
-#include "datatypes.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-void
-byte_order(void);
+#include <stdio.h>  /* for printf() */
+#include <string.h> /* for strlen() */
+#include "datatypes.h"
+#include "util.h"
 
-void
-test_hex_string_funcs(void);
+void byte_order(void);
 
-void
-print_string(char *s);
+void test_hex_string_funcs(void);
 
-void
-test_bswap(void);
+void print_string(char *s);
+
+void test_bswap(void);
 
-int
-main (void) {
-  
-  /*
-   * this program includes various and sundry tests for fundamental
-   * datatypes.  it's a grab-bag of throwaway code, retained only in
-   * case of future problems
-   */
+int main(void)
+{
+    /*
+     * this program includes various and sundry tests for fundamental
+     * datatypes.  it's a grab-bag of throwaway code, retained only in
+     * case of future problems
+     */
 
-  int i, j;
-  v128_t x;
-  char *r = 
-    "The Moving Finger writes; and, having writ,\n"
-    "Moves on: nor all thy Piety nor Wit\n"
-    "Shall lure it back to cancel half a Line,\n"
-    "Nor all thy Tears wash out a Word of it.";
-  char *s = "incomplet"; 
- 
-  print_string(r);
-  print_string(s);
- 
-  byte_order();
-  test_hex_string_funcs();
+    int i, j;
+    v128_t x;
+    char *r = "The Moving Finger writes; and, having writ,\n"
+              "Moves on: nor all thy Piety nor Wit\n"
+              "Shall lure it back to cancel half a Line,\n"
+              "Nor all thy Tears wash out a Word of it.";
+    char *s = "incomplet";
+
+    print_string(r);
+    print_string(s);
 
-  for (j=0; j < 128; j++) {
+    byte_order();
+    test_hex_string_funcs();
+
+    for (j = 0; j < 128; j++) {
+        v128_set_to_zero(&x);
+        /*      x.v32[0] = (1 << j); */
+        v128_set_bit(&x, j);
+        printf("%s\n", v128_bit_string(&x));
+        v128_clear_bit(&x, j);
+        printf("%s\n", v128_bit_string(&x));
+    }
+
+    printf("----------------------------------------------\n");
     v128_set_to_zero(&x);
-    /*      x.v32[0] = (1 << j); */
-    v128_set_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    v128_clear_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    
-  }
-
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  for (i=0; i < 128; i++) {
-    v128_set_bit(&x, i);
-  }
-  printf("%s\n", v128_bit_string(&x)); 
+    for (i = 0; i < 128; i++) {
+        v128_set_bit(&x, i);
+    }
+    printf("%s\n", v128_bit_string(&x));
 
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  v128_set_bit(&x, 0);
-  for (i=0; i < 128; i++) {
-      printf("%s\n", v128_bit_string(&x)); 
-    v128_right_shift(&x, 1);
-  }
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  v128_set_bit(&x, 127);
-  for (i=0; i < 128; i++) {
-      printf("%s\n", v128_bit_string(&x)); 
-    v128_left_shift(&x, 1);
-  }
-  printf("----------------------------------------------\n");
-  for (i=0; i < 128; i++) {
+    printf("----------------------------------------------\n");
+    v128_set_to_zero(&x);
+    v128_set_bit(&x, 0);
+    for (i = 0; i < 128; i++) {
+        printf("%s\n", v128_bit_string(&x));
+        v128_right_shift(&x, 1);
+    }
+    printf("----------------------------------------------\n");
     v128_set_to_zero(&x);
     v128_set_bit(&x, 127);
-    v128_left_shift(&x, i);
-      printf("%s\n", v128_bit_string(&x)); 
-  }
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  for (i=0; i < 128; i+=2) {
-    v128_set_bit(&x, i);
-  }
-  printf("bit_string: { %s }\n", v128_bit_string(&x)); 
-  printf("get_bit:    { ");   
-  for (i=0; i < 128; i++) {
-    if (v128_get_bit(&x, i) == 1)
-      printf("1");
-    else
-      printf("0");
-  }
-  printf(" } \n");
+    for (i = 0; i < 128; i++) {
+        printf("%s\n", v128_bit_string(&x));
+        v128_left_shift(&x, 1);
+    }
+    printf("----------------------------------------------\n");
+    for (i = 0; i < 128; i++) {
+        v128_set_to_zero(&x);
+        v128_set_bit(&x, 127);
+        v128_left_shift(&x, i);
+        printf("%s\n", v128_bit_string(&x));
+    }
+    printf("----------------------------------------------\n");
+    v128_set_to_zero(&x);
+    for (i = 0; i < 128; i += 2) {
+        v128_set_bit(&x, i);
+    }
+    printf("bit_string: { %s }\n", v128_bit_string(&x));
+    printf("get_bit:    { ");
+    for (i = 0; i < 128; i++) {
+        if (v128_get_bit(&x, i) == 1)
+            printf("1");
+        else
+            printf("0");
+    }
+    printf(" } \n");
 
-  test_bswap();
+    test_bswap();
 
-  return 0;
+    return 0;
 }
 
-
 /* byte_order() prints out byte ordering of datatypes */
 
-void
-byte_order(void) {
-  int i;
-  v128_t e;
+void byte_order(void)
+{
+    int i;
+    v128_t e;
 #if 0
   v16_t b;
   v32_t c;
   v64_t d;
 
   for (i=0; i < sizeof(b); i++)
     b.octet[i] = i;
   for (i=0; i < sizeof(c); i++)
@@ -170,68 +166,65 @@ byte_order(void) {
   printf("v32_t:\t%s\n", v32_hex_string(c));
   b.value = 0x0102;
   printf("v16_t:\t%s\n", v16_hex_string(b));
 
   printf("uint16_t ordering:\n");
 
   c.value = 0x00010002;
   printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]);
-#endif 
+#endif
 
-  printf("byte ordering of crypto/math datatypes:\n");
-  for (i=0; i < sizeof(e); i++)
-    e.v8[i] = i;
-  printf("v128_t: %s\n", v128_hex_string(&e));
-  
+    printf("byte ordering of crypto/math datatypes:\n");
+    for (i = 0; i < sizeof(e); i++)
+        e.v8[i] = i;
+    printf("v128_t: %s\n", v128_hex_string(&e));
 }
 
-void
-test_hex_string_funcs(void) {
-  char hex1[] = "abadcafe";
-  char hex2[] = "0123456789abcdefqqqqq";
-  char raw[10];
-  int len;
+void test_hex_string_funcs(void)
+{
+    char hex1[] = "abadcafe";
+    char hex2[] = "0123456789abcdefqqqqq";
+    char raw[10];
+    int len;
 
-  len = hex_string_to_octet_string(raw, hex1, strlen(hex1));
-  printf("computed length: %d\tstring: %s\n", len,
-	 octet_string_hex_string(raw, len/2));
-  printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1);
+    len = hex_string_to_octet_string(raw, hex1, strlen(hex1));
+    printf("computed length: %d\tstring: %s\n", len,
+           octet_string_hex_string(raw, len / 2));
+    printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1);
 
-  len = hex_string_to_octet_string(raw, hex2, strlen(hex2));
-  printf("computed length: %d\tstring: %s\n", len,
-	 octet_string_hex_string(raw, len/2));
-  printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
-
+    len = hex_string_to_octet_string(raw, hex2, strlen(hex2));
+    printf("computed length: %d\tstring: %s\n", len,
+           octet_string_hex_string(raw, len / 2));
+    printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
 }
 
-void
-print_string(char *s) {
-  int i;  
-  printf("%s\n", s);
-  printf("strlen(s) = %u\n", (unsigned)strlen(s));
-  printf("{ ");
-  for (i=0; i < strlen(s); i++) {
-    printf("0x%x, ", s[i]);
-    if (((i+1) % 8) == 0)
-      printf("\n   ");
-  }
-  printf("}\n");
+void print_string(char *s)
+{
+    size_t i;
+    printf("%s\n", s);
+    printf("strlen(s) = %u\n", (unsigned)strlen(s));
+    printf("{ ");
+    for (i = 0; i < strlen(s); i++) {
+        printf("0x%x, ", s[i]);
+        if (((i + 1) % 8) == 0)
+            printf("\n   ");
+    }
+    printf("}\n");
 }
 
-void
-test_bswap(void) {
-  uint32_t x = 0x11223344;
-  uint64_t y = 0x1122334455667788LL;
+void test_bswap(void)
+{
+    uint32_t x = 0x11223344;
+    uint64_t y = 0x1122334455667788LL;
 
-  printf("before: %0x\nafter:  %0x\n", x, be32_to_cpu(x));
-  printf("before: %0llx\nafter:  %0llx\n", (unsigned long long)y,
-	 (unsigned long long)be64_to_cpu(y));
+    printf("before: %0x\nafter:  %0x\n", x, (unsigned int)be32_to_cpu(x));
+    printf("before: %0llx\nafter:  %0llx\n", (unsigned long long)y,
+           (unsigned long long)be64_to_cpu(y));
 
-  y = 1234;
+    y = 1234;
 
-  printf("1234: %0llx\n", (unsigned long long)y);
-  printf("as octet string: %s\n", 
-	 octet_string_hex_string((uint8_t *) &y, 8));
-  y = be64_to_cpu(y);
-  printf("bswapped octet string: %s\n", 
-	 octet_string_hex_string((uint8_t *) &y, 8));
+    printf("1234: %0llx\n", (unsigned long long)y);
+    printf("as octet string: %s\n", octet_string_hex_string((uint8_t *)&y, 8));
+    y = be64_to_cpu(y);
+    printf("bswapped octet string: %s\n",
+           octet_string_hex_string((uint8_t *)&y, 8));
 }
--- a/netwerk/srtp/src/crypto/test/env.c
+++ b/netwerk/srtp/src/crypto/test/env.c
@@ -2,98 +2,88 @@
  * env.c
  *
  * prints out a brief report on the build environment
  *
  * David 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
  * 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>
-#include <string.h>     /* for srtcmp() */
+#include <string.h> /* for srtcmp() */
 #include "config.h"
 
-int 
-main(void) {
-  int err_count = 0;
-  char *str;
+int main(void)
+{
+    int err_count = 0;
 
 #ifdef WORDS_BIGENDIAN
-  printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
+    printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
 #else
-  printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n");
+    printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n");
 #endif
 
 #ifdef CPU_RISC
-  printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n");
+    printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n");
 #elif defined(CPU_CISC)
-  printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n");
+    printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n");
 #else
-  printf("CPU set to an unknown type, probably due to a configuration error\n");
-  err_count++;
+    printf(
+        "CPU set to an unknown type, probably due to a configuration error\n");
+    err_count++;
 #endif
 
 #ifdef CPU_ALTIVEC
-  printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n");
+    printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n");
 #endif
 
 #ifndef NO_64BIT_MATH
-  printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n");
+    printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n");
 #else
-  printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n");
+    printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n");
 #endif
 
 #ifdef ERR_REPORTING_STDOUT
-  printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
+    printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
 #endif
 
-#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++;
-  }
-  
-  if (err_count)
-    printf("warning: configuration is probably in error "
-	   "(found %d problems)\n", err_count);
+    if (err_count)
+        printf("warning: configuration is probably in error "
+               "(found %d problems)\n",
+               err_count);
 
-  return err_count;
+    return err_count;
 }
--- a/netwerk/srtp/src/crypto/test/kernel_driver.c
+++ b/netwerk/srtp/src/crypto/test/kernel_driver.c
@@ -2,125 +2,126 @@
  * kernel_driver.c
  *
  * a test driver for the crypto_kernel
  *
  * 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
  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <stdio.h>           /* for printf() */
-#include <unistd.h>          /* for getopt() */
+#include <stdio.h> /* for printf() */
+#include "getopt_s.h"
 #include "crypto_kernel.h"
 
-void
-usage(char *prog_name) {
-  printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name);
-  exit(255);
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name);
+    exit(255);
 }
 
-int
-main (int argc, char *argv[]) {
-  extern char *optarg;
-  int q;
-  int do_validation      = 0;
-  err_status_t status;
+int main(int argc, char *argv[])
+{
+    int q;
+    int do_validation = 0;
+    srtp_err_status_t status;
 
-  if (argc == 1)
-    usage(argv[0]);
+    if (argc == 1)
+        usage(argv[0]);
 
-  /* initialize kernel - we need to do this before anything else */ 
-  status = crypto_kernel_init();
-  if (status) {
-    printf("error: crypto_kernel init failed\n");
-    exit(1);
-  }
-  printf("crypto_kernel successfully initalized\n");
+    /* initialize kernel - we need to do this before anything else */
+    status = srtp_crypto_kernel_init();
+    if (status) {
+        printf("error: srtp_crypto_kernel init failed\n");
+        exit(1);
+    }
+    printf("srtp_crypto_kernel successfully initalized\n");
 
-  /* process input arguments */
-  while (1) {
-    q = getopt(argc, argv, "vd:");
-    if (q == -1) 
-      break;
-    switch (q) {
-    case 'v':
-      do_validation = 1;
-      break;
-    case 'd':
-      status = crypto_kernel_set_debug_module(optarg, 1);
-      if (status) {
-	printf("error: set debug module (%s) failed\n", optarg);
-	exit(1);
-      }
-      break;
-    default:
-      usage(argv[0]);
-    }    
-  }
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "vd:");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 'v':
+            do_validation = 1;
+            break;
+        case 'd':
+            status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
+            if (status) {
+                printf("error: set debug module (%s) failed\n", optarg_s);
+                exit(1);
+            }
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
 
-  if (do_validation) {
-    printf("checking crypto_kernel status...\n");
-    status = crypto_kernel_status();
-    if (status) {
-      printf("failed\n");
-      exit(1);
+    if (do_validation) {
+        printf("checking srtp_crypto_kernel status...\n");
+        status = srtp_crypto_kernel_status();
+        if (status) {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("srtp_crypto_kernel passed self-tests\n");
     }
-    printf("crypto_kernel passed self-tests\n");
-  }
 
-  status = crypto_kernel_shutdown();
-  if (status) {
-    printf("error: crypto_kernel shutdown failed\n");
-    exit(1);
-  }
-  printf("crypto_kernel successfully shut down\n");
-  
-  return 0;
+    status = srtp_crypto_kernel_shutdown();
+    if (status) {
+        printf("error: srtp_crypto_kernel shutdown failed\n");
+        exit(1);
+    }
+    printf("srtp_crypto_kernel successfully shut down\n");
+
+    return 0;
 }
 
 /*
  * crypto_kernel_cipher_test() is a test of the cipher interface
  * of the crypto_kernel
  */
 
-err_status_t
-crypto_kernel_cipher_test(void) {
+srtp_err_status_t crypto_kernel_cipher_test(void)
+{
+    /* not implemented yet! */
 
-  /* not implemented yet! */
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
deleted file mode 100644
--- a/netwerk/srtp/src/crypto/test/rand_gen.c
+++ /dev/null
@@ -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;
-}
-
--- a/netwerk/srtp/src/crypto/test/sha1_driver.c
+++ b/netwerk/srtp/src/crypto/test/sha1_driver.c
@@ -3,548 +3,385 @@
  *
  * a test driver for SHA-1
  *
  * 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
  * 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>
+#include <string.h>
 #include "sha1.h"
+#include "util.h"
 
 #define SHA_PASS 0
 #define SHA_FAIL 1
 
 #define MAX_HASH_DATA_LEN 1024
-#define MAX_HASH_OUT_LEN   20
+#define MAX_HASH_OUT_LEN 20
 
 typedef struct hash_test_case_t {
-  unsigned data_len;                 /* number of octets in data        */
-  unsigned hash_len;                 /* number of octets output by hash */
-  uint8_t data[MAX_HASH_DATA_LEN];   /* message data                    */            
-  uint8_t hash[MAX_HASH_OUT_LEN];    /* expected hash output            */  
-  struct hash_test_case_t *next_test_case;
+    unsigned data_len;               /* number of octets in data        */
+    unsigned hash_len;               /* number of octets output by hash */
+    uint8_t data[MAX_HASH_DATA_LEN]; /* message data                    */
+    uint8_t hash[MAX_HASH_OUT_LEN];  /* expected hash output            */
+    struct hash_test_case_t *next_test_case;
 } hash_test_case_t;
 
 hash_test_case_t *sha1_test_case_list;
 
-err_status_t
-hash_test_case_add(hash_test_case_t **list_ptr, 
-		   char *hex_data, 
-		   unsigned data_len, 
-		   char *hex_hash, 
-		   unsigned hash_len) {
-  hash_test_case_t *list_head = *list_ptr;
-  hash_test_case_t *test_case;
-  unsigned tmp_len;
+srtp_err_status_t hash_test_case_add(hash_test_case_t **list_ptr,
+                                     char *hex_data,
+                                     unsigned data_len,
+                                     char *hex_hash,
+                                     unsigned hash_len)
+{
+    hash_test_case_t *list_head = *list_ptr;
+    hash_test_case_t *test_case;
+    unsigned tmp_len;
+
+    test_case = malloc(sizeof(hash_test_case_t));
+    if (test_case == NULL)
+        return srtp_err_status_alloc_fail;
 
-  test_case = malloc(sizeof(hash_test_case_t));
-  if (test_case == NULL)
-    return 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;
+    tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data,
+                                         data_len * 2);
+    if (tmp_len != data_len * 2) {
+        free(test_case);
+        return srtp_err_status_parse_err;
+    }
 
-  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;
+    tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash,
+                                         hash_len * 2);
+    if (tmp_len != hash_len * 2) {
+        free(test_case);
+        return srtp_err_status_parse_err;
+    }
 
-  test_case->data_len = data_len;
-  test_case->hash_len = hash_len;
+    test_case->data_len = data_len;
+    test_case->hash_len = hash_len;
 
-  /* add the new test case to the head of the list */
-  test_case->next_test_case = list_head;
-  *list_ptr = test_case;
+    /* add the new test case to the head of the list */
+    test_case->next_test_case = list_head;
+    *list_ptr = test_case;
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-sha1_test_case_validate(const hash_test_case_t *test_case) {
-  sha1_ctx_t ctx;
-  uint32_t hash_value[5];
+srtp_err_status_t sha1_test_case_validate(const hash_test_case_t *test_case)
+{
+    srtp_sha1_ctx_t ctx;
+    uint32_t hash_value[5];
 
-  if (test_case == NULL)
-    return err_status_bad_param;
+    if (test_case == NULL)
+        return srtp_err_status_bad_param;
 
-  if (test_case->hash_len != 20)
-    return err_status_bad_param;
-  if (test_case->data_len > MAX_HASH_DATA_LEN)
-    return err_status_bad_param;
+    if (test_case->hash_len != 20)
+        return srtp_err_status_bad_param;
+    if (test_case->data_len > MAX_HASH_DATA_LEN)
+        return srtp_err_status_bad_param;
 
-  sha1_init(&ctx);
-  sha1_update(&ctx, test_case->data, test_case->data_len);
-  sha1_final(&ctx, hash_value);
-  if (0 == memcmp(test_case->hash, hash_value, 20)) {
+    srtp_sha1_init(&ctx);
+    srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
+    srtp_sha1_final(&ctx, hash_value);
+    if (0 == memcmp(test_case->hash, hash_value, 20)) {
 #if VERBOSE
-    printf("PASSED: reference value: %s\n", 
-	   octet_string_hex_string((const uint8_t *)test_case->hash, 20));
-    printf("PASSED: computed value:  %s\n", 
-	   octet_string_hex_string((const uint8_t *)hash_value, 20));   
-#endif 
-    return err_status_ok;
-  }
+        printf("PASSED: reference value: %s\n",
+               octet_string_hex_string((const uint8_t *)test_case->hash, 20));
+        printf("PASSED: computed value:  %s\n",
+               octet_string_hex_string((const uint8_t *)hash_value, 20));
+#endif
+        return srtp_err_status_ok;
+    }
 
-  printf("reference value: %s\n", 
-	 octet_string_hex_string((const uint8_t *)test_case->hash, 20));
-  printf("computed value:  %s\n", 
-	 octet_string_hex_string((const uint8_t *)hash_value, 20));
+    printf("reference value: %s\n",
+           octet_string_hex_string((const uint8_t *)test_case->hash, 20));
+    printf("computed value:  %s\n",
+           octet_string_hex_string((const uint8_t *)hash_value, 20));
 
-  return err_status_algo_fail;
-  
+    return srtp_err_status_algo_fail;
 }
 
 struct hex_sha1_test_case_t {
-  unsigned bit_len;
-  char hex_data[MAX_HASH_DATA_LEN*2];
-  char hex_hash[40];
+    unsigned bit_len;
+    char hex_data[MAX_HASH_DATA_LEN * 2];
+    char hex_hash[40];
 };
 
-err_status_t
-sha1_add_test_cases(void) {
-  int i;
-  err_status_t err;
+srtp_err_status_t sha1_add_test_cases(void)
+{
+    int i;
+    srtp_err_status_t err;
 
-  /*
-   * these test cases are taken from the "SHA-1 Sample Vectors"
-   * provided by NIST at http://csrc.nist.gov/cryptval/shs.html
-   */
+    /*
+     * these test cases are taken from the "SHA-1 Sample Vectors"
+     * provided by NIST at http://csrc.nist.gov/cryptval/shs.html
+     */
 
-  struct hex_sha1_test_case_t tc[] = {
-    { 
-      0,
-      "",
-      "da39a3ee5e6b4b0d3255bfef95601890afd80709"
-    },
-    {
-      8,
-      "a8",
-      "99f2aa95e36f95c2acb0eaf23998f030638f3f15"
-    }, 
-    {
-      16, 
-      "3000",
-      "f944dcd635f9801f7ac90a407fbc479964dec024"
-    }, 
-    {
-      24, 
-      "42749e", 
-      "a444319e9b6cc1e8464c511ec0969c37d6bb2619"
-    }, 
-    {
-      32, 
-      "9fc3fe08", 
-      "16a0ff84fcc156fd5d3ca3a744f20a232d172253"
-    }, 
-    {
-      40, 
-      "b5c1c6f1af",
-      "fec9deebfcdedaf66dda525e1be43597a73a1f93"
-    },
-    {
-      48, 
-      "e47571e5022e",
-      "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5"
-    }, 
-    {
-      56, 
-      "3e1b28839fb758",
-      "67da53837d89e03bf652ef09c369a3415937cfd3"
-    },
-    {
-      64, 
-      "a81350cbb224cb90",
-      "305e4ff9888ad855a78573cddf4c5640cce7e946"
-    }, 
-    {
-      72, "c243d167923dec3ce1",
-      "5902b77b3265f023f9bbc396ba1a93fa3509bde7"
-    },
-    {
-      80, 
-      "50ac18c59d6a37a29bf4",
-      "fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab"
-    }, 
-    {
-      88, 
-      "98e2b611ad3b1cccf634f6",
-      "1d20fbe00533c10e3cbd6b27088a5de0c632c4b5"
-    },
-    {
-      96, 
-      "73fe9afb68e1e8712e5d4eec",
-      "7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93"
-    }, 
-    {
-      104, 
-      "9e701ed7d412a9226a2a130e66",
-      "706f0677146307b20bb0e8d6311e329966884d13"
-    }, 
-    {
-      112, 
-      "6d3ee90413b0a7cbf69e5e6144ca",
-      "a7241a703aaf0d53fe142f86bf2e849251fa8dff"
-    }, 
-    {
-      120, 
-      "fae24d56514efcb530fd4802f5e71f",
-      "400f53546916d33ad01a5e6df66822dfbdc4e9e6"
-    }, 
-    {
-      128, 
-      "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
-      "fac8ab93c1ae6c16f0311872b984f729dc928ccd"
-    }, 
-    {
-      136, 
-      "d98cded2adabf08fda356445c781802d95",
-      "fba6d750c18da58f6e2aab10112b9a5ef3301b3b"
-    }, 
-    {
-      144, 
-      "bcc6d7087a84f00103ccb32e5f5487a751a2",
-      "29d27c2d44c205c8107f0351b05753ac708226b6"
-    }, 
-    {
-      152, 
-      "36ecacb1055434190dbbc556c48bafcb0feb0d",
-      "b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845"
-    }, 
-    {
-      160, 
-      "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
-      "96d08c430094b9fcc164ad2fb6f72d0a24268f68"
-    },
-    {
-      168, "c95b441d8270822a46a798fae5defcf7b26abace36",
-      "a287ea752a593d5209e287881a09c49fa3f0beb1"
-    }, 
-    {
-      176, 
-      "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
-      "a06c713779cbd88519ed4a585ac0cb8a5e9d612b"
-    }, 
-    {
-      184,
-      "755175528d55c39c56493d697b790f099a5ce741f7754b",
-      "bff7d52c13a3688132a1d407b1ab40f5b5ace298"
-    }, 
-    {
-      192,
-      "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
-      "c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9"
-    }, 
-    {
-      200,
-      "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
-      "ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1"
-    }, 
-    {
-      208, 
-      "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
-      "29e66ed23e914351e872aa761df6e4f1a07f4b81"
-    }, 
-    {
-      216, 
-      "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
-      "b28cf5e5b806a01491d41f69bd9248765c5dc292"
-    }, 
-    {
-      224,
-      "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
-      "60224fb72c46069652cd78bcd08029ef64da62f3"
-    }, 
-    {
-      232,
-      "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
-      "b72c4a86f72608f24c05f3b9088ef92fba431df7"
-    }, 
-    {
-      240,
-      "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
-      "73779ad5d6b71b9b8328ef7220ff12eb167076ac"
-    },
-    {
-      248,
-      "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
-      "a09671d4452d7cf50015c914a1e31973d20cc1a0"
-    }, 
-    {
-      256, 
-      "041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
-      "e88cdcd233d99184a6fd260b8fca1b7f7687aee0"
-    }, 
-    {
-      264,
-      "17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
-      "010def22850deb1168d525e8c84c28116cb8a269"
-    },
-    {
-      272, 
-      "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77",
-      "aeaa40ba1717ed5439b1e6ea901b294ba500f9ad"
-    }, 
-    {
-      280, 
-      "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f",
-      "c6433791238795e34f080a5f1f1723f065463ca0"
-    }, 
-    {
-      288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d",
-      "e21e22b89c1bb944a32932e6b2a2f20d491982c3"
-    }, 
-    {
-      296, 
-      "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22",
-      "575323a9661f5d28387964d2ba6ab92c17d05a8a"
-    },
-    {
-      304,
-      "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910",
-      "feb44494af72f245bfe68e86c4d7986d57c11db7"
-    },
-    {
-      312,
-      "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5",
-      "cff2290b3648ba2831b98dde436a72f9ebf51eee"
-    }, 
-    {
-      320,
-      "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e",
-      "9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c"
-    }, 
-    {
-      328,
-      "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f",
-      "afedb0ff156205bcd831cbdbda43db8b0588c113"
-    }, 
-    {
-      336,
-      "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33",
-      "8deb1e858f88293a5e5e4d521a34b2a4efa70fc4"
-    }, 
-    {
-      344,
-      "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab",
-      "95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf"
-    }, 
-    {
-      352, 
-      "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc",
-      "f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2"
-    }, 
-    {
-      360,
-      "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54",
-      "7b13bb0dbf14964bd63b133ac85e22100542ef55"
-    }, 
-    {
-      368,
-      "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258",
-      "c314d2b6cf439be678d2a74e890d96cfac1c02ed"
-    }, 
-    {
-      376, 
-      "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6",
-      "4d0be361e410b47a9d67d8ce0bb6a8e01c53c078"
-    }, 
-    {
-      384,
-      "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02",
-      "e5353431ffae097f675cbf498869f6fbb6e1c9f2"
-    },
-    {
-      392, 
-      "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9",
-      "b8720a7068a085c018ab18961de2765aa6cd9ac4"
-    }, 
-    {
-      400,
-      "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475",
-      "b0732181568543ba85f2b6da602b4b065d9931aa"
-    }, 
-    {
-      408,
-      "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944",
-      "9c22674cf3222c3ba921672694aafee4ce67b96b"
-    }, 
-    {
-      416, 
-      "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709",
-      "d128335f4cecca9066cdae08958ce656ff0b4cfc"
-    }, 
-    {
-      424, 
-      "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f",
-      "0b67c57ac578de88a2ae055caeaec8bb9b0085a0"
-    },
-    {
-      432,
-      "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
-      "c766f912a89d4ccda88e0cce6a713ef5f178b596"
-    }, 
-    {
-      440,
-      "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
-      "9aa3925a9dcb177b15ccff9b78e70cf344858779"
-    }, 
-    {
-      448,
-      "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
-      "4811fa30042fc076acf37c8e2274d025307e5943"
-    }, 
-    {
-      456,
-      "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
-      "6743018450c9730761ee2b130df9b91c1e118150"
-    }, 
-    {
-      464,
-      "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
-      "71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645"
-    }, 
-    {
-      472, 
-      "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
-      "a7d9dc68dacefb7d6116186048cb355cc548e11d"
-    }, 
-    {
-      480,
-      "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
-      "142e429f0522ba5abf5131fa81df82d355b96909"
-    }, 
-    {
-      488,
-      "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
-      "ef72db70dcbcab991e9637976c6faf00d22caae9"
-    }, 
-    {
-      496,
-      "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
-      "f220a7457f4588d639dc21407c942e9843f8e26b"
-    }, 
-    {
-      504, 
-      "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645", 
-      "ddd2117b6e309c233ede85f962a0c2fc215e5c69"
-    }, 
-    {
-      512, 
-      "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116", 
-      "a3054427cdb13f164a610b348702724c808a0dcc"
+    struct hex_sha1_test_case_t tc[] = {
+        { 0, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709" },
+        { 8, "a8", "99f2aa95e36f95c2acb0eaf23998f030638f3f15" },
+        { 16, "3000", "f944dcd635f9801f7ac90a407fbc479964dec024" },
+        { 24, "42749e", "a444319e9b6cc1e8464c511ec0969c37d6bb2619" },
+        { 32, "9fc3fe08", "16a0ff84fcc156fd5d3ca3a744f20a232d172253" },
+        { 40, "b5c1c6f1af", "fec9deebfcdedaf66dda525e1be43597a73a1f93" },
+        { 48, "e47571e5022e", "8ce051181f0ed5e9d0c498f6bc4caf448d20deb5" },
+        { 56, "3e1b28839fb758", "67da53837d89e03bf652ef09c369a3415937cfd3" },
+        { 64, "a81350cbb224cb90", "305e4ff9888ad855a78573cddf4c5640cce7e946" },
+        { 72, "c243d167923dec3ce1",
+          "5902b77b3265f023f9bbc396ba1a93fa3509bde7" },
+        { 80, "50ac18c59d6a37a29bf4",
+          "fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab" },
+        { 88, "98e2b611ad3b1cccf634f6",
+          "1d20fbe00533c10e3cbd6b27088a5de0c632c4b5" },
+        { 96, "73fe9afb68e1e8712e5d4eec",
+          "7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93" },
+        { 104, "9e701ed7d412a9226a2a130e66",
+          "706f0677146307b20bb0e8d6311e329966884d13" },
+        { 112, "6d3ee90413b0a7cbf69e5e6144ca",
+          "a7241a703aaf0d53fe142f86bf2e849251fa8dff" },
+        { 120, "fae24d56514efcb530fd4802f5e71f",
+          "400f53546916d33ad01a5e6df66822dfbdc4e9e6" },
+        { 128, "c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
+          "fac8ab93c1ae6c16f0311872b984f729dc928ccd" },
+        { 136, "d98cded2adabf08fda356445c781802d95",
+          "fba6d750c18da58f6e2aab10112b9a5ef3301b3b" },
+        { 144, "bcc6d7087a84f00103ccb32e5f5487a751a2",
+          "29d27c2d44c205c8107f0351b05753ac708226b6" },
+        { 152, "36ecacb1055434190dbbc556c48bafcb0feb0d",
+          "b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845" },
+        { 160, "5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
+          "96d08c430094b9fcc164ad2fb6f72d0a24268f68" },
+        { 168, "c95b441d8270822a46a798fae5defcf7b26abace36",
+          "a287ea752a593d5209e287881a09c49fa3f0beb1" },
+        { 176, "83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
+          "a06c713779cbd88519ed4a585ac0cb8a5e9d612b" },
+        { 184, "755175528d55c39c56493d697b790f099a5ce741f7754b",
+          "bff7d52c13a3688132a1d407b1ab40f5b5ace298" },
+        { 192, "088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
+          "c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9" },
+        { 200, "a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
+          "ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1" },
+        { 208, "8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
+          "29e66ed23e914351e872aa761df6e4f1a07f4b81" },
+        { 216, "a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
+          "b28cf5e5b806a01491d41f69bd9248765c5dc292" },
+        { 224, "589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
+          "60224fb72c46069652cd78bcd08029ef64da62f3" },
+        { 232, "a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
+          "b72c4a86f72608f24c05f3b9088ef92fba431df7" },
+        { 240, "82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
+          "73779ad5d6b71b9b8328ef7220ff12eb167076ac" },
+        { 248, "9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
+          "a09671d4452d7cf50015c914a1e31973d20cc1a0" },
+        { 256,
+          "041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
+          "e88cdcd233d99184a6fd260b8fca1b7f7687aee0" },
+        { 264,
+          "17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
+          "010def22850deb1168d525e8c84c28116cb8a269" },
+        { 272, "d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc9862"
+               "0cf77",
+          "aeaa40ba1717ed5439b1e6ea901b294ba500f9ad" },
+        { 280, "09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838"
+               "443328f",
+          "c6433791238795e34f080a5f1f1723f065463ca0" },
+        { 288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b2659"
+               "4a25c709d",
+          "e21e22b89c1bb944a32932e6b2a2f20d491982c3" },
+        { 296, "b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d"
+               "79f4f195b22",
+          "575323a9661f5d28387964d2ba6ab92c17d05a8a" },
+        { 304, "5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d2"
+               "34cc1c5002910",
+          "feb44494af72f245bfe68e86c4d7986d57c11db7" },
+        { 312, "498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8"
+               "ba8a621fd6e3be5",
+          "cff2290b3648ba2831b98dde436a72f9ebf51eee" },
+        { 320, "3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15c"
+               "b5c83afb4b570376e",
+          "9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c" },
+        { 328, "dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99ca"
+               "c34dfca38910db2678f",
+          "afedb0ff156205bcd831cbdbda43db8b0588c113" },
+        { 336, "5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c"
+               "2fcf9716d3fad261dff33",
+          "8deb1e858f88293a5e5e4d521a34b2a4efa70fc4" },
+        { 344, "df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f"
+               "20fd697c3e4c8b8c5f590ab",
+          "95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf" },
+        { 352, "1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b"
+               "48c68d7f7057e5675cd96fcfc",
+          "f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2" },
+        { 360, "ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e179"
+               "0e888e09fbe3a70412176cb3b54",
+          "7b13bb0dbf14964bd63b133ac85e22100542ef55" },
+        { 368, "d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b08"
+               "4d3741afb8d24aaa8ab9c104f7258",
+          "c314d2b6cf439be678d2a74e890d96cfac1c02ed" },
+        { 376, "32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a"
+               "6c0d615c2ac8ad04b213cc589541cf6",
+          "4d0be361e410b47a9d67d8ce0bb6a8e01c53c078" },
+        { 384, "e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d"
+               "29688a65e2e3f3da47a45ac14343c9c02",
+          "e5353431ffae097f675cbf498869f6fbb6e1c9f2" },
+        { 392, "e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97a"
+               "b506ee05aebebc1eed09fc0e357109818b9",
+          "b8720a7068a085c018ab18961de2765aa6cd9ac4" },
+        { 400, "bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a"
+               "0d96e9e33326ccb7747cfff0852b961bfd475",
+          "b0732181568543ba85f2b6da602b4b065d9931aa" },
+        { 408, "235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7da"
+               "d814bce8dabb611790a6abe56030b798b75c944",
+          "9c22674cf3222c3ba921672694aafee4ce67b96b" },
+        { 416, "07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9"
+               "ee07cb169ec5186292e44c27e5696a967f5e67709",
+          "d128335f4cecca9066cdae08958ce656ff0b4cfc" },
+        { 424, "65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241"
+               "822bf67e6335a6d8b5ed06abf8841884c636a25733f",
+          "0b67c57ac578de88a2ae055caeaec8bb9b0085a0" },
+        { 432, "dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b759"
+               "41d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
+          "c766f912a89d4ccda88e0cce6a713ef5f178b596" },
+        { 440, "4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373"
+               "dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
+          "9aa3925a9dcb177b15ccff9b78e70cf344858779" },
+        { 448, "ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8a"
+               "a7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
+          "4811fa30042fc076acf37c8e2274d025307e5943" },
+        { 456, "8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be"
+               "22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
+          "6743018450c9730761ee2b130df9b91c1e118150" },
+        { 464, "497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623"
+               "d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
+          "71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645" },
+        { 472, "72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e7"
+               "3e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
+          "a7d9dc68dacefb7d6116186048cb355cc548e11d" },
+        { 480, "7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb"
+               "66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
+          "142e429f0522ba5abf5131fa81df82d355b96909" },
+        { 488, "74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd69"
+               "13c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
+          "ef72db70dcbcab991e9637976c6faf00d22caae9" },
+        { 496, "46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc409"
+               "75c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
+          "f220a7457f4588d639dc21407c942e9843f8e26b" },
+        { 504, "836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc03"
+               "48e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c864"
+               "5",
+          "ddd2117b6e309c233ede85f962a0c2fc215e5c69" },
+        { 512, "7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2"
+               "438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c61"
+               "16",
+          "a3054427cdb13f164a610b348702724c808a0dcc" }
+    };
+
+    for (i = 0; i < 65; i++) {
+        err = hash_test_case_add(&sha1_test_case_list, tc[i].hex_data,
+                                 tc[i].bit_len / 8, tc[i].hex_hash, 20);
+        if (err) {
+            printf("error adding hash test case (code %d)\n", err);
+            return err;
+        }
     }
-  };
-  
 
-  for (i=0; i < 65; i++) {
-    err = hash_test_case_add(&sha1_test_case_list, 
-			     tc[i].hex_data, 
-			     tc[i].bit_len/8, 
-			     tc[i].hex_hash, 20);
-    if (err) {
-      printf("error adding hash test case (code %d)\n", err);
-      return err;
-    }
-  }
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-sha1_dealloc_test_cases(void) {
-  hash_test_case_t *t, *next;
+srtp_err_status_t sha1_dealloc_test_cases(void)
+{
+    hash_test_case_t *t, *next;
 
-  for (t = sha1_test_case_list; t != NULL; t = next) {
-    next = t->next_test_case;
-    free(t);
-  }
+    for (t = sha1_test_case_list; t != NULL; t = next) {
+        next = t->next_test_case;
+        free(t);
+    }
 
-  sha1_test_case_list = NULL;
+    sha1_test_case_list = NULL;
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
+srtp_err_status_t sha1_validate(void)
+{
+    hash_test_case_t *test_case;
+    srtp_err_status_t err;
 
-err_status_t
-sha1_validate(void) {
-  hash_test_case_t *test_case;
-  err_status_t err;
+    err = sha1_add_test_cases();
+    if (err) {
+        printf("error adding SHA1 test cases (error code %d)\n", err);
+        return err;
+    }
 
-  err = sha1_add_test_cases();
-  if (err) {
-    printf("error adding SHA1 test cases (error code %d)\n", err);
-    return err;
-  }  
+    if (sha1_test_case_list == NULL)
+        return srtp_err_status_cant_check;
 
-  if (sha1_test_case_list == NULL)
-    return err_status_cant_check;
-  
-  test_case = sha1_test_case_list;
-  while (test_case != NULL) {
-    err = sha1_test_case_validate(test_case);
-    if (err) {
-      printf("error validating hash test case (error code %d)\n", err);
-      return err;
+    test_case = sha1_test_case_list;
+    while (test_case != NULL) {
+        err = sha1_test_case_validate(test_case);
+        if (err) {
+            printf("error validating hash test case (error code %d)\n", err);
+            return err;
+        }
+        test_case = test_case->next_test_case;
     }
-    test_case = test_case->next_test_case;
-  }
 
-  sha1_dealloc_test_cases();
+    sha1_dealloc_test_cases();
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-
+int main(void)
+{
+    srtp_err_status_t err;
 
-int
-main (void) {
-  err_status_t err;
-
-  printf("sha1 test driver\n");
+    printf("sha1 test driver\n");
 
-  err = sha1_validate();
-  if (err) {
-    printf("SHA1 did not pass validation testing\n");
-    return 1;
-  }
-  printf("SHA1 passed validation tests\n");
+    err = sha1_validate();
+    if (err) {
+        printf("SHA1 did not pass validation testing\n");
+        return 1;
+    }
+    printf("SHA1 passed validation tests\n");
 
-  return 0;
-
+    return 0;
 }
--- a/netwerk/srtp/src/crypto/test/stat_driver.c
+++ b/netwerk/srtp/src/crypto/test/stat_driver.c
@@ -3,172 +3,256 @@
  *
  * test driver for the stat_test functions
  *
  * 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
  * 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() */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h> /* for printf() */
 
 #include "err.h"
 #include "stat.h"
+#include "srtp.h"
 
 #include "cipher.h"
 
 typedef struct {
-  void *state;
+    void *state;
 } random_source_t;
 
-err_status_t
-random_source_alloc(void);
+srtp_err_status_t random_source_alloc(void);
 
-void
-err_check(err_status_t s) {
-  if (s) {
-    printf("error (code %d)\n", s);
-    exit(1);
-  }
+void err_check(srtp_err_status_t s)
+{
+    if (s) {
+        printf("error (code %d)\n", s);
+        exit(1);
+    }
 }
 
-int
-main (int argc, char *argv[]) {
-  uint8_t buffer[2500];
-  unsigned int buf_len = 2500;
-  int i, j;
-  extern cipher_type_t aes_icm;
-  cipher_t *c;
-  uint8_t key[46] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05
+int main(int argc, char *argv[])
+{
+    uint8_t buffer[2532];
+    unsigned int buf_len = 2500;
+    int i, j;
+    extern srtp_cipher_type_t srtp_aes_icm_128;
+    extern srtp_cipher_type_t srtp_aes_icm_256;
+#ifdef OPENSSL
+    extern srtp_cipher_type_t srtp_aes_gcm_128_openssl;
+    extern srtp_cipher_type_t srtp_aes_gcm_256_openssl;
+#endif
+    srtp_cipher_t *c;
+    /* clang-format off */
+    uint8_t key[46] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05
     };
-  v128_t nonce;
-  int num_trials = 500;
-  int num_fail;
+    /* clang-format on */
+    v128_t nonce;
+    int num_trials = 500;
+    int num_fail;
+
+    printf("statistical tests driver\n");
 
-  printf("statistical tests driver\n");
+    v128_set_to_zero(&nonce);
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
 
-  for (i=0; i < 2500; i++)
-    buffer[i] = 0;
+    /* run tests */
+    printf("running stat_tests on all-null buffer, expecting failure\n");
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
 
-  /* run tests */
-  printf("running stat_tests on all-null buffer, expecting failure\n");
-  printf("monobit %d\n", stat_test_monobit(buffer));
-  printf("poker   %d\n", stat_test_poker(buffer));
-  printf("runs    %d\n", stat_test_runs(buffer));
+    for (i = 0; i < 2500; i++)
+        buffer[i] = rand();
+    printf("running stat_tests on rand(), expecting success\n");
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
 
-  for (i=0; i < 2500; i++)
-    buffer[i] = rand();
-  printf("running stat_tests on rand(), expecting success\n");
-  printf("monobit %d\n", stat_test_monobit(buffer));
-  printf("poker   %d\n", stat_test_poker(buffer));
-  printf("runs    %d\n", stat_test_runs(buffer));
+    printf("running stat_tests on AES-128-ICM, expecting success\n");
+    /* set buffer to cipher output */
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
+    err_check(srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
+                                     SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
+    err_check(srtp_cipher_init(c, key));
+    err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+    err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+    /* run tests on cipher outout */
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
 
-  printf("running stat_tests on AES-128-ICM, expecting success\n");
-  /* set buffer to cipher output */
-  for (i=0; i < 2500; i++)
-    buffer[i] = 0;
-  err_check(cipher_type_alloc(&aes_icm, &c, 30));
-  err_check(cipher_init(c, key, direction_encrypt));
-  err_check(cipher_set_iv(c, &nonce));
-  err_check(cipher_encrypt(c, buffer, &buf_len));
-  /* run tests on cipher outout */
-  printf("monobit %d\n", stat_test_monobit(buffer));
-  printf("poker   %d\n", stat_test_poker(buffer));
-  printf("runs    %d\n", stat_test_runs(buffer));
+    printf("runs test (please be patient): ");
+    fflush(stdout);
+    num_fail = 0;
+    v128_set_to_zero(&nonce);
+    for (j = 0; j < num_trials; j++) {
+        for (i = 0; i < 2500; i++)
+            buffer[i] = 0;
+        nonce.v32[3] = i;
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        if (stat_test_runs(buffer)) {
+            num_fail++;
+        }
+    }
+
+    printf("%d failures in %d tests\n", num_fail, num_trials);
+    printf("(nota bene: a small fraction of stat_test failures does not \n"
+           "indicate that the random source is invalid)\n");
+
+    err_check(srtp_cipher_dealloc(c));
 
-  printf("runs test (please be patient): ");
-  fflush(stdout);
-  num_fail = 0;
-  v128_set_to_zero(&nonce);
-  for(j=0; j < num_trials; j++) {
-    for (i=0; i < 2500; i++)
-      buffer[i] = 0;
-    nonce.v32[3] = i;
-    err_check(cipher_set_iv(c, &nonce));
-    err_check(cipher_encrypt(c, buffer, &buf_len));
-    if (stat_test_runs(buffer)) {
-      num_fail++;
+    printf("running stat_tests on AES-256-ICM, expecting success\n");
+    /* set buffer to cipher output */
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
+    err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
+                                     SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
+    err_check(srtp_cipher_init(c, key));
+    err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+    err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+    /* run tests on cipher outout */
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
+
+    printf("runs test (please be patient): ");
+    fflush(stdout);
+    num_fail = 0;
+    v128_set_to_zero(&nonce);
+    for (j = 0; j < num_trials; j++) {
+        for (i = 0; i < 2500; i++)
+            buffer[i] = 0;
+        nonce.v32[3] = i;
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        if (stat_test_runs(buffer)) {
+            num_fail++;
+        }
     }
-  }
-
-  printf("%d failures in %d tests\n", num_fail, num_trials);
-  printf("(nota bene: a small fraction of stat_test failures does not \n"
-	 "indicate that the random source is invalid)\n");
-
-  err_check(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));
-  err_check(cipher_init(c, key, direction_encrypt));
-  err_check(cipher_set_iv(c, &nonce));
-  err_check(cipher_encrypt(c, buffer, &buf_len));
-  /* run tests on cipher outout */
-  printf("monobit %d\n", stat_test_monobit(buffer));
-  printf("poker   %d\n", stat_test_poker(buffer));
-  printf("runs    %d\n", stat_test_runs(buffer));
+#ifdef OPENSSL
+    {
+        printf("running stat_tests on AES-128-GCM, expecting success\n");
+        /* set buffer to cipher output */
+        for (i = 0; i < 2500; i++) {
+            buffer[i] = 0;
+        }
+        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128_openssl, &c,
+                                         SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
+        err_check(srtp_cipher_init(c, key));
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        /* run tests on cipher outout */
+        printf("monobit %d\n", stat_test_monobit(buffer));
+        printf("poker   %d\n", stat_test_poker(buffer));
+        printf("runs    %d\n", stat_test_runs(buffer));
+        fflush(stdout);
+        num_fail = 0;
+        v128_set_to_zero(&nonce);
+        for (j = 0; j < num_trials; j++) {
+            for (i = 0; i < 2500; i++) {
+                buffer[i] = 0;
+            }
+            nonce.v32[3] = i;
+            err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
+                                         srtp_direction_encrypt));
+            err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+            buf_len = 2500;
+            if (stat_test_runs(buffer)) {
+                num_fail++;
+            }
+        }
 
-  printf("runs test (please be patient): ");
-  fflush(stdout);
-  num_fail = 0;
-  v128_set_to_zero(&nonce);
-  for(j=0; j < num_trials; j++) {
-    for (i=0; i < 2500; i++)
-      buffer[i] = 0;
-    nonce.v32[3] = i;
-    err_check(cipher_set_iv(c, &nonce));
-    err_check(cipher_encrypt(c, buffer, &buf_len));
-    if (stat_test_runs(buffer)) {
-      num_fail++;
+        printf("running stat_tests on AES-256-GCM, expecting success\n");
+        /* set buffer to cipher output */
+        for (i = 0; i < 2500; i++) {
+            buffer[i] = 0;
+        }
+        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256_openssl, &c,
+                                         SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
+        err_check(srtp_cipher_init(c, key));
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        /* run tests on cipher outout */
+        printf("monobit %d\n", stat_test_monobit(buffer));
+        printf("poker   %d\n", stat_test_poker(buffer));
+        printf("runs    %d\n", stat_test_runs(buffer));
+        fflush(stdout);
+        num_fail = 0;
+        v128_set_to_zero(&nonce);
+        for (j = 0; j < num_trials; j++) {
+            for (i = 0; i < 2500; i++) {
+                buffer[i] = 0;
+            }
+            nonce.v32[3] = i;
+            err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
+                                         srtp_direction_encrypt));
+            err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+            buf_len = 2500;
+            if (stat_test_runs(buffer)) {
+                num_fail++;
+            }
+        }
     }
-  }
+#endif
 
-  printf("%d failures in %d tests\n", num_fail, num_trials);
-  printf("(nota bene: a small fraction of stat_test failures does not \n"
-	 "indicate that the random source is invalid)\n");
+    printf("%d failures in %d tests\n", num_fail, num_trials);
+    printf("(nota bene: a small fraction of stat_test failures does not \n"
+           "indicate that the random source is invalid)\n");
 
-  err_check(cipher_dealloc(c));
+    err_check(srtp_cipher_dealloc(c));
 
-  return 0;
+    return 0;
 }
--- a/netwerk/srtp/src/include/ekt.h
+++ b/netwerk/srtp/src/include/ekt.h
@@ -2,200 +2,180 @@
  * ekt.h
  *
  * interface to Encrypted Key Transport for SRTP
  *
  * David McGrew
  * Cisco Systems, Inc.
  */
 /*
- *	
- * 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
  * 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.
  *
  */
 
-
-
 /*
- * EKT implementation strategy 
- * 
+ * EKT implementation strategy
+ *
  * use stream_template approach
  *
  * in srtp_unprotect, when a new stream appears, check if template has
- * EKT defined, and if it does, then apply EKT processing 
+ * EKT defined, and if it does, then apply EKT processing
  *
  * question: will we want to allow key-sharing templates in addition
  * to EKT templates?  could define a new ssrc_type_t that's associated
  * with an EKT, e.g.  ssrc_any_ekt.
  *
  *
  */
 
-#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 srtp_ekt_spi_t;
 
-typedef uint16_t 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 */
-  uint8_t    ekt_cipher_type;
-  uint8_t   *ekt_key;
-  struct ekt_policy_ctx_t *next_ekt_policy;
-} ekt_policy_ctx_t;
-
+typedef struct srtp_ekt_policy_ctx_t {
+    srtp_ekt_spi_t spi; /* security parameter index */
+    uint8_t ekt_cipher_type;
+    uint8_t *ekt_key;
+    struct srtp_ekt_policy_ctx_t *next_ekt_policy;
+} srtp_ekt_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;
-  uint8_t ekt_cipher_type;
-  aes_expanded_key_t ekt_enc_key;
-  aes_expanded_key_t ekt_dec_key;
-  struct ekt_data_t *next_ekt_data;
-} ekt_data_t;
+typedef struct srtp_ekt_data_t {
+    srtp_ekt_spi_t spi;
+    uint8_t ekt_cipher_type;
+    srtp_aes_expanded_key_t ekt_enc_key;
+    srtp_aes_expanded_key_t ekt_dec_key;
+    struct ekt_data_t *next_ekt_data;
+} srtp_ekt_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);
-
-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_alloc(srtp_ekt_stream_t *stream_data,
+                                 srtp_ekt_policy_t policy);
 
-err_status_t
-ekt_stream_init_from_policy(ekt_stream_t e, ekt_policy_t p);
-  
+srtp_err_status_t srtp_ekt_stream_init(srtp_ekt_stream_t e,
+                                       srtp_ekt_spi_t spi,
+                                       void *ekt_key,
+                                       unsigned ekt_cipher_type);
 
+srtp_err_status_t srtp_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
  * authentication (copying the auth tag into a temporary location,
  * zeroizing the "base tag" field in the packet)
  *
  * With EKT, the tag_len parameter is actually the base tag
  * length
  */
-
-err_status_t
-ekt_tag_verification_preproces(uint8_t *pkt_tag, 
-			       uint8_t *pkt_tag_copy, 
-			       unsigned tag_len);
+srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag,
+                                                      uint8_t *pkt_tag_copy,
+                                                      unsigned tag_len);
 
-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);
 
 /*
  * @brief EKT pre-processing for srtcp tag generation
  *
  * This function does the pre-processing of the SRTCP authentication
  * tag format.  When EKT is used, it consists of writing the Encrypted
  * Master Key, the SRTP ROC, the Initial Sequence Number, and SPI
  * fields.  The Base Authentication Tag field is set to the all-zero
  * value
- * 
+ *
  * When EKT is not used, this function is a no-op.
- * 
+ *
  */
-
-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 */
--- a/netwerk/srtp/src/include/getopt_s.h
+++ b/netwerk/srtp/src/include/getopt_s.h
@@ -2,36 +2,36 @@
  * getopt.h
  *
  * interface to a minimal implementation of the getopt() function,
  * written so that test applications that use that function can run on
  * non-POSIX platforms
  *
  */
 /*
- *	
- * 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
  * 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)
@@ -40,21 +40,28 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
 #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.
  */
- 
-int
-getopt_s(int argc, char * const argv[], const char *optstring);
+
+int getopt_s(int argc, char *const argv[], const char *optstring);
+
+extern char *optarg_s; /* defined in getopt.c */
 
-extern char *optarg_s;    /* defined in getopt.c */
+extern int optind_s; /* defined in getopt.c */
 
-extern int optind_s;      /* defined in getopt.c */
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GETOPT_S_H */
deleted file mode 100644
--- a/netwerk/srtp/src/include/rtp.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * rtp.h
- * 
- * rtp interface for srtp reference implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- *
- * data types:
- *
- * rtp_msg_t       an rtp message (the data that goes on the wire)
- * rtp_sender_t    sender side socket and rtp info
- * rtp_receiver_t  receiver side socket and rtp info
- *
- */
-
-/*
- *	
- * Copyright (c) 2001-2006, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef RTP_H
-#define RTP_H
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#elif defined HAVE_WINSOCK2_H
-# include <winsock2.h>
-#endif
-
-#include "srtp.h"
-
-typedef struct rtp_sender_ctx_t *rtp_sender_t;
-
-typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
-
-int
-rtp_sendto(rtp_sender_t sender, const void* msg, int len);
-
-int
-rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
-
-int
-rtp_receiver_init(rtp_receiver_t rcvr, int sock, 
-		  struct sockaddr_in addr, unsigned int ssrc);
-
-int
-rtp_sender_init(rtp_sender_t sender, int sock, 
-		struct sockaddr_in addr, unsigned int ssrc);
-
-/*
- * srtp_sender_init(...) initializes an rtp_sender_t
- */
-
-int
-srtp_sender_init(rtp_sender_t rtp_ctx,          /* structure to be init'ed */
-		 struct sockaddr_in name,       /* socket name             */
-		 sec_serv_t security_services,  /* sec. servs. to be used  */
-		 unsigned char *input_key       /* master key/salt in hex  */
-		 );
-
-int
-srtp_receiver_init(rtp_receiver_t rtp_ctx,       /* structure to be init'ed */
-		   struct sockaddr_in name, 	 /* socket name             */
-		   sec_serv_t security_services, /* sec. servs. to be used  */
-		   unsigned char *input_key	 /* master key/salt in hex  */
-		   );
-
-
-int
-rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
-
-int
-rtp_sender_deinit_srtp(rtp_sender_t sender);
-
-int
-rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
-
-int
-rtp_receiver_deinit_srtp(rtp_receiver_t sender);
-
-
-rtp_sender_t 
-rtp_sender_alloc(void);
-
-void
-rtp_sender_dealloc(rtp_sender_t rtp_ctx);
-
-rtp_receiver_t 
-rtp_receiver_alloc(void);
-
-void
-rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
-
-
-/*
- * RTP_HEADER_LEN indicates the size of an RTP header
- */
-#define RTP_HEADER_LEN   12
-
-/* 
- * RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
- */
-#define RTP_MAX_BUF_LEN  16384
-
-
-#endif /* RTP_H */
deleted file mode 100644
--- a/netwerk/srtp/src/include/rtp_priv.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * rtp_priv.h
- *
- * private, internal header file for RTP
- *
- * 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 RTP_PRIV_H
-#define RTP_PRIV_H
-
-#include "srtp_priv.h"
-#include "rtp.h"
-
-typedef srtp_hdr_t rtp_hdr_t;
-
-typedef struct {
-  srtp_hdr_t header;        
-  char body[RTP_MAX_BUF_LEN];  
-} rtp_msg_t;
-
-typedef struct rtp_sender_ctx_t {
-  rtp_msg_t message;         
-  int socket;
-  srtp_ctx_t *srtp_ctx;
-  struct sockaddr_in addr;   /* reciever's address */
-} rtp_sender_ctx_t;
-
-typedef struct rtp_receiver_ctx_t {
-  rtp_msg_t message;
-  int socket;
-  srtp_ctx_t *srtp_ctx;
-  struct sockaddr_in addr;   /* receiver's address */
-} rtp_receiver_ctx_t;
-
-
-#endif /* RTP_PRIV_H */
--- a/netwerk/srtp/src/include/srtp.h
+++ b/netwerk/srtp/src/include/srtp.h
@@ -2,61 +2,60 @@
  * srtp.h
  *
  * interface to libsrtp
  *
  * 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
  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
+#ifndef SRTP_SRTP_H
+#define SRTP_SRTP_H
 
-#ifndef SRTP_H
-#define SRTP_H
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include "crypto_kernel.h" 
-
 /**
  * @defgroup SRTP Secure RTP
  *
  * @brief libSRTP provides functions for protecting RTP and RTCP.  See
  * Section @ref Overview for an introduction to the use of the library.
  *
  * @{
  */
@@ -65,844 +64,1473 @@ extern "C" {
  * SRTP_MASTER_KEY_LEN is the nominal master key length supported by libSRTP
  */
 
 #define SRTP_MASTER_KEY_LEN 30
 
 /*
  * SRTP_MAX_KEY_LEN is the maximum key length supported by libSRTP
  */
-#define SRTP_MAX_KEY_LEN      64
+#define SRTP_MAX_KEY_LEN 64
 
 /*
  * SRTP_MAX_TAG_LEN is the maximum tag length supported by libSRTP
  */
 
-#define SRTP_MAX_TAG_LEN 12 
+#define SRTP_MAX_TAG_LEN 16
+
+/**
+ * SRTP_MAX_MKI_LEN is the maximum size the MKI could be which is
+ * 128 bytes
+ */
+#define SRTP_MAX_MKI_LEN 128
 
 /**
  * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer
  * (authentication tag and MKI) supported by libSRTP.  This value is
- * the maximum number of octets that will be added to an RTP packet by
+ * the maixmum number of octets that will be added to an RTP packet by
  * srtp_protect().
  *
  * @brief the maximum number of octets added by srtp_protect().
  */
-#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN 
+#define SRTP_MAX_TRAILER_LEN (SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN)
+
+/**
+ * SRTP_MAX_NUM_MASTER_KEYS is the maximum number of Master keys for
+ * MKI supported by libSRTP.
+ *
+ */
+#define SRTP_MAX_NUM_MASTER_KEYS 16
+
+#define SRTP_SALT_LEN 14
+
+/*
+ * SRTP_AEAD_SALT_LEN is the length of the SALT values used with
+ * GCM mode.  GCM mode requires an IV.  The SALT value is used
+ * as part of the IV formation logic applied to each RTP packet.
+ */
+#define SRTP_AEAD_SALT_LEN 12
+
+#define SRTP_AES_128_KEY_LEN 16
+#define SRTP_AES_192_KEY_LEN 24
+#define SRTP_AES_256_KEY_LEN 32
+
+#define SRTP_AES_ICM_128_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_128_KEY_LEN)
+#define SRTP_AES_ICM_192_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_192_KEY_LEN)
+#define SRTP_AES_ICM_256_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_256_KEY_LEN)
 
-/* 
- * nota bene: since libSRTP doesn't support the use of the MKI, the
- * SRTP_MAX_TRAILER_LEN value is just the maximum tag length
+#define SRTP_AES_GCM_128_KEY_LEN_WSALT                                         \
+    (SRTP_AEAD_SALT_LEN + SRTP_AES_128_KEY_LEN)
+#define SRTP_AES_GCM_192_KEY_LEN_WSALT                                         \
+    (SRTP_AEAD_SALT_LEN + SRTP_AES_192_KEY_LEN)
+#define SRTP_AES_GCM_256_KEY_LEN_WSALT                                         \
+    (SRTP_AEAD_SALT_LEN + SRTP_AES_256_KEY_LEN)
+
+/**
+ *  @brief A srtp_cipher_type_id_t is an identifier for a particular cipher
+ *  type.
+ *
+ *  A srtp_cipher_type_id_t is an integer that represents a particular
+ *  cipher type, e.g. the Advanced Encryption Standard (AES).  A
+ *  SRTP_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 srtp_cipher_type_id_t;
+
+/**
+ *  @brief An srtp_auth_type_id_t is an identifier for a particular
+ * authentication
+ *   function.
+ *
+ *  An srtp_auth_type_id_t is an integer that represents a particular
+ *  authentication function type, e.g. HMAC-SHA1.  A SRTP_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 srtp_auth_type_id_t;
 
 /**
- * @brief sec_serv_t describes a set of security services. 
+ * @brief srtp_err_status_t defines error codes.
  *
- * A sec_serv_t enumeration is used to describe the particular
- * security services that will be applied by a particular crypto
- * policy (or other mechanism).  
+ * The enumeration srtp_err_status_t defines error codes.  Note that the
+ * value of srtp_err_status_ok is equal to zero, which can simplify error
+ * checking somewhat.
+ *
  */
-
 typedef enum {
-  sec_serv_none          = 0, /**< no services                        */
-  sec_serv_conf          = 1, /**< confidentiality                    */
-  sec_serv_auth          = 2, /**< authentication                     */
-  sec_serv_conf_and_auth = 3  /**< confidentiality and authentication */
-} sec_serv_t;
+    srtp_err_status_ok = 0,             /**< nothing to report               */
+    srtp_err_status_fail = 1,           /**< unspecified failure             */
+    srtp_err_status_bad_param = 2,      /**< unsupported parameter           */
+    srtp_err_status_alloc_fail = 3,     /**< couldn't allocate memory        */
+    srtp_err_status_dealloc_fail = 4,   /**< couldn't deallocate properly    */
+    srtp_err_status_init_fail = 5,      /**< couldn't initialize             */
+    srtp_err_status_terminus = 6,       /**< can't process as much data as   */
+                                        /**< requested                       */
+    srtp_err_status_auth_fail = 7,      /**< authentication failure          */
+    srtp_err_status_cipher_fail = 8,    /**< cipher failure                  */
+    srtp_err_status_replay_fail = 9,    /**< replay check failed (bad index) */
+    srtp_err_status_replay_old = 10,    /**< replay check failed (index too  */
+                                        /**< old)                            */
+    srtp_err_status_algo_fail = 11,     /**< algorithm failed test routine   */
+    srtp_err_status_no_such_op = 12,    /**< unsupported operation           */
+    srtp_err_status_no_ctx = 13,        /**< no appropriate context found    */
+    srtp_err_status_cant_check = 14,    /**< unable to perform desired       */
+                                        /**< validation                      */
+    srtp_err_status_key_expired = 15,   /**< can't use key any more          */
+    srtp_err_status_socket_err = 16,    /**< error in use of socket          */
+    srtp_err_status_signal_err = 17,    /**< error in use POSIX signals      */
+    srtp_err_status_nonce_bad = 18,     /**< nonce check failed              */
+    srtp_err_status_read_fail = 19,     /**< couldn't read data              */
+    srtp_err_status_write_fail = 20,    /**< couldn't write data             */
+    srtp_err_status_parse_err = 21,     /**< error parsing data              */
+    srtp_err_status_encode_err = 22,    /**< error encoding data             */
+    srtp_err_status_semaphore_err = 23, /**< error while using semaphores    */
+    srtp_err_status_pfkey_err = 24,     /**< error while using pfkey         */
+    srtp_err_status_bad_mki = 25,       /**< error MKI present in packet is  */
+                                        /**< invalid                         */
+    srtp_err_status_pkt_idx_old = 26,   /**< packet index is too old to      */
+                                        /**< consider                        */
+    srtp_err_status_pkt_idx_adv = 27    /**< packet index advanced, reset    */
+                                        /**< needed                          */
+} srtp_err_status_t;
 
-/** 
- * @brief crypto_policy_t describes a particular crypto policy that
+typedef struct srtp_ctx_t_ srtp_ctx_t;
+
+/**
+ * @brief srtp_sec_serv_t describes a set of security services.
+ *
+ * A srtp_sec_serv_t enumeration is used to describe the particular
+ * security services that will be applied by a particular crypto
+ * policy (or other mechanism).
+ */
+typedef enum {
+    sec_serv_none = 0,         /**< no services                        */
+    sec_serv_conf = 1,         /**< confidentiality                    */
+    sec_serv_auth = 2,         /**< authentication                     */
+    sec_serv_conf_and_auth = 3 /**< confidentiality and authentication */
+} srtp_sec_serv_t;
+
+/**
+ * @brief srtp_crypto_policy_t describes a particular crypto policy that
  * can be applied to an SRTP stream.
  *
- * A crypto_policy_t describes a particular cryptographic policy that
+ * A srtp_crypto_policy_t describes a particular cryptographic policy that
  * can be applied to an SRTP or SRTCP stream.  An SRTP session policy
- * consists of a list of these policies, one for each SRTP stream 
+ * consists of a list of these policies, one for each SRTP stream
  * in the session.
  */
+typedef struct srtp_crypto_policy_t {
+    srtp_cipher_type_id_t cipher_type; /**< An integer representing          */
+                                       /**< the type of cipher.              */
+    int cipher_key_len;                /**< The length of the cipher key     */
+                                       /**< in octets.                       */
+    srtp_auth_type_id_t auth_type;     /**< An integer representing the      */
+                                       /**< authentication function.         */
+    int auth_key_len;                  /**< The length of the authentication */
+                                       /**< function key in octets.          */
+    int auth_tag_len;                  /**< The length of the authentication */
+                                       /**< tag in octets.                   */
+    srtp_sec_serv_t sec_serv;          /**< The flag indicating the security */
+                                       /**< services to be applied.          */
+} srtp_crypto_policy_t;
 
-typedef struct crypto_policy_t {
-  cipher_type_id_t cipher_type;    /**< An integer representing
-				    *   the type of cipher.  */
-  int              cipher_key_len; /**< The length of the cipher key
-				    *   in octets.                       */
-  auth_type_id_t   auth_type;      /**< An integer representing the
-				    *   authentication function.         */
-  int              auth_key_len;   /**< The length of the authentication 
-				    *   function key in octets.          */
-  int              auth_tag_len;   /**< The length of the authentication 
-				    *   tag in octets.                   */
-  sec_serv_t       sec_serv;       /**< The flag indicating the security
-				    *   services to be applied.          */
-} crypto_policy_t;
-
-
-/** 
- * @brief ssrc_type_t describes the type of an SSRC.
- * 
- * An ssrc_type_t enumeration is used to indicate a type of SSRC.  See
+/**
+ * @brief srtp_ssrc_type_t describes the type of an SSRC.
+ *
+ * An srtp_ssrc_type_t enumeration is used to indicate a type of SSRC.  See
  * @ref srtp_policy_t for more informataion.
  */
-
-typedef enum { 
-  ssrc_undefined    = 0,  /**< Indicates an undefined SSRC type. */
-  ssrc_specific     = 1,  /**< Indicates a specific SSRC value   */
-  ssrc_any_inbound  = 2, /**< Indicates any inbound SSRC value 
-			    (i.e. a value that is used in the
-			    function srtp_unprotect())              */
-  ssrc_any_outbound = 3  /**< Indicates any outbound SSRC value 
-			    (i.e. a value that is used in the 
-			    function srtp_protect())		  */
-} ssrc_type_t;
+typedef enum {
+    ssrc_undefined = 0,   /**< Indicates an undefined SSRC type.    */
+    ssrc_specific = 1,    /**< Indicates a specific SSRC value      */
+    ssrc_any_inbound = 2, /**< Indicates any inbound SSRC value     */
+                          /**< (i.e. a value that is used in the    */
+                          /**< function srtp_unprotect())           */
+    ssrc_any_outbound = 3 /**< Indicates any outbound SSRC value    */
+                          /**< (i.e. a value that is used in the    */
+                          /**< function srtp_protect())             */
+} srtp_ssrc_type_t;
 
 /**
- * @brief An ssrc_t represents a particular SSRC value, or a `wildcard' SSRC.
- * 
- * An ssrc_t represents a particular SSRC value (if its type is
+ * @brief An srtp_ssrc_t represents a particular SSRC value, or a `wildcard'
+ * SSRC.
+ *
+ * An srtp_ssrc_t represents a particular SSRC value (if its type is
  * ssrc_specific), or a wildcard SSRC value that will match all
  * outbound SSRCs (if its type is ssrc_any_outbound) or all inbound
- * SSRCs (if its type is ssrc_any_inbound).  
- *
+ * SSRCs (if its type is ssrc_any_inbound).
  */
-
-typedef struct { 
-  ssrc_type_t type;   /**< The type of this particular SSRC */
-  unsigned int value; /**< The value of this SSRC, if it is not a wildcard */
-} ssrc_t;
-
+typedef struct {
+    srtp_ssrc_type_t type; /**< The type of this particular SSRC */
+    unsigned int value;    /**< The value of this SSRC, if it is not a */
+                           /**< wildcard */
+} srtp_ssrc_t;
 
 /**
  * @brief points to an EKT policy
  */
-typedef struct ekt_policy_ctx_t *ekt_policy_t;
-
+typedef struct srtp_ekt_policy_ctx_t *srtp_ekt_policy_t;
 
 /**
  * @brief points to EKT stream data
  */
-typedef struct ekt_stream_ctx_t *ekt_stream_t;
-
+typedef struct srtp_ekt_stream_ctx_t *srtp_ekt_stream_t;
 
-/** 
- * @brief represents the policy for an SRTP session.  
+/**
+ * @brief srtp_master_key_t represents a master key.  There will
+ * be a Master Key Index and the Master Key associated with the
+ * Master Key Index.  Need to also keep track of the Master Key
+ * Index Size to correctly read it from a packet.
+ */
+typedef struct srtp_master_key_t {
+    unsigned char *key;
+    unsigned char *mki_id;
+    unsigned int mki_size;
+} srtp_master_key_t;
+
+/**
+ * @brief represents the policy for an SRTP session.
  *
  * A single srtp_policy_t struct represents the policy for a single
  * SRTP stream, and a linked list of these elements represents the
  * policy for an entire SRTP session.  Each element contains the SRTP
  * and SRTCP crypto policies for that stream, a pointer to the SRTP
  * master key for that stream, the SSRC describing that stream, or a
  * flag indicating a `wildcard' SSRC value, and a `next' field that
  * holds a pointer to the next element in the list of policy elements,
- * or NULL if it is the last element. 
+ * or NULL if it is the last element.
  *
  * The wildcard value SSRC_ANY_INBOUND matches any SSRC from an
  * inbound stream that for which there is no explicit SSRC entry in
  * another policy element.  Similarly, the value SSRC_ANY_OUTBOUND
  * will matches any SSRC from an outbound stream that does not appear
  * in another policy element.  Note that wildcard SSRCs &b cannot be
  * used to match both inbound and outbound traffic.  This restriction
  * is intentional, and it allows libSRTP to ensure that no security
  * lapses result from accidental re-use of SSRC values during key
  * sharing.
- * 
- * 
+ *
  * @warning The final element of the list @b must have its `next' pointer
  *          set to NULL.
  */
 
 typedef struct srtp_policy_t {
-  ssrc_t        ssrc;        /**< The SSRC value of stream, or the 
-			      *   flags SSRC_ANY_INBOUND or 
-			      *   SSRC_ANY_OUTBOUND if key sharing
-			      *   is used for this policy element.
-			      */
-  crypto_policy_t rtp;         /**< SRTP crypto policy.                  */
-  crypto_policy_t rtcp;        /**< SRTCP crypto policy.                 */
-  unsigned char *key;          /**< Pointer to the SRTP master key for
-				*    this stream.                        */
-  ekt_policy_t ekt;            /**< Pointer to the EKT policy structure
-                                *   for this stream (if any)             */ 
-  unsigned long window_size;   /**< The window size to use for replay
-				*   protection. */
-  int        allow_repeat_tx;  /**< Whether retransmissions of
-				*   packets with the same sequence number
-				*   are allowed.  (Note that such repeated
-				*   transmissions must have the same RTP
-				*   payload, or a severe security weakness
-				*   is introduced!)                      */
-  struct srtp_policy_t *next;  /**< Pointer to next stream policy.       */
+    srtp_ssrc_t ssrc;              /**< The SSRC value of stream, or the    */
+                                   /**< flags SSRC_ANY_INBOUND or           */
+                                   /**< SSRC_ANY_OUTBOUND if key sharing    */
+                                   /**< is used for this policy element.    */
+    srtp_crypto_policy_t rtp;      /**< SRTP crypto policy.                 */
+    srtp_crypto_policy_t rtcp;     /**< SRTCP crypto policy.                */
+    unsigned char *key;            /**< Pointer to the SRTP master key for  */
+                                   /**< this stream.                        */
+    srtp_master_key_t **keys;      /** Array of Master Key structures       */
+    unsigned long num_master_keys; /** Number of master keys                */
+    srtp_ekt_policy_t ekt;         /**< Pointer to the EKT policy structure */
+                                   /**< for this stream (if any)            */
+    unsigned long window_size;     /**< The window size to use for replay   */
+                                   /**< protection.                         */
+    int allow_repeat_tx;           /**< Whether retransmissions of          */
+                                   /**< packets with the same sequence      */
+                                   /**< number are allowed.                 */
+                                   /**< (Note that such repeated            */
+                                   /**< transmissions must have the same    */
+                                   /**< RTP payload, or a severe security   */
+                                   /**< weakness is introduced!)            */
+    int *enc_xtn_hdr;              /**< List of header ids to encrypt.      */
+    int enc_xtn_hdr_count;         /**< Number of entries in list of header */
+                                   /**<  ids.                               */
+    struct srtp_policy_t *next;    /**< Pointer to next stream policy.      */
 } srtp_policy_t;
 
-
-
-
 /**
  * @brief An srtp_t points to an SRTP session structure.
  *
  * The typedef srtp_t is a pointer to a structure that represents
- * an SRTP session.  This datatype is intentially opaque in 
+ * an SRTP session.  This datatype is intentially opaque in
  * order to separate the interface from the implementation.
  *
  * An SRTP session consists of all of the traffic sent to the RTP and
  * RTCP destination transport addresses, using the RTP/SAVP (Secure
  * Audio/Video Profile).  A session can be viewed as a set of SRTP
  * streams, each of which originates with a different participant.
  */
-
-typedef struct srtp_ctx_t *srtp_t;
-
+typedef srtp_ctx_t *srtp_t;
 
 /**
- * @brief An srtp_stream_t points to an SRTP stream structure.
- *
- * The typedef srtp_stream_t is a pointer to a structure that
- * represents an SRTP stream.  This datatype is intentionally
- * opaque in order to separate the interface from the implementation. 
- * 
- * An SRTP stream consists of all of the traffic sent to an SRTP
- * session by a single participant.  A session can be viewed as
- * a set of streams.  
- *
- */
-typedef struct srtp_stream_ctx_t *srtp_stream_t;
-
-
-
-/**
- * @brief srtp_init() initializes the srtp library.  
+ * @brief srtp_init() initializes the srtp library.
  *
  * @warning This function @b must be called before any other srtp
  * functions.
  */
-
-err_status_t
-srtp_init(void);
+srtp_err_status_t srtp_init(void);
 
 /**
  * @brief srtp_shutdown() de-initializes the srtp library.
  *
  * @warning No srtp functions may be called after calling this function.
  */
-
-err_status_t
-srtp_shutdown(void);
+srtp_err_status_t srtp_shutdown(void);
 
 /**
  * @brief srtp_protect() is the Secure RTP sender-side packet processing
  * function.
- * 
+ *
  * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP
  * protection to the RTP packet rtp_hdr (which has length *len_ptr) using
- * the SRTP context ctx.  If err_status_ok is returned, then rtp_hdr
+ * the SRTP context ctx.  If srtp_err_status_ok is returned, then rtp_hdr
  * points to the resulting SRTP packet and *len_ptr is the number of
  * octets in that packet; otherwise, no assumptions should be made
  * about the value of either data elements.
- * 
+ *
+ * The sequence numbers of the RTP packets presented to this function
+ * need not be consecutive, but they @b must be out of order by less
+ * than 2^15 = 32,768 packets.
+ *
+ * @warning This function assumes that it can write the authentication
+ * tag into the location in memory immediately following the RTP
+ * packet, and assumes that the RTP packet is aligned on a 32-bit
+ * boundary.
+ *
+ * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN
+ * into the location in memory immediately following the RTP packet.
+ * Callers MUST ensure that this much writable memory is available in
+ * the buffer that holds the RTP packet.
+ *
+ * @param ctx is the SRTP context to use in processing the packet.
+ *
+ * @param rtp_hdr is a pointer to the RTP packet (before the call); after
+ * the function returns, it points to the srtp packet.
+ *
+ * @param len_ptr is a pointer to the length in octets of the complete
+ * RTP packet (header and body) before the function call, and of the
+ * complete SRTP packet after the call, if srtp_err_status_ok was returned.
+ * Otherwise, the value of the data to which it points is undefined.
+ *
+ * @return
+ *    - srtp_err_status_ok            no problems
+ *    - srtp_err_status_replay_fail   rtp sequence number was non-increasing
+ *    - @e other                 failure in cryptographic mechanisms
+ */
+srtp_err_status_t srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr);
+
+/**
+ * @brief srtp_protect_mki() is the Secure RTP sender-side packet processing
+ * function that can utilize MKI.
+ *
+ * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP
+ * protection to the RTP packet rtp_hdr (which has length *len_ptr) using
+ * the SRTP context ctx.  If srtp_err_status_ok is returned, then rtp_hdr
+ * points to the resulting SRTP packet and *len_ptr is the number of
+ * octets in that packet; otherwise, no assumptions should be made
+ * about the value of either data elements.
+ *
  * The sequence numbers of the RTP packets presented to this function
  * need not be consecutive, but they @b must be out of order by less
  * than 2^15 = 32,768 packets.
  *
  * @warning This function assumes that it can write the authentication
  * tag into the location in memory immediately following the RTP
  * packet, and assumes that the RTP packet is aligned on a 32-bit
  * boundary.
  *
+ * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN
+ * into the location in memory immediately following the RTP packet.
+ * Callers MUST ensure that this much writable memory is available in
+ * the buffer that holds the RTP packet.
+ *
  * @param ctx is the SRTP context to use in processing the packet.
  *
  * @param rtp_hdr is a pointer to the RTP packet (before the call); after
  * the function returns, it points to the srtp packet.
  *
- * @param len_ptr is a pointer to the length in octets of the complete
+ * @param pkt_octet_len is a pointer to the length in octets of the complete
  * RTP packet (header and body) before the function call, and of the
- * complete SRTP packet after the call, if err_status_ok was returned.
+ * complete SRTP packet after the call, if srtp_err_status_ok was returned.
  * Otherwise, the value of the data to which it points is undefined.
  *
- * @return 
- *    - err_status_ok            no problems
- *    - err_status_replay_fail   rtp sequence number was non-increasing
+ * @param use_mki is a boolean to tell the system if mki is being used.  If
+ * set to false then will use the first set of session keys.  If set to true
+ * will
+ * use the session keys identified by the mki_index
+ *
+ * @param mki_index integer value specifying which set of session keys should be
+ * used if use_mki is set to true.
+ *
+ * @return
+ *    - srtp_err_status_ok            no problems
+ *    - srtp_err_status_replay_fail   rtp sequence number was non-increasing
  *    - @e other                 failure in cryptographic mechanisms
  */
+srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
+                                   void *rtp_hdr,
+                                   int *pkt_octet_len,
+                                   unsigned int use_mki,
+                                   unsigned int mki_index);
 
-err_status_t
-srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr);
-	     
 /**
  * @brief srtp_unprotect() is the Secure RTP receiver-side packet
  * processing function.
  *
  * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies
  * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr
  * (which has length *len_ptr), using the SRTP context ctx.  If
- * err_status_ok is returned, then srtp_hdr points to the resulting
+ * srtp_err_status_ok is returned, then srtp_hdr points to the resulting
  * RTP packet and *len_ptr is the number of octets in that packet;
  * otherwise, no assumptions should be made about the value of either
- * data elements.  
- * 
+ * data elements.
+ *
  * The sequence numbers of the RTP packets presented to this function
  * need not be consecutive, but they @b must be out of order by less
  * than 2^15 = 32,768 packets.
- * 
+ *
  * @warning This function assumes that the SRTP packet is aligned on a
  * 32-bit boundary.
  *
- * @param ctx is a pointer to the srtp_t which applies to the
- * particular packet.
+ * @param ctx is the SRTP session which applies to the particular packet.
  *
  * @param srtp_hdr is a pointer to the header of the SRTP packet
  * (before the call).  after the function returns, it points to the
- * rtp packet if err_status_ok was returned; otherwise, the value of
+ * rtp packet if srtp_err_status_ok was returned; otherwise, the value of
  * the data to which it points is undefined.
  *
  * @param len_ptr is a pointer to the length in octets of the complete
  * srtp packet (header and body) before the function call, and of the
- * complete rtp packet after the call, if err_status_ok was returned.
+ * complete rtp packet after the call, if srtp_err_status_ok was returned.
  * Otherwise, the value of the data to which it points is undefined.
  *
- * @return 
- *    - err_status_ok          if the RTP packet is valid.
- *    - err_status_auth_fail   if the SRTP packet failed the message 
- *                             authentication check.
- *    - err_status_replay_fail if the SRTP packet is a replay (e.g. packet has
- *                             already been processed and accepted).
+ * @return
+ *    - srtp_err_status_ok          if the RTP packet is valid.
+ *    - srtp_err_status_auth_fail   if the SRTP packet failed the message
+ *                                  authentication check.
+ *    - srtp_err_status_replay_fail if the SRTP packet is a replay (e.g. packet
+ *                                  has already been processed and accepted).
  *    - [other]  if there has been an error in the cryptographic mechanisms.
  *
  */
+srtp_err_status_t srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr);
 
-err_status_t
-srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr);
-
+/**
+ * @brief srtp_unprotect_mki() is the Secure RTP receiver-side packet
+ * processing function that checks for MKI.
+ *
+ * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies
+ * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr
+ * (which has length *len_ptr), using the SRTP context ctx.  If
+ * srtp_err_status_ok is returned, then srtp_hdr points to the resulting
+ * RTP packet and *len_ptr is the number of octets in that packet;
+ * otherwise, no assumptions should be made about the value of either
+ * data elements.
+ *
+ * The sequence numbers of the RTP packets presented to this function
+ * need not be consecutive, but they @b must be out of order by less
+ * than 2^15 = 32,768 packets.
+ *
+ * @warning This function assumes that the SRTP packet is aligned on a
+ * 32-bit boundary.
+ *
+ * @param ctx is the SRTP session which applies to the particular packet.
+ *
+ * @param srtp_hdr is a pointer to the header of the SRTP packet
+ * (before the call).  after the function returns, it points to the
+ * rtp packet if srtp_err_status_ok was returned; otherwise, the value of
+ * the data to which it points is undefined.
+ *
+ * @param len_ptr is a pointer to the length in octets of the complete
+ * srtp packet (header and body) before the function call, and of the
+ * complete rtp packet after the call, if srtp_err_status_ok was returned.
+ * Otherwise, the value of the data to which it points is undefined.
+ *
+ * @param use_mki is a boolean to tell the system if mki is being used.  If
+ * set to false then will use the first set of session keys.  If set to true
+ * will
+ * use the session keys identified by the mki_index
+ *
+ * @return
+ *    - srtp_err_status_ok          if the RTP packet is valid.
+ *    - srtp_err_status_auth_fail   if the SRTP packet failed the message
+ *                                  authentication check.
+ *    - srtp_err_status_replay_fail if the SRTP packet is a replay (e.g. packet
+ *                                  has already been processed and accepted).
+ *    - srtp_err_status_bad_mki if the MKI in the packet is not a known MKI id
+ *    - [other]  if there has been an error in the cryptographic mechanisms.
+ *
+ */
+srtp_err_status_t srtp_unprotect_mki(srtp_t ctx,
+                                     void *srtp_hdr,
+                                     int *len_ptr,
+                                     unsigned int use_mki);
 
 /**
  * @brief srtp_create() allocates and initializes an SRTP session.
 
- * The function call srtp_create(session, policy, key) allocates and
- * initializes an SRTP session context, applying the given policy and
- * key.
+ * The function call srtp_create(session, policy) allocates and
+ * initializes an SRTP session context, applying the given policy.
  *
- * @param session is the SRTP session to which the policy is to be added.
- * 
+ * @param session is a pointer to the SRTP session to which the policy is
+ * to be added.
+ *
  * @param policy is the srtp_policy_t struct that describes the policy
  * for the session.  The struct may be a single element, or it may be
  * the head of a list, in which case each element of the list is
  * processed.  It may also be NULL, in which case streams should be added
  * later using srtp_add_stream().  The final element of the list @b must
  * have its `next' field set to NULL.
- * 
+ *
  * @return
- *    - err_status_ok           if creation succeded.
- *    - err_status_alloc_fail   if allocation failed.
- *    - err_status_init_fail    if initialization failed.
+ *    - srtp_err_status_ok           if creation succeded.
+ *    - srtp_err_status_alloc_fail   if allocation failed.
+ *    - srtp_err_status_init_fail    if initialization failed.
  */
-
-err_status_t
-srtp_create(srtp_t *session, const srtp_policy_t *policy);
-
+srtp_err_status_t srtp_create(srtp_t *session, const srtp_policy_t *policy);
 
 /**
  * @brief srtp_add_stream() allocates and initializes an SRTP stream
  * within a given SRTP session.
- * 
+ *
  * The function call srtp_add_stream(session, policy) allocates and
  * initializes a new SRTP stream within a given, previously created
  * session, applying the policy given as the other argument to that
  * stream.
  *
  * @return values:
- *    - err_status_ok           if stream creation succeded.
- *    - err_status_alloc_fail   if stream allocation failed
- *    - err_status_init_fail    if stream initialization failed.
+ *    - srtp_err_status_ok           if stream creation succeded.
+ *    - srtp_err_status_alloc_fail   if stream allocation failed
+ *    - srtp_err_status_init_fail    if stream initialization failed.
  */
-
-err_status_t
-srtp_add_stream(srtp_t session, 
-		const srtp_policy_t *policy);
-
+srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy);
 
 /**
  * @brief srtp_remove_stream() deallocates an SRTP stream.
- * 
+ *
  * The function call srtp_remove_stream(session, ssrc) removes
  * the SRTP stream with the SSRC value ssrc from the SRTP session
  * context given by the argument session.
  *
  * @param session is the SRTP session from which the stream
  *        will be removed.
  *
- * @param ssrc is the SSRC value of the stream to be removed.
+ * @param ssrc is the SSRC value of the stream to be removed
+ *             in network byte order.
  *
  * @warning Wildcard SSRC values cannot be removed from a
  *          session.
- * 
+ *
  * @return
- *    - err_status_ok     if the stream deallocation succeded.
+ *    - srtp_err_status_ok     if the stream deallocation succeded.
  *    - [other]           otherwise.
  *
  */
+srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc);
 
-err_status_t
-srtp_remove_stream(srtp_t session, unsigned int ssrc);
+/**
+ * @brief srtp_update() udpates all streams in the session.
+ *
+ * The function call srtp_update(session, policy) updates
+ * all the streams in the session applying the given policy
+ * and key. The exsisting ROC value of all streams will be
+ * preserved.
+ *
+ * @param session is the SRTP session that contains the streams
+ *        to be updated.
+ *
+ * @param policy is the srtp_policy_t struct that describes the policy
+ * for the session.  The struct may be a single element, or it may be
+ * the head of a list, in which case each element of the list is
+ * processed. The final element of the list @b must
+ * have its `next' field set to NULL.
+ *
+ * @return
+ *    - srtp_err_status_ok           if stream creation succeded.
+ *    - srtp_err_status_alloc_fail   if stream allocation failed
+ *    - srtp_err_status_init_fail    if stream initialization failed.
+ *    - [other]                 otherwise.
+ *
+ */
+srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy);
 
 /**
- * @brief crypto_policy_set_rtp_default() sets a crypto policy
+ * @brief srtp_update_stream() udpates a SRTP stream.
+ *
+ * The function call srtp_update_stream(session, policy) updates
+ * the stream(s) in the session that match applying the given
+ * policy and key. The exsisting ROC value of all stream(s) will
+ * be preserved.
+ *
+ * @param session is the SRTP session that contains the streams
+ *        to be updated.
+ *
+ * @param policy is the srtp_policy_t struct that describes the policy
+ * for the session.
+ *
+ * @return
+ *    - srtp_err_status_ok           if stream creation succeded.
+ *    - srtp_err_status_alloc_fail   if stream allocation failed
+ *    - srtp_err_status_init_fail    if stream initialization failed.
+ *    - [other]                      otherwise.
+ *
+ */
+srtp_err_status_t srtp_update_stream(srtp_t session,
+                                     const srtp_policy_t *policy);
+
+/**
+ * @brief srtp_crypto_policy_set_rtp_default() sets a crypto policy
  * structure to the SRTP default policy for RTP protection.
  *
- * @param p is a pointer to the policy structure to be set 
- * 
+ * @param p is a pointer to the policy structure to be set
+ *
  * The function call crypto_policy_set_rtp_default(&p) sets the
  * crypto_policy_t at location p to the SRTP default policy for RTP
  * protection, as defined in the specification.  This function is a
  * convenience that helps to avoid dealing directly with the policy
  * data structure.  You are encouraged to initialize policy elements
  * with this function call.  Doing so may allow your code to be
  * forward compatible with later versions of libSRTP that include more
  * elements in the crypto_policy_t datatype.
- * 
+ *
  * @return void.
- * 
+ *
  */
-
-void
-crypto_policy_set_rtp_default(crypto_policy_t *p);
+void srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_rtcp_default() sets a crypto policy
+ * @brief srtp_crypto_policy_set_rtcp_default() sets a crypto policy
  * structure to the SRTP default policy for RTCP protection.
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_rtcp_default(&p) sets the
- * crypto_policy_t at location p to the SRTP default policy for RTCP
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_rtcp_default(&p) sets the
+ * srtp_crypto_policy_t at location p to the SRTP default policy for RTCP
  * protection, as defined in the specification.  This function is a
  * convenience that helps to avoid dealing directly with the policy
  * data structure.  You are encouraged to initialize policy elements
  * with this function call.  Doing so may allow your code to be
  * forward compatible with later versions of libSRTP that include more
- * elements in the crypto_policy_t datatype.
- * 
+ * elements in the srtp_crypto_policy_t datatype.
+ *
  * @return void.
- * 
+ *
  */
-
-void
-crypto_policy_set_rtcp_default(crypto_policy_t *p);
+void srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto
+ * @brief srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto
  * policy structure to the SRTP default policy for RTP protection.
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function crypto_policy_set_aes_cm_128_hmac_sha1_80() is a
- * synonym for crypto_policy_set_rtp_default().  It conforms to the
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80() is a
+ * synonym for srtp_crypto_policy_set_rtp_default().  It conforms to the
  * naming convention used in RFC 4568 (SDP Security Descriptions for
  * Media Streams).
- * 
+ *
  * @return void.
- * 
+ *
  */
-
-#define crypto_policy_set_aes_cm_128_hmac_sha1_80(p) crypto_policy_set_rtp_default(p)
-
+#define srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(p)                      \
+    srtp_crypto_policy_set_rtp_default(p)
 
 /**
- * @brief crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto
+ * @brief srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto
  * policy structure to a short-authentication tag policy
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_aes_cm_128_hmac_sha1_32(&p)
- * sets the crypto_policy_t at location p to use policy
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&p)
+ * sets the srtp_crypto_policy_t at location p to use policy
  * AES_CM_128_HMAC_SHA1_32 as defined in RFC 4568.
  * This policy uses AES-128
  * Counter Mode encryption and HMAC-SHA1 authentication, with an
  * authentication tag that is only 32 bits long.  This length is
  * considered adequate only for protecting audio and video media that
  * use a stateless playback function.  See Section 7.5 of RFC 3711
  * (http://www.ietf.org/rfc/rfc3711.txt).
- * 
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This crypto policy is intended for use in SRTP, but not in
+ * SRTCP.  It is recommended that a policy that uses longer
+ * authentication tags be used for SRTCP.  See Section 7.5 of RFC 3711
+ * (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_128_null_auth() sets a crypto
+ * policy structure to an encryption-only policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_128_null_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-128 Counter Mode), but to use no authentication method.  This
+ * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5
+ * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This policy is NOT RECOMMENDED for SRTP unless it is
+ * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see
+ * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto
+ * policy structure to an authentication-only policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&p)
+ * sets the srtp_crypto_policy_t at location p to use HMAC-SHA1 with an 80
+ * bit authentication tag to provide message authentication, but to
+ * use no encryption.  This policy is NOT RECOMMENDED for SRTP unless
+ * there is a requirement to forego encryption.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This policy is NOT RECOMMENDED for SRTP unless there is a
+ * requirement to forego encryption.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_null_cipher_hmac_null() sets a crypto
+ * policy structure to use no encryption or authentication.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_null_cipher_hmac_null(&p)
+ * sets the srtp_crypto_policy_t at location p to use no encryption and
+ * no authentication.  This policy should only be used for testing and
+ * troubleshootingl.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This policy is NOT RECOMMENDED for SRTP unless there is a
+ * requirement to forego encryption and authentication.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80() sets a crypto
+ * policy structure to a encryption and authentication policy using AES-256
+ * for RTP protection.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&p)
+ * sets the srtp_crypto_policy_t at location p to use policy
+ * AES_CM_256_HMAC_SHA1_80 as defined in RFC 6188.  This policy uses AES-256
+ * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit
+ * authentication tag.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32() sets a crypto
+ * policy structure to a short-authentication tag policy using AES-256
+ * encryption.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(&p)
+ * sets the srtp_crypto_policy_t at location p to use policy
+ * AES_CM_256_HMAC_SHA1_32 as defined in RFC 6188.  This policy uses AES-256
+ * Counter Mode encryption and HMAC-SHA1 authentication, with an
+ * authentication tag that is only 32 bits long.  This length is
+ * considered adequate only for protecting audio and video media that
+ * use a stateless playback function.  See Section 7.5 of RFC 3711
+ * (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This crypto policy is intended for use in SRTP, but not in
+ * SRTCP.  It is recommended that a policy that uses longer
+ * authentication tags be used for SRTCP.  See Section 7.5 of RFC 3711
+ * (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_256_null_auth() sets a crypto
+ * policy structure to an encryption-only policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_256_null_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-256 Counter Mode), but to use no authentication method.  This
+ * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5
+ * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @warning This policy is NOT RECOMMENDED for SRTP unless it is
+ * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see
+ * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80() sets a crypto
+ * policy structure to a encryption and authentication policy using AES-192
+ * for RTP protection.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&p)
+ * sets the crypto_policy_t at location p to use policy
+ * AES_CM_192_HMAC_SHA1_80 as defined in RFC 6188.  This policy uses AES-192
+ * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit
+ * authentication tag.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32() sets a crypto
+ * policy structure to a short-authentication tag policy using AES-192
+ * encryption.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&p)
+ * sets the crypto_policy_t at location p to use policy
+ * AES_CM_192_HMAC_SHA1_32 as defined in RFC 6188.  This policy uses AES-192
+ * Counter Mode encryption and HMAC-SHA1 authentication, with an
+ * authentication tag that is only 32 bits long.  This length is
+ * considered adequate only for protecting audio and video media that
+ * use a stateless playback function.  See Section 7.5 of RFC 3711
+ * (http://www.ietf.org/rfc/rfc3711.txt).
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
  * include more elements in the crypto_policy_t datatype.
  *
  * @warning This crypto policy is intended for use in SRTP, but not in
  * SRTCP.  It is recommended that a policy that uses longer
  * authentication tags be used for SRTCP.  See Section 7.5 of RFC 3711
  * (http://www.ietf.org/rfc/rfc3711.txt).
  *
  * @return void.
- * 
+ *
  */
-
-void
-crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p);
-
-
+void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_aes_cm_128_null_auth() sets a crypto
+ * @brief srtp_crypto_policy_set_aes_cm_192_null_auth() sets a crypto
  * policy structure to an encryption-only policy
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_aes_cm_128_null_auth(&p) sets
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_cm_192_null_auth(&p) sets
  * the crypto_policy_t at location p to use the SRTP default cipher
- * (AES-128 Counter Mode), but to use no authentication method.  This
+ * (AES-192 Counter Mode), but to use no authentication method.  This
  * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5
  * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
- * 
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
  * include more elements in the crypto_policy_t datatype.
  *
  * @warning This policy is NOT RECOMMENDED for SRTP unless it is
  * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see
  * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt).
  *
  * @return void.
- * 
+ *
  */
+void srtp_crypto_policy_set_aes_cm_192_null_auth(srtp_crypto_policy_t *p);
 
-void
-crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p);
-
+/**
+ * @brief srtp_crypto_policy_set_aes_gcm_128_8_auth() sets a crypto
+ * policy structure to an AEAD encryption policy.
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_gcm_128_8_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-128 Galois Counter Mode) with 8 octet auth tag.  This
+ * policy applies confidentiality and authentication to both the
+ * RTP and RTCP packets.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto
- * policy structure to an authentication-only policy
+ * @brief srtp_crypto_policy_set_aes_gcm_256_8_auth() sets a crypto
+ * policy structure to an AEAD encryption policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_gcm_256_8_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-256 Galois Counter Mode) with 8 octet auth tag.  This
+ * policy applies confidentiality and authentication to both the
+ * RTP and RTCP packets.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_null_cipher_hmac_sha1_80(&p)
- * sets the crypto_policy_t at location p to use HMAC-SHA1 with an 80
- * bit authentication tag to provide message authentication, but to
- * use no encryption.  This policy is NOT RECOMMENDED for SRTP unless
- * there is a requirement to forego encryption.  
- * 
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p);
+
+/**
+ * @brief srtp_crypto_policy_set_aes_gcm_128_8_only_auth() sets a crypto
+ * policy structure to an AEAD authentication-only policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-128 Galois Counter Mode) with 8 octet auth tag.  This policy
+ * applies confidentiality and authentication to the RTP packets,
+ * but only authentication to the RTCP packets.
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
- * include more elements in the crypto_policy_t datatype.
- *
- * @warning This policy is NOT RECOMMENDED for SRTP unless there is a
- * requirement to forego encryption.  
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
  * @return void.
- * 
+ *
  */
-
-void
-crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p);
-
+void srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_aes_cm_256_hmac_sha1_80() sets a crypto
- * policy structure to a encryption and authentication policy using AES-256 
- * for RTP protection.
+ * @brief srtp_crypto_policy_set_aes_gcm_256_8_only_auth() sets a crypto
+ * policy structure to an AEAD authentication-only policy
+ *
+ * @param p is a pointer to the policy structure to be set
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_aes_cm_256_hmac_sha1_80(&p)
- * sets the crypto_policy_t at location p to use policy
- * AES_CM_256_HMAC_SHA1_80 as defined in
- * draft-ietf-avt-srtp-big-aes-03.txt.  This policy uses AES-256
- * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit
- * authentication tag.
- * 
+ * The function call srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-256 Galois Counter Mode) with 8 octet auth tag.  This policy
+ * applies confidentiality and authentication to the RTP packets,
+ * but only authentication to the RTCP packets.
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
- * include more elements in the crypto_policy_t datatype.
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
  * @return void.
- * 
+ *
  */
-
-void crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p);
-
+void srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p);
 
 /**
- * @brief crypto_policy_set_aes_cm_256_hmac_sha1_32() sets a crypto
- * policy structure to a short-authentication tag policy using AES-256
- * encryption.
+ * @brief srtp_crypto_policy_set_aes_gcm_128_16_auth() sets a crypto
+ * policy structure to an AEAD encryption policy.
+ *
+ * @param p is a pointer to the policy structure to be set
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_aes_cm_256_hmac_sha1_32(&p)
- * sets the crypto_policy_t at location p to use policy
- * AES_CM_256_HMAC_SHA1_32 as defined in
- * draft-ietf-avt-srtp-big-aes-03.txt.  This policy uses AES-256
- * Counter Mode encryption and HMAC-SHA1 authentication, with an
- * authentication tag that is only 32 bits long.  This length is
- * considered adequate only for protecting audio and video media that
- * use a stateless playback function.  See Section 7.5 of RFC 3711
- * (http://www.ietf.org/rfc/rfc3711.txt).
- * 
+ * The function call srtp_crypto_policy_set_aes_gcm_128_16_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-128 Galois Counter Mode) with 16 octet auth tag.  This
+ * policy applies confidentiality and authentication to both the
+ * RTP and RTCP packets.
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
- * include more elements in the crypto_policy_t datatype.
- *
- * @warning This crypto policy is intended for use in SRTP, but not in
- * SRTCP.  It is recommended that a policy that uses longer
- * authentication tags be used for SRTCP.  See Section 7.5 of RFC 3711
- * (http://www.ietf.org/rfc/rfc3711.txt).
+ * include more elements in the srtp_crypto_policy_t datatype.
  *
  * @return void.
- * 
+ *
  */
+void srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p);
 
-void
-crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p);
-
+/**
+ * @brief srtp_crypto_policy_set_aes_gcm_256_16_auth() sets a crypto
+ * policy structure to an AEAD encryption policy
+ *
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_aes_gcm_256_16_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (AES-256 Galois Counter Mode) with 16 octet auth tag.  This
+ * policy applies confidentiality and authentication to both the
+ * RTP and RTCP packets.
+ *
+ * This function is a convenience that helps to avoid dealing directly
+ * with the policy data structure.  You are encouraged to initialize
+ * policy elements with this function call.  Doing so may allow your
+ * code to be forward compatible with later versions of libSRTP that
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p);
 
 /**
  * @brief srtp_dealloc() deallocates storage for an SRTP session
  * context.
- * 
+ *
  * The function call srtp_dealloc(s) deallocates storage for the
  * SRTP session context s.  This function should be called no more
  * than one time for each of the contexts allocated by the function
  * srtp_create().
  *
  * @param s is the srtp_t for the session to be deallocated.
  *
  * @return
- *    - err_status_ok             if there no problems.
- *    - err_status_dealloc_fail   a memory deallocation failure occured.
+ *    - srtp_err_status_ok             if there no problems.
+ *    - srtp_err_status_dealloc_fail   a memory deallocation failure occured.
  */
-
-err_status_t
-srtp_dealloc(srtp_t s);
-
+srtp_err_status_t srtp_dealloc(srtp_t s);
 
 /*
- * @brief identifies a particular SRTP profile 
+ * @brief identifies a particular SRTP profile
  *
  * An srtp_profile_t enumeration is used to identify a particular SRTP
- * profile (that is, a set of algorithms and parameters).  These
- * profiles are defined in the DTLS-SRTP draft.
+ * profile (that is, a set of algorithms and parameters). These profiles
+ * are defined for DTLS-SRTP:
+ * https://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
  */
-
 typedef enum {
-  srtp_profile_reserved           = 0,
-  srtp_profile_aes128_cm_sha1_80  = 1,
-  srtp_profile_aes128_cm_sha1_32  = 2,
-  srtp_profile_aes256_cm_sha1_80  = 3,
-  srtp_profile_aes256_cm_sha1_32  = 4,
-  srtp_profile_null_sha1_80       = 5,
-  srtp_profile_null_sha1_32       = 6,
+    srtp_profile_reserved = 0,
+    srtp_profile_aes128_cm_sha1_80 = 1,
+    srtp_profile_aes128_cm_sha1_32 = 2,
+    srtp_profile_null_sha1_80 = 5,
+    srtp_profile_null_sha1_32 = 6,
+    srtp_profile_aead_aes_128_gcm = 7,
+    srtp_profile_aead_aes_256_gcm = 8,
 } srtp_profile_t;
 
-
 /**
- * @brief crypto_policy_set_from_profile_for_rtp() sets a crypto policy
+ * @brief srtp_crypto_policy_set_from_profile_for_rtp() sets a crypto policy
  * structure to the appropriate value for RTP based on an srtp_profile_t
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_rtp_default(&policy, profile)
- * sets the crypto_policy_t at location policy to the policy for RTP
+ * @param policy is a pointer to the policy structure to be set
+ *
+ * @param profile is an enumeration for the policy to be set
+ *
+ * The function call srtp_crypto_policy_set_rtp_default(&policy, profile)
+ * sets the srtp_crypto_policy_t at location policy to the policy for RTP
  * protection, as defined by the srtp_profile_t profile.
- * 
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
- * include more elements in the crypto_policy_t datatype.
- * 
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
  * @return values
- *     - err_status_ok         no problems were encountered
- *     - err_status_bad_param  the profile is not supported 
- * 
+ *     - srtp_err_status_ok         no problems were encountered
+ *     - srtp_err_status_bad_param  the profile is not supported
+ *
  */
-err_status_t
-crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, 
-				       srtp_profile_t profile);
-
-
-
+srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
+    srtp_crypto_policy_t *policy,
+    srtp_profile_t profile);
 
 /**
- * @brief crypto_policy_set_from_profile_for_rtcp() sets a crypto policy
+ * @brief srtp_crypto_policy_set_from_profile_for_rtcp() sets a crypto policy
  * structure to the appropriate value for RTCP based on an srtp_profile_t
  *
- * @param p is a pointer to the policy structure to be set 
- * 
- * The function call crypto_policy_set_rtcp_default(&policy, profile)
- * sets the crypto_policy_t at location policy to the policy for RTCP
+ * @param policy is a pointer to the policy structure to be set
+ *
+ * @param profile is an enumeration for the policy to be set
+ *
+ * The function call srtp_crypto_policy_set_rtcp_default(&policy, profile)
+ * sets the srtp_crypto_policy_t at location policy to the policy for RTCP
  * protection, as defined by the srtp_profile_t profile.
- * 
+ *
  * This function is a convenience that helps to avoid dealing directly
  * with the policy data structure.  You are encouraged to initialize
  * policy elements with this function call.  Doing so may allow your
  * code to be forward compatible with later versions of libSRTP that
- * include more elements in the crypto_policy_t datatype.
- * 
+ * include more elements in the srtp_crypto_policy_t datatype.
+ *
  * @return values
- *     - err_status_ok         no problems were encountered
- *     - err_status_bad_param  the profile is not supported 
- * 
+ *     - srtp_err_status_ok         no problems were encountered
+ *     - srtp_err_status_bad_param  the profile is not supported
+ *
  */
-err_status_t
-crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, 
-				       srtp_profile_t profile);
+srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtcp(
+    srtp_crypto_policy_t *policy,
+    srtp_profile_t profile);
 
 /**
  * @brief returns the master key length for a given SRTP profile
  */
-unsigned int
-srtp_profile_get_master_key_length(srtp_profile_t profile);
-
+unsigned int srtp_profile_get_master_key_length(srtp_profile_t profile);
 
 /**
  * @brief returns the master salt length for a given SRTP profile
  */
-unsigned int
-srtp_profile_get_master_salt_length(srtp_profile_t profile);
+unsigned int srtp_profile_get_master_salt_length(srtp_profile_t profile);
 
 /**
  * @brief appends the salt to the key
  *
- * The function call append_salt_to_key(k, klen, s, slen) 
+ * The function call srtp_append_salt_to_key(k, klen, s, slen)
  * copies the string s to the location at klen bytes following
- * the location k.  
+ * the location k.
  *
  * @warning There must be at least bytes_in_salt + bytes_in_key bytes
  *          available at the location pointed to by key.
- * 
+ *
  */
-
-void
-append_salt_to_key(unsigned char *key, unsigned int bytes_in_key,
-		   unsigned char *salt, unsigned int bytes_in_salt);
-
-
+void srtp_append_salt_to_key(unsigned char *key,
+                             unsigned int bytes_in_key,
+                             unsigned char *salt,
+                             unsigned int bytes_in_salt);
 
 /**
  * @}
  */
 
-
-
 /**
  * @defgroup SRTCP Secure RTCP
- * @ingroup  SRTP 
+ * @ingroup  SRTP
  *
  * @brief Secure RTCP functions are used to protect RTCP traffic.
  *
  * RTCP is the control protocol for RTP.  libSRTP protects RTCP
  * traffic in much the same way as it does RTP traffic.  The function
  * srtp_protect_rtcp() applies cryptographic protections to outbound
  * RTCP packets, and srtp_unprotect_rtcp() verifies the protections on
- * inbound RTCP packets.  
+ * inbound RTCP packets.
  *
  * A note on the naming convention: srtp_protect_rtcp() has an srtp_t
  * as its first argument, and thus has `srtp_' as its prefix.  The
- * trailing `_rtcp' indicates the protocol on which it acts.  
- * 
+ * trailing `_rtcp' indicates the protocol on which it acts.
+ *
  * @{
  */
 
 /**
  * @brief srtp_protect_rtcp() is the Secure RTCP sender-side packet
  * processing function.
- * 
+ *
  * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies
  * SRTCP protection to the RTCP packet rtcp_hdr (which has length
- * *len_ptr) using the SRTP session context ctx.  If err_status_ok is
+ * *len_ptr) using the SRTP session context ctx.  If srtp_err_status_ok is
  * returned, then rtp_hdr points to the resulting SRTCP packet and
  * *len_ptr is the number of octets in that packet; otherwise, no
  * assumptions should be made about the value of either data elements.
- * 
+ *
  * @warning This function assumes that it can write the authentication
  * tag into the location in memory immediately following the RTCP
  * packet, and assumes that the RTCP packet is aligned on a 32-bit
  * boundary.
  *
+ * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4
+ * into the location in memory immediately following the RTCP packet.
+ * Callers MUST ensure that this much writable memory is available in
+ * the buffer that holds the RTCP packet.
+ *
  * @param ctx is the SRTP context to use in processing the packet.
  *
  * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after
  * the function returns, it points to the srtp packet.
  *
  * @param pkt_octet_len is a pointer to the length in octets of the
  * complete RTCP packet (header and body) before the function call,
- * and of the complete SRTCP packet after the call, if err_status_ok
+ * and of the complete SRTCP packet after the call, if srtp_err_status_ok
  * was returned.  Otherwise, the value of the data to which it points
  * is undefined.
  *
- * @return 
- *    - err_status_ok            if there were no problems.
- *    - [other]                  if there was a failure in 
+ * @return
+ *    - srtp_err_status_ok            if there were no problems.
+ *    - [other]                  if there was a failure in
  *                               the cryptographic mechanisms.
  */
-	     
+srtp_err_status_t srtp_protect_rtcp(srtp_t ctx,
+                                    void *rtcp_hdr,
+                                    int *pkt_octet_len);
 
-err_status_t 
-srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len);
+/**
+ * @brief srtp_protect_rtcp_mki() is the Secure RTCP sender-side packet
+ * processing function that can utilize mki.
+ *
+ * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies
+ * SRTCP protection to the RTCP packet rtcp_hdr (which has length
+ * *len_ptr) using the SRTP session context ctx.  If srtp_err_status_ok is
+ * returned, then rtp_hdr points to the resulting SRTCP packet and
+ * *len_ptr is the number of octets in that packet; otherwise, no
+ * assumptions should be made about the value of either data elements.
+ *
+ * @warning This function assumes that it can write the authentication
+ * tag into the location in memory immediately following the RTCP
+ * packet, and assumes that the RTCP packet is aligned on a 32-bit
+ * boundary.
+ *
+ * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4
+ * into the location in memory immediately following the RTCP packet.
+ * Callers MUST ensure that this much writable memory is available in
+ * the buffer that holds the RTCP packet.
+ *
+ * @param ctx is the SRTP context to use in processing the packet.
+ *
+ * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after
+ * the function returns, it points to the srtp packet.
+ *
+ * @param pkt_octet_len is a pointer to the length in octets of the
+ * complete RTCP packet (header and body) before the function call,
+ * and of the complete SRTCP packet after the call, if srtp_err_status_ok
+ * was returned.  Otherwise, the value of the data to which it points
+ * is undefined.
+ *
+ * @param use_mki is a boolean to tell the system if mki is being used.  If
+ * set to false then will use the first set of session keys.  If set to true
+ * will
+ * use the session keys identified by the mki_index
+ *
+ * @param mki_index integer value specifying which set of session kesy should be
+ * used if use_mki is set to true.
+ *
+ * @return
+ *    - srtp_err_status_ok            if there were no problems.
+ *    - [other]                  if there was a failure in
+ *                               the cryptographic mechanisms.
+ */
+srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
+                                        void *rtcp_hdr,
+                                        int *pkt_octet_len,
+                                        unsigned int use_mki,
+                                        unsigned int mki_index);
 
 /**
  * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet
  * processing function.
  *
  * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr)
  * verifies the Secure RTCP protection of the SRTCP packet pointed to
  * by srtcp_hdr (which has length *len_ptr), using the SRTP session
- * context ctx.  If err_status_ok is returned, then srtcp_hdr points
+ * context ctx.  If srtp_err_status_ok is returned, then srtcp_hdr points
  * to the resulting RTCP packet and *len_ptr is the number of octets
  * in that packet; otherwise, no assumptions should be made about the
  * value of either data elements.
- * 
+ *
+ * @warning This function assumes that the SRTCP packet is aligned on a
+ * 32-bit boundary.
+ *
+ * @param ctx is a pointer to the srtp_t which applies to the
+ * particular packet.
+ *
+ * @param srtcp_hdr is a pointer to the header of the SRTCP packet
+ * (before the call).  After the function returns, it points to the
+ * rtp packet if srtp_err_status_ok was returned; otherwise, the value of
+ * the data to which it points is undefined.
+ *
+ * @param pkt_octet_len is a pointer to the length in octets of the
+ * complete SRTCP packet (header and body) before the function call,
+ * and of the complete rtp packet after the call, if srtp_err_status_ok was
+ * returned.  Otherwise, the value of the data to which it points is
+ * undefined.
+ *
+ * @return
+ *    - srtp_err_status_ok          if the RTCP packet is valid.
+ *    - srtp_err_status_auth_fail   if the SRTCP packet failed the message
+ *                             authentication check.
+ *    - srtp_err_status_replay_fail if the SRTCP packet is a replay (e.g. has
+ *                             already been processed and accepted).
+ *    - [other]  if there has been an error in the cryptographic mechanisms.
+ *
+ */
+srtp_err_status_t srtp_unprotect_rtcp(srtp_t ctx,
+                                      void *srtcp_hdr,
+                                      int *pkt_octet_len);
+
+/**
+ * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet
+ * processing function.
+ *
+ * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr)
+ * verifies the Secure RTCP protection of the SRTCP packet pointed to
+ * by srtcp_hdr (which has length *len_ptr), using the SRTP session
+ * context ctx.  If srtp_err_status_ok is returned, then srtcp_hdr points
+ * to the resulting RTCP packet and *len_ptr is the number of octets
+ * in that packet; otherwise, no assumptions should be made about the
+ * value of either data elements.
+ *
  * @warning This function assumes that the SRTCP packet is aligned on a
  * 32-bit boundary.
  *
  * @param ctx is a pointer to the srtp_t which applies to the
  * particular packet.
  *
  * @param srtcp_hdr is a pointer to the header of the SRTCP packet
  * (before the call).  After the function returns, it points to the
- * rtp packet if err_status_ok was returned; otherwise, the value of
+ * rtp packet if srtp_err_status_ok was returned; otherwise, the value of
  * the data to which it points is undefined.
  *
  * @param pkt_octet_len is a pointer to the length in octets of the
  * complete SRTCP packet (header and body) before the function call,
- * and of the complete rtp packet after the call, if err_status_ok was
+ * and of the complete rtp packet after the call, if srtp_err_status_ok was
  * returned.  Otherwise, the value of the data to which it points is
  * undefined.
  *
- * @return 
- *    - err_status_ok          if the RTCP packet is valid.
- *    - err_status_auth_fail   if the SRTCP packet failed the message 
- *                             authentication check.
- *    - err_status_replay_fail if the SRTCP packet is a replay (e.g. has
- *                             already been processed and accepted).
- *    - [other]  if there has been an error in the cryptographic mechanisms.
+ * @param use_mki is a boolean to tell the system if mki is being used.  If
+ * set to false then will use the first set of session keys.  If set to true
+ * will use the session keys identified by the mki_index
+ *
+ * @return
+ *    - srtp_err_status_ok          if the RTCP packet is valid.
+ *    - srtp_err_status_auth_fail   if the SRTCP packet failed the message
+ *                                  authentication check.
+ *    - srtp_err_status_replay_fail if the SRTCP packet is a replay (e.g. has
+ *                                  already been processed and accepted).
+ *    - srtp_err_status_bad_mki     if the MKI in the packet is not a known MKI
+ *                                  id
+ *    - [other]                     if there has been an error in the
+ *                                  cryptographic mechanisms.
  *
  */
+srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
+                                          void *srtcp_hdr,
+                                          int *pkt_octet_len,
+                                          unsigned int use_mki);
 
-err_status_t 
-srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup User data associated to a SRTP session.
+ * @ingroup  SRTP
+ *
+ * @brief Store custom user data within a SRTP session.
+ *
+ * @{
+ */
+
+/**
+ * @brief srtp_set_user_data() stores the given pointer into the SRTP
+ * session for later retrieval.
+ *
+ * @param ctx is the srtp_t context in which the given data pointer is
+ * stored.
+ *
+ * @param data is a pointer to the custom information (struct, function,
+ * etc) associated with the SRTP session.
+ *
+ * @return void.
+ *
+ */
+void srtp_set_user_data(srtp_t ctx, void *data);
+
+/**
+ * @brief srtp_get_user_data() retrieves the pointer to the custom data
+ * previously stored with srtp_set_user_data().
+ *
+ * This function is mostly useful for retrieving data associated to a
+ * SRTP session when an event fires. The user can then get such a custom
+ * data by calling this function with the session field of the
+ * srtp_event_data_t struct as argument.
+ *
+ * @param ctx is the srtp_t context in which the given data pointer was
+ * stored.
+ *
+ * @return void* pointer to the user data.
+ *
+ */
+void *srtp_get_user_data(srtp_t ctx);
 
 /**
  * @}
  */
 
 /**
  * @defgroup SRTPevents SRTP events and callbacks
  * @ingroup  SRTP
  *
- * @brief libSRTP can use a user-provided callback function to 
+ * @brief libSRTP can use a user-provided callback function to
  * handle events.
  *
- * 
+ *
  * libSRTP allows a user to provide a callback function to handle
  * events that need to be dealt with outside of the data plane (see
  * the enum srtp_event_t for a description of these events).  Dealing
  * with these events is not a strict necessity; they are not
  * security-critical, but the application may suffer if they are not
  * handled.  The function srtp_set_event_handler() is used to provide
  * the callback function.
  *
@@ -913,94 +1541,219 @@ srtp_unprotect_rtcp(srtp_t ctx, void *sr
  *
  * @{
  */
 
 /**
  * @brief srtp_event_t defines events that need to be handled
  *
  * The enum srtp_event_t defines events that need to be handled
- * outside the `data plane', such as SSRC collisions and 
- * key expirations.  
+ * outside the `data plane', such as SSRC collisions and
+ * key expirations.
  *
  * When a key expires or the maximum number of packets has been
  * reached, an SRTP stream will enter an `expired' state in which no
  * more packets can be protected or unprotected.  When this happens,
  * it is likely that you will want to either deallocate the stream
- * (using srtp_stream_dealloc()), and possibly allocate a new one.
+ * (using srtp_remove_stream()), and possibly allocate a new one.
  *
  * When an SRTP stream expires, the other streams in the same session
  * are unaffected, unless key sharing is used by that stream.  In the
  * latter case, all of the streams in the session will expire.
  */
-
-typedef enum { 
-  event_ssrc_collision,    /**<
-			    * An SSRC collision occured.             
-			    */
-  event_key_soft_limit,    /**< An SRTP stream reached the soft key
-			    *   usage limit and will expire soon.	   
-			    */
-  event_key_hard_limit,    /**< An SRTP stream reached the hard 
-			    *   key usage limit and has expired.
-			    */
-  event_packet_index_limit /**< An SRTP stream reached the hard 
-			    * packet limit (2^48 packets).             
-			    */
+typedef enum {
+    event_ssrc_collision,    /**< An SSRC collision occured.            */
+    event_key_soft_limit,    /**< An SRTP stream reached the soft key   */
+                             /**< usage limit and will expire soon.     */
+    event_key_hard_limit,    /**< An SRTP stream reached the hard       */
+                             /**< key usage limit and has expired.      */
+    event_packet_index_limit /**< An SRTP stream reached the hard       */
+                             /**< packet limit (2^48 packets).          */
 } srtp_event_t;
 
 /**
- * @brief srtp_event_data_t is the structure passed as a callback to 
+ * @brief srtp_event_data_t is the structure passed as a callback to
  * the event handler function
  *
  * The struct srtp_event_data_t holds the data passed to the event
- * handler function.  
+ * handler function.
  */
-
 typedef struct srtp_event_data_t {
-  srtp_t        session;  /**< The session in which the event happend. */
-  srtp_stream_t stream;   /**< The stream in which the event happend.  */
-  srtp_event_t  event;    /**< An enum indicating the type of event.   */
+    srtp_t session;     /**< The session in which the event happend.        */
+    uint32_t ssrc;      /**< The ssrc in host order of the stream in which  */
+                        /**< the event happend                              */
+    srtp_event_t event; /**< An enum indicating the type of event.          */
 } srtp_event_data_t;
 
 /**
  * @brief srtp_event_handler_func_t is the function prototype for
  * the event handler.
  *
  * The typedef srtp_event_handler_func_t is the prototype for the
  * event handler function.  It has as its only argument an
  * srtp_event_data_t which describes the event that needs to be handled.
  * There can only be a single, global handler for all events in
  * libSRTP.
  */
-
-typedef void (srtp_event_handler_func_t)(srtp_event_data_t *data);
+typedef void(srtp_event_handler_func_t)(srtp_event_data_t *data);
 
 /**
  * @brief sets the event handler to the function supplied by the caller.
- * 
+ *
  * The function call srtp_install_event_handler(func) sets the event
  * handler function to the value func.  The value NULL is acceptable
  * as an argument; in this case, events will be ignored rather than
  * handled.
  *
  * @param func is a pointer to a fuction that takes an srtp_event_data_t
  *             pointer as an argument and returns void.  This function
  *             will be used by libSRTP to handle events.
  */
+srtp_err_status_t srtp_install_event_handler(srtp_event_handler_func_t func);
 
-err_status_t
-srtp_install_event_handler(srtp_event_handler_func_t func);
+/**
+ * @brief Returns the version string of the library.
+ *
+ */
+const char *srtp_get_version_string(void);
+
+/**
+ * @brief Returns the numeric representation of the library version.
+ *
+ */
+unsigned int srtp_get_version(void);
+
+/**
+ * @brief srtp_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
+ */
+srtp_err_status_t srtp_set_debug_module(const char *mod_name, int v);
+
+/**
+ * @brief srtp_list_debug_modules() outputs a list of debugging modules
+ *
+ */
+srtp_err_status_t srtp_list_debug_modules(void);
+
+/**
+ * @brief srtp_log_level_t defines log levels.
+ *
+ * The enumeration srtp_log_level_t defines log levels reported
+ * in the srtp_log_handler_func_t.
+ *
+ */
+typedef enum {
+    srtp_log_level_error,   /**< log level is reporting an error message  */
+    srtp_log_level_warning, /**< log level is reporting a warning message */
+    srtp_log_level_info,    /**< log level is reporting an info message   */
+    srtp_log_level_debug    /**< log level is reporting a debug message   */
+} srtp_log_level_t;
+
+/**
+ * @brief srtp_log_handler_func_t is the function prototype for
+ * the log handler.
+ *
+ * The typedef srtp_event_handler_func_t is the prototype for the
+ * event handler function.  It has as srtp_log_level_t, log
+ * message and data as arguments.
+ * There can only be a single, global handler for all log messages in
+ * libSRTP.
+ */
+typedef void(srtp_log_handler_func_t)(srtp_log_level_t level,
+                                      const char *msg,
+                                      void *data);
+
+/**
+ * @brief sets the log handler to the function supplied by the caller.
+ *
+ * The function call srtp_install_log_handler(func) sets the log
+ * handler function to the value func.  The value NULL is acceptable
+ * as an argument; in this case, log messages will be ignored.
+ * This function can be called before srtp_init() inorder to capture
+ * any logging during start up.
+ *
+ * @param func is a pointer to a fuction of type srtp_log_handler_func_t.
+ *             This function will be used by libSRTP to output log messages.
+ * @param data is a user pointer that will be returned as the data argument in
+ * func.
+ */
+srtp_err_status_t srtp_install_log_handler(srtp_log_handler_func_t func,
+                                           void *data);
+
+/**
+ * @brief srtp_get_protect_trailer_length(session, use_mki, mki_index, length)
+ *
+ * Determines the length of the amount of data Lib SRTP will add to the
+ * packet during the protect process. The length is returned in the length
+ * parameter
+ *
+ * returns err_status_ok on success, err_status_bad_mki if the MKI index is
+ * invalid
+ *
+ */
+srtp_err_status_t srtp_get_protect_trailer_length(srtp_t session,
+                                                  uint32_t use_mki,
+                                                  uint32_t mki_index,
+                                                  uint32_t *length);
+
+/**
+ * @brief srtp_get_protect_rtcp_trailer_length(session, use_mki, mki_index,
+ * length)
+ *
+ * Determines the length of the amount of data Lib SRTP will add to the
+ * packet during the protect process. The length is returned in the length
+ * parameter
+ *
+ * returns err_status_ok on success, err_status_bad_mki if the MKI index is
+ * invalid
+ *
+ */
+srtp_err_status_t srtp_get_protect_rtcp_trailer_length(srtp_t session,
+                                                       uint32_t use_mki,
+                                                       uint32_t mki_index,
+                                                       uint32_t *length);
+
+/**
+ * @brief srtp_set_stream_roc(session, ssrc, roc)
+ *
+ * Set the roll-over-counter on a session for a given SSRC
+ *
+ * returns err_status_ok on success, srtp_err_status_bad_param if there is no
+ * stream found
+ *
+ */
+srtp_err_status_t srtp_set_stream_roc(srtp_t session,
+                                      uint32_t ssrc,
+                                      uint32_t roc);
+
+/**
+ * @brief srtp_get_stream_roc(session, ssrc, roc)
+ *
+ * Get the roll-over-counter on a session for a given SSRC
+ *
+ * returns err_status_ok on success, srtp_err_status_bad_param if there is no
+ * stream found
+ *
+ */
+srtp_err_status_t srtp_get_stream_roc(srtp_t session,
+                                      uint32_t ssrc,
+                                      uint32_t *roc);
 
 /**
  * @}
  */
+
 /* in host order, so outside the #if */
-#define SRTCP_E_BIT      0x80000000
+#define SRTCP_E_BIT 0x80000000
+
 /* for byte-access */
 #define SRTCP_E_BYTE_BIT 0x80
 #define SRTCP_INDEX_MASK 0x7fffffff
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* SRTP_H */
+#endif /* SRTP_SRTP_H */
--- a/netwerk/srtp/src/include/srtp_priv.h
+++ b/netwerk/srtp/src/include/srtp_priv.h
@@ -2,36 +2,36 @@
  * srtp_priv.h
  *
  * private internal data structures and functions for libSRTP
  *
  * 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
  * 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)
@@ -40,217 +40,241 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
 #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"
+
+#ifdef __cplusplus
+extern "C" {
+#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
+ */
+
+/*
+ * 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_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);
+
+/*
+ * 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
+ */
+srtp_err_status_t srtp_stream_init(srtp_stream_t srtp, const srtp_policy_t *p);
 
 /*
- * an srtp_hdr_t represents the srtp header
+ * libsrtp internal datatypes
+ */
+typedef enum direction_t {
+    dir_unknown = 0,
+    dir_srtp_sender = 1,
+    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
  *
- * 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)
+ * note that the keys might not actually be unique, in which case the
+ * srtp_cipher_t and srtp_auth_t pointers will point to the same structures
  */
- 
-#ifndef WORDS_BIGENDIAN
+typedef struct srtp_stream_ctx_t_ {
+    uint32_t ssrc;
+    srtp_session_keys_t *session_keys;
+    unsigned int num_master_keys;
+    srtp_rdbx_t rtp_rdbx;
+    srtp_sec_serv_t rtp_services;
+    srtp_rdb_t rtcp_rdb;
+    srtp_sec_serv_t rtcp_services;
+    direction_t direction;
+    int allow_repeat_tx;
+    srtp_ekt_stream_t ekt;
+    int *enc_xtn_hdr;
+    int enc_xtn_hdr_count;
+    uint32_t pending_roc;
+    struct srtp_stream_ctx_t_ *next; /* linked list of streams */
+} strp_stream_ctx_t_;
+
+/*
+ * an srtp_ctx_t holds a stream list and a service description
+ */
+typedef struct srtp_ctx_t_ {
+    struct srtp_stream_ctx_t_ *stream_list;     /* linked list of streams     */
+    struct srtp_stream_ctx_t_ *stream_template; /* act as template for other  */
+                                                /* streams                    */
+    void *user_data;                            /* user custom data           */
+} 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 
+ * 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)
  */
 
+#ifndef WORDS_BIGENDIAN
+
 typedef struct {
-  unsigned char cc:4;	/* CSRC count             */
-  unsigned char x:1;	/* header extension flag  */
-  unsigned char p:1;	/* padding flag           */
-  unsigned char version:2; /* protocol version    */
-  unsigned char pt:7;	/* payload type           */
-  unsigned char m:1;	/* marker bit             */
-  uint16_t seq;		/* sequence number        */
-  uint32_t ts;		/* timestamp              */
-  uint32_t ssrc;	/* synchronization source */
+    unsigned char cc : 4;      /* CSRC count             */
+    unsigned char x : 1;       /* header extension flag  */
+    unsigned char p : 1;       /* padding flag           */
+    unsigned char version : 2; /* protocol version       */
+    unsigned char pt : 7;      /* payload type           */
+    unsigned char m : 1;       /* marker bit             */
+    uint16_t seq;              /* sequence number        */
+    uint32_t ts;               /* timestamp              */
+    uint32_t ssrc;             /* synchronization source */
 } srtp_hdr_t;
 
 #else /*  BIG_ENDIAN */
 
 typedef struct {
-  unsigned char version:2; /* protocol version    */
-  unsigned char p:1;	/* padding flag           */
-  unsigned char x:1;	/* header extension flag  */
-  unsigned char cc:4;	/* CSRC count             */
-  unsigned char m:1;	/* marker bit             */
-  unsigned pt:7;	/* payload type           */
-  uint16_t seq;		/* sequence number        */
-  uint32_t ts;		/* timestamp              */
-  uint32_t ssrc;	/* synchronization source */
+    unsigned char version : 2; /* protocol version       */
+    unsigned char p : 1;       /* padding flag           */
+    unsigned char x : 1;       /* header extension flag  */
+    unsigned char cc : 4;      /* CSRC count             */
+    unsigned char m : 1;       /* marker bit             */
+    unsigned char pt : 7;      /* payload type           */
+    uint16_t seq;              /* sequence number        */
+    uint32_t ts;               /* timestamp              */
+    uint32_t ssrc;             /* synchronization source */
 } srtp_hdr_t;
 
 #endif
 
 typedef struct {
-  uint16_t profile_specific;    /* profile-specific info               */
-  uint16_t length;              /* number of 32-bit words in extension */
+    uint16_t profile_specific; /* profile-specific info               */
+    uint16_t length;           /* number of 32-bit words in extension */
 } srtp_hdr_xtnd_t;
 
-
 /*
- * srtcp_hdr_t represents a secure rtcp header 
+ * 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 char rc:5;		/* reception report count */
-  unsigned char p:1;		/* padding flag           */
-  unsigned char version:2;	/* protocol version       */
-  unsigned char pt:8;		/* payload type           */
-  uint16_t len;			/* length                 */
-  uint32_t ssrc;	       	/* synchronization source */
+    unsigned char rc : 5;      /* reception report count */
+    unsigned char p : 1;       /* padding flag           */
+    unsigned char version : 2; /* protocol version       */
+    unsigned char pt : 8;      /* payload type           */
+    uint16_t len;              /* length                 */
+    uint32_t ssrc;             /* synchronization source */
 } srtcp_hdr_t;
 
 typedef struct {
-  unsigned int index:31;    /* srtcp packet index in network order! */
-  unsigned int e:1;         /* encrypted? 1=yes */
-  /* optional mikey/etc go here */
-  /* and then the variable-length auth tag */
+    unsigned int index : 31; /* srtcp packet index in network order!  */
+    unsigned int e : 1;      /* encrypted? 1=yes                      */
+                             /* optional mikey/etc go here            */
+                             /* and then the variable-length auth tag */
 } srtcp_trailer_t;
 
-
 #else /*  BIG_ENDIAN */
 
 typedef struct {
-  unsigned char version:2;	/* protocol version       */
-  unsigned char p:1;		/* padding flag           */
-  unsigned char rc:5;		/* reception report count */
-  unsigned char pt:8;		/* payload type           */
-  uint16_t len;			/* length                 */
-  uint32_t ssrc;	       	/* synchronization source */
+    unsigned char version : 2; /* protocol version       */
+    unsigned char p : 1;       /* padding flag           */
+    unsigned char rc : 5;      /* reception report count */
+    unsigned char 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 */
+    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
 
-
-/*
- * the following declarations are libSRTP internal functions 
- */
-
-/*
- * 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_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.
- */
-
-
-err_status_t
-srtp_stream_init_keys(srtp_stream_t srtp, const void *key);
-
-/*
- * 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);
-
-
-/*
- * libsrtp internal datatypes 
- */
-
-typedef enum direction_t { 
-  dir_unknown       = 0,
-  dir_srtp_sender   = 1, 
-  dir_srtp_receiver = 2
-} direction_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
- */
-
-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;
-  direction_t direction;
-  int        allow_repeat_tx;
-  ekt_stream_t ekt; 
-  struct srtp_stream_ctx_t *next;   /* linked list of streams */
-} srtp_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;
-
-
-
 /*
  * srtp_handle_event(srtp, srtm, evnt) calls the event handling
  * function, if there is one.
  *
- * This macro is not included in the documentation as it is 
+ * This macro is not included in the documentation as it is
  * an internal-only function.
  */
 
-#define srtp_handle_event(srtp, strm, evnt)         \
-   if(srtp_event_handler) {                         \
-      srtp_event_data_t data;                       \
-      data.session = srtp;                          \
-      data.stream  = strm;                          \
-      data.event   = evnt;                          \
-      srtp_event_handler(&data);                    \
-}   
+#define srtp_handle_event(srtp, strm, evnt)                                    \
+    if (srtp_event_handler) {                                                  \
+        srtp_event_data_t data;                                                \
+        data.session = srtp;                                                   \
+        data.ssrc = ntohl(strm->ssrc);                                         \
+        data.event = evnt;                                                     \
+        srtp_event_handler(&data);                                             \
+    }
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* SRTP_PRIV_H */
--- a/netwerk/srtp/src/include/ut_sim.h
+++ b/netwerk/srtp/src/include/ut_sim.h
@@ -4,77 +4,80 @@
  * an unreliable transport simulator
  * (for testing replay databases and suchlike)
  *
  * 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
  * 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 UT_SIM_H
 #define UT_SIM_H
 
-#include "integers.h"  /* for uint32_t */
+#include "integers.h" /* for uint32_t */
 
-#define UT_BUF 160      /* maximum amount of packet reorder */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UT_BUF 160 /* maximum amount of packet reorder */
 
 typedef struct {
-  uint32_t index;
-  uint32_t buffer[UT_BUF];
+    uint32_t index;
+    uint32_t buffer[UT_BUF];
 } ut_connection;
 
 /*
- * ut_init(&u) initializes the ut_connection 
+ * ut_init(&u) initializes the ut_connection
  *
  * this function should always be the first one called on a new
  * ut_connection
  */
 
-void
-ut_init(ut_connection *utc);
+void ut_init(ut_connection *utc);
 
 /*
  * ut_next_index(&u) returns the next index from the simulated
  * unreliable connection
  */
 
-uint32_t
-ut_next_index(ut_connection *utc);
+uint32_t ut_next_index(ut_connection *utc);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* UT_SIM_H */
--- a/netwerk/srtp/src/srtp/ekt.c
+++ b/netwerk/srtp/src/srtp/ekt.c
@@ -1,276 +1,281 @@
 /*
  * ekt.c
  *
  * Encrypted Key Transport for SRTP
- * 
+ *
  * David 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
  * 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 "srtp_priv.h"
 #include "err.h"
-#include "srtp_priv.h"
 #include "ekt.h"
 
-extern debug_module_t mod_srtp;
+extern srtp_debug_module_t mod_srtp;
 
 /*
  *  The EKT Authentication Tag format.
  *
  *    0                   1                   2                   3
  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *   :                   Base Authentication Tag                     :
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *   :                     Encrypted Master Key                      :
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *   |                       Rollover Counter                        |
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *   |    Initial Sequence Number    |   Security Parameter Index    |
  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
- */			 
+ */
 
 #define EKT_OCTETS_AFTER_BASE_TAG 24
-#define EKT_OCTETS_AFTER_EMK       8
-#define EKT_OCTETS_AFTER_ROC       4
-#define EKT_SPI_LEN                2
+#define EKT_OCTETS_AFTER_EMK 8
+#define EKT_OCTETS_AFTER_ROC 4
+#define EKT_SPI_LEN 2
 
-unsigned
-ekt_octets_after_base_tag(ekt_stream_t ekt) {
-  /*
-   * if the pointer ekt is NULL, then EKT is not in effect, so we
-   * indicate this by returning zero
-   */
-  if (!ekt)
-    return 0;
+unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt)
+{
+    /*
+     * if the pointer ekt is NULL, then EKT is not in effect, so we
+     * indicate this by returning zero
+     */
+    if (!ekt)
+        return 0;
 
-  switch(ekt->data->ekt_cipher_type) {
-  case EKT_CIPHER_AES_128_ECB:
-    return 16 + EKT_OCTETS_AFTER_EMK;
-    break;
-  default:
-    break;
-  }
-  return 0;
+    switch (ekt->data->ekt_cipher_type) {
+    case SRTP_EKT_CIPHER_AES_128_ECB:
+        return 16 + EKT_OCTETS_AFTER_EMK;
+        break;
+    default:
+        break;
+    }
+    return 0;
 }
 
-static inline ekt_spi_t
-srtcp_packet_get_ekt_spi(const uint8_t *packet_start, unsigned pkt_octet_len) {
-  const uint8_t *spi_location;
-  
-  spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
-  
-  return *((const ekt_spi_t *)spi_location);
+static inline srtp_ekt_spi_t srtcp_packet_get_ekt_spi(
+    const uint8_t *packet_start,
+    unsigned pkt_octet_len)
+{
+    const uint8_t *spi_location;
+
+    spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
+
+    return *((const srtp_ekt_spi_t *)spi_location);
 }
 
-static inline uint32_t
-srtcp_packet_get_ekt_roc(const uint8_t *packet_start, unsigned pkt_octet_len) {
-  const uint8_t *roc_location;
-  
-  roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
-  
-  return *((const uint32_t *)roc_location);
+static inline uint32_t srtcp_packet_get_ekt_roc(const uint8_t *packet_start,
+                                                unsigned pkt_octet_len)
+{
+    const uint8_t *roc_location;
+
+    roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
+
+    return *((const uint32_t *)roc_location);
 }
 
-static inline const uint8_t *
-srtcp_packet_get_emk_location(const uint8_t *packet_start, 
-			      unsigned pkt_octet_len) {
-  const uint8_t *location;
-  
-  location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
+static inline const uint8_t *srtcp_packet_get_emk_location(
+    const uint8_t *packet_start,
+    unsigned pkt_octet_len)
+{
+    const uint8_t *location;
 
-  return location;
+    location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
+
+    return location;
 }
 
-
-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)
+{
+    /*
+     * if the policy pointer is NULL, then EKT is not in use
+     * so we just set the EKT stream data pointer to NULL
+     */
+    if (!policy) {
+        *stream_data = NULL;
+        return srtp_err_status_ok;
+    }
 
-  /*
-   * if the policy pointer is NULL, then EKT is not in use
-   * so we just set the EKT stream data pointer to NULL
-   */
-  if (!policy) {
+    /* TODO */
     *stream_data = NULL;
-    return err_status_ok;
-  }
 
-  /* TODO */
-  *stream_data = NULL;
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-ekt_stream_init_from_policy(ekt_stream_t stream_data, ekt_policy_t policy) {
-  if (!stream_data)
-    return err_status_ok;
+srtp_err_status_t srtp_ekt_stream_init_from_policy(
+    srtp_ekt_stream_t stream_data,
+    srtp_ekt_policy_t policy)
+{
+    if (!stream_data)
+        return srtp_err_status_ok;
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
+void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len)
+{
+#ifndef OPENSSL
+    // FIXME: need to get this working through the crypto module interface
+    srtp_aes_expanded_key_t expanded_key;
 
-void
-aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len) {
-  aes_expanded_key_t expanded_key;
-
-  aes_expand_decryption_key(key, key_len, &expanded_key);
-  aes_decrypt(ciphertext, &expanded_key);
+    srtp_aes_expand_decryption_key(key, key_len, &expanded_key);
+    srtp_aes_decrypt(ciphertext, &expanded_key);
+#endif
 }
 
 /*
  * The function srtp_stream_init_from_ekt() initializes a stream using
- * the EKT data from an SRTCP trailer.  
+ * the EKT data from an SRTCP trailer.
  */
 
-err_status_t
-srtp_stream_init_from_ekt(srtp_stream_t stream,			  
-			  const void *srtcp_hdr,
-			  unsigned pkt_octet_len) {
-  err_status_t err;
-  const uint8_t *master_key;
-  srtp_policy_t srtp_policy;
-  uint32_t roc;
+srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
+                                            const void *srtcp_hdr,
+                                            unsigned pkt_octet_len)
+{
+    srtp_err_status_t err;
+    const uint8_t *master_key;
+    srtp_policy_t srtp_policy;
+    uint32_t roc;
 
-  /*
-   * NOTE: at present, we only support a single ekt_policy at a time.  
-   */
-  if (stream->ekt->data->spi != 
-      srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
-    return err_status_no_ctx;
+    /*
+     * NOTE: at present, we only support a single ekt_policy at a time.
+     */
+    if (stream->ekt->data->spi !=
+        srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
+        return srtp_err_status_no_ctx;
+
+    if (stream->ekt->data->ekt_cipher_type != SRTP_EKT_CIPHER_AES_128_ECB)
+        return srtp_err_status_bad_param;
 
-  if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB)
-    return err_status_bad_param;
-
-  /* decrypt the Encrypted Master Key field */
-  master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
-  /* FIX!? This decrypts the master key in-place, and never uses it */
-  /* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
-   * to a function which expects a raw (unexpanded) key */
-  aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16);
+    /* decrypt the Encrypted Master Key field */
+    master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
+    /* FIX!? This decrypts the master key in-place, and never uses it */
+    /* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
+     * to a function which expects a raw (unexpanded) key */
+    aes_decrypt_with_raw_key((void *)master_key,
+                             &stream->ekt->data->ekt_dec_key, 16);
 
-  /* set the SRTP ROC */
-  roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
-  err = rdbx_set_roc(&stream->rtp_rdbx, roc);
-  if (err) return err;
+    /* set the SRTP ROC */
+    roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
+    err = srtp_rdbx_set_roc(&stream->rtp_rdbx, roc);
+    if (err)
+        return err;
 
-  err = srtp_stream_init(stream, &srtp_policy);
-  if (err) return err;
+    err = srtp_stream_init(stream, &srtp_policy);
+    if (err)
+        return err;
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-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) {
-  uint32_t roc;
-  uint16_t isn;
-  unsigned emk_len;
-  uint8_t *packet;
+void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
+                         uint8_t *base_tag,
+                         unsigned base_tag_len,
+                         int *packet_len,
+                         srtp_xtd_seq_num_t pkt_index)
+{
+    uint32_t roc;
+    uint16_t isn;
+    unsigned emk_len;
+    uint8_t *packet;
 
-  /* if the pointer ekt is NULL, then EKT is not in effect */
-  if (!ekt) {
-    debug_print(mod_srtp, "EKT not in use", NULL);
-    return;
-  }
+    /* if the pointer ekt is NULL, then EKT is not in effect */
+    if (!ekt) {
+        debug_print(mod_srtp, "EKT not in use", NULL);
+        return;
+    }
 
-  /* write zeros into the location of the base tag */
-  octet_string_set_to_zero(base_tag, base_tag_len);
-  packet = base_tag + base_tag_len;
+    /* write zeros into the location of the base tag */
+    octet_string_set_to_zero(base_tag, base_tag_len);
+    packet = base_tag + base_tag_len;
 
-  /* copy encrypted master key into packet */
-  emk_len = ekt_octets_after_base_tag(ekt);
-  memcpy(packet, ekt->encrypted_master_key, emk_len);
-  debug_print(mod_srtp, "writing EKT EMK: %s,", 
-	      octet_string_hex_string(packet, emk_len));
-  packet += emk_len;
+    /* copy encrypted master key into packet */
+    emk_len = srtp_ekt_octets_after_base_tag(ekt);
+    memcpy(packet, ekt->encrypted_master_key, emk_len);
+    debug_print(mod_srtp, "writing EKT EMK: %s,",
+                srtp_octet_string_hex_string(packet, emk_len));
+    packet += emk_len;
 
-  /* copy ROC into packet */
-  roc = (uint32_t)(pkt_index >> 16);
-  *((uint32_t *)packet) = be32_to_cpu(roc);
-  debug_print(mod_srtp, "writing EKT ROC: %s,", 
-	      octet_string_hex_string(packet, sizeof(roc)));
-  packet += sizeof(roc);
+    /* copy ROC into packet */
+    roc = (uint32_t)(pkt_index >> 16);
+    *((uint32_t *)packet) = be32_to_cpu(roc);
+    debug_print(mod_srtp, "writing EKT ROC: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(roc)));
+    packet += sizeof(roc);
 
-  /* copy ISN into packet */
-  isn = (uint16_t)pkt_index;
-  *((uint16_t *)packet) = htons(isn);
-  debug_print(mod_srtp, "writing EKT ISN: %s,", 
-	      octet_string_hex_string(packet, sizeof(isn)));
-  packet += sizeof(isn);
+    /* copy ISN into packet */
+    isn = (uint16_t)pkt_index;
+    *((uint16_t *)packet) = htons(isn);
+    debug_print(mod_srtp, "writing EKT ISN: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(isn)));
+    packet += sizeof(isn);
 
-  /* copy SPI into packet */
-  *((uint16_t *)packet) = htons(ekt->data->spi);
-  debug_print(mod_srtp, "writing EKT SPI: %s,", 
-	      octet_string_hex_string(packet, sizeof(ekt->data->spi)));
+    /* copy SPI into packet */
+    *((uint16_t *)packet) = htons(ekt->data->spi);
+    debug_print(mod_srtp, "writing EKT SPI: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(ekt->data->spi)));
 
-  /* increase packet length appropriately */
-  *packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
+    /* increase packet length appropriately */
+    *packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
 }
 
-
 /*
  * The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag   )
- * 
+ *
  * If the pointer ekt is NULL, then the other inputs are unaffected.
  *
  * auth_tag is a pointer to the pointer to the location of the
  * authentication tag in the packet.  If EKT is in effect, then the
- * auth_tag pointer is set to the location 
+ * auth_tag pointer is set to the location
  */
 
-void
-srtcp_ekt_trailer(ekt_stream_t ekt,
-		  unsigned *auth_len,
-		  void **auth_tag,
-		  void *tag_copy) {
-  
-  /* 
-   * if there is no EKT policy, then the other inputs are unaffected
-   */
-  if (!ekt) 
-    return;
-      
-  /* copy auth_tag into temporary location */
-  
+void srtcp_ekt_trailer(srtp_ekt_stream_t ekt,
+                       unsigned *auth_len,
+                       void **auth_tag,
+                       void *tag_copy)
+{
+    /*
+     * if there is no EKT policy, then the other inputs are unaffected
+     */
+    if (!ekt)
+        return;
+
+    /* copy auth_tag into temporary location */
 }
-
--- a/netwerk/srtp/src/srtp/srtp.c
+++ b/netwerk/srtp/src/srtp/srtp.c
@@ -2,2166 +2,4760 @@
  * srtp.c
  *
  * the secure real-time transport protocol
  *
  * 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
  * 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 "srtp.h"
-#include "ekt.h"             /* for SRTP Encrypted Key Transport */
-#include "alloc.h"           /* for crypto_alloc()          */
-
-#ifndef SRTP_KERNEL
-# include <limits.h>
-# ifdef HAVE_NETINET_IN_H
-#  include <netinet/in.h>
-# elif defined(HAVE_WINSOCK2_H)
-#  include <winsock2.h>
-# endif
-#endif /* ! SRTP_KERNEL */
-
+// Leave this as the top level import. Ensures the existence of defines
+#include "config.h"
+
+#include "srtp_priv.h"
+#include "crypto_types.h"
+#include "err.h"
+#include "ekt.h"   /* for SRTP Encrypted Key Transport */
+#include "alloc.h" /* for srtp_crypto_alloc() */
+
+#ifdef OPENSSL
+#include "aes_gcm_ossl.h" /* for AES GCM mode */
+#ifdef OPENSSL_KDF
+#include <openssl/kdf.h>
+#include "aes_icm_ossl.h" /* for AES GCM mode */
+#endif
+#endif
+
+#include <limits.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined(HAVE_WINSOCK2_H)
+#include <winsock2.h>
+#endif
 
 /* the debug module for srtp */
-
-debug_module_t mod_srtp = {
-  0,                  /* debugging is off by default */
-  "srtp"              /* printable name for module   */
+srtp_debug_module_t mod_srtp = {
+    0,     /* debugging is off by default */
+    "srtp" /* printable name for module */
 };
 
-#define octets_in_rtp_header   12
-#define uint32s_in_rtp_header  3
-#define octets_in_rtcp_header  8
+#define octets_in_rtp_header 12
+#define uint32s_in_rtp_header 3
+#define octets_in_rtcp_header 8
 #define uint32s_in_rtcp_header 2
-
-
-err_status_t
-srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
-		  const srtp_policy_t *p) {
-  srtp_stream_ctx_t *str;
-  err_status_t stat;
-
-  /*
-   * This function allocates the stream context, rtp and rtcp ciphers
-   * and auth functions, and key limit structure.  If there is a
-   * failure during allocation, we free all previously allocated
-   * memory and return a failure code.  The code could probably 
-   * be improved, but it works and should be clear.
-   */
-
-  /* allocate srtp stream and set str_ptr */
-  str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
-  if (str == NULL)
-    return err_status_alloc_fail;
-  *str_ptr = str;  
-  
-  /* allocate cipher */
-  stat = crypto_kernel_alloc_cipher(p->rtp.cipher_type, 
-				    &str->rtp_cipher, 
-				    p->rtp.cipher_key_len); 
-  if (stat) {
-    crypto_free(str);
-    return stat;
-  }
-
-  /* allocate auth function */
-  stat = crypto_kernel_alloc_auth(p->rtp.auth_type, 
-				  &str->rtp_auth,
-				  p->rtp.auth_key_len, 
-				  p->rtp.auth_tag_len); 
-  if (stat) {
-    cipher_dealloc(str->rtp_cipher);
-    crypto_free(str);
-    return stat;
-  }
-  
-  /* allocate key limit structure */
-  str->limit = (key_limit_ctx_t*) crypto_alloc(sizeof(key_limit_ctx_t));
-  if (str->limit == NULL) {
-    auth_dealloc(str->rtp_auth);
-    cipher_dealloc(str->rtp_cipher);
-    crypto_free(str); 
-    return err_status_alloc_fail;
-  }
-
-  /*
-   * ...and now the RTCP-specific initialization - first, allocate
-   * the cipher 
-   */
-  stat = crypto_kernel_alloc_cipher(p->rtcp.cipher_type, 
-				    &str->rtcp_cipher, 
-				    p->rtcp.cipher_key_len); 
-  if (stat) {
-    auth_dealloc(str->rtp_auth);
-    cipher_dealloc(str->rtp_cipher);
-    crypto_free(str->limit);
-    crypto_free(str);
-    return stat;
-  }
-
-  /* allocate auth function */
-  stat = crypto_kernel_alloc_auth(p->rtcp.auth_type, 
-				  &str->rtcp_auth,
-				  p->rtcp.auth_key_len, 
-				  p->rtcp.auth_tag_len); 
-  if (stat) {
-    cipher_dealloc(str->rtcp_cipher);
-    auth_dealloc(str->rtp_auth);
-    cipher_dealloc(str->rtp_cipher);
-    crypto_free(str->limit);
-    crypto_free(str);
-   return stat;
-  }  
-
-  /* allocate ekt data associated with stream */
-  stat = ekt_alloc(&str->ekt, p->ekt);
-  if (stat) {
-    auth_dealloc(str->rtcp_auth);
-    cipher_dealloc(str->rtcp_cipher);
-    auth_dealloc(str->rtp_auth);
-    cipher_dealloc(str->rtp_cipher);
-    crypto_free(str->limit);
-    crypto_free(str);
-   return stat;    
-  }
-
-  return err_status_ok;
+#define octets_in_rtp_extn_hdr 4
+
+static srtp_err_status_t srtp_validate_rtp_header(void *rtp_hdr,
+                                                  int *pkt_octet_len)
+{
+    if (*pkt_octet_len < octets_in_rtp_header)
+        return srtp_err_status_bad_param;
+
+    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
+
+    /* Check RTP header length */
+    int rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
+    if (hdr->x == 1)
+        rtp_header_len += octets_in_rtp_extn_hdr;
+
+    if (*pkt_octet_len < rtp_header_len)
+        return srtp_err_status_bad_param;
+
+    /* Verifing profile length. */
+    if (hdr->x == 1) {
+        srtp_hdr_xtnd_t *xtn_hdr =
+            (srtp_hdr_xtnd_t *)((uint32_t *)hdr + uint32s_in_rtp_header +
+                                hdr->cc);
+        int profile_len = ntohs(xtn_hdr->length);
+        rtp_header_len += profile_len * 4;
+        /* profile length counts the number of 32-bit words */
+        if (*pkt_octet_len < rtp_header_len)
+            return srtp_err_status_bad_param;
+    }
+    return srtp_err_status_ok;
+}
+
+const char *srtp_get_version_string()
+{
+    /*
+     * Simply return the autotools generated string
+     */
+    return SRTP_VER_STRING;
+}
+
+unsigned int srtp_get_version()
+{
+    unsigned int major = 0, minor = 0, micro = 0;
+    unsigned int rv = 0;
+    int parse_rv;
+
+    /*
+     * Parse the autotools generated version
+     */
+    parse_rv = sscanf(SRTP_VERSION, "%u.%u.%u", &major, &minor, &micro);
+    if (parse_rv != 3) {
+        /*
+         * We're expected to parse all 3 version levels.
+         * If not, then this must not be an official release.
+         * Return all zeros on the version
+         */
+        return (0);
+    }
+
+    /*
+     * We allow 8 bits for the major and minor, while
+     * allowing 16 bits for the micro.  16 bits for the micro
+     * may be beneficial for a continuous delivery model
+     * in the future.
+     */
+    rv |= (major & 0xFF) << 24;
+    rv |= (minor & 0xFF) << 16;
+    rv |= micro & 0xFF;
+    return rv;
+}
+
+/* Release (maybe partially allocated) stream. */
+static void srtp_stream_free(srtp_stream_ctx_t *str)
+{
+    unsigned int i = 0;
+    srtp_session_keys_t *session_keys = NULL;
+
+    for (i = 0; i < str->num_master_keys; i++) {
+        session_keys = &str->session_keys[i];
+
+        if (session_keys->rtp_xtn_hdr_cipher) {
+            srtp_cipher_dealloc(session_keys->rtp_xtn_hdr_cipher);
+        }
+
+        if (session_keys->rtcp_cipher) {
+            srtp_cipher_dealloc(session_keys->rtcp_cipher);
+        }
+
+        if (session_keys->rtcp_auth) {
+            srtp_auth_dealloc(session_keys->rtcp_auth);
+        }
+
+        if (session_keys->rtp_cipher) {
+            srtp_cipher_dealloc(session_keys->rtp_cipher);
+        }
+
+        if (session_keys->rtp_auth) {
+            srtp_auth_dealloc(session_keys->rtp_auth);
+        }
+
+        if (session_keys->mki_id) {
+            srtp_crypto_free(session_keys->mki_id);
+        }
+
+        if (session_keys->limit) {
+            srtp_crypto_free(session_keys->limit);
+        }
+    }
+
+    srtp_crypto_free(str->session_keys);
+
+    if (str->enc_xtn_hdr) {
+        srtp_crypto_free(str->enc_xtn_hdr);
+    }
+
+    srtp_crypto_free(str);
 }
 
-err_status_t
-srtp_stream_dealloc(srtp_t session, srtp_stream_ctx_t *stream) { 
-  err_status_t status;
-  
-  /*
-   * we use a conservative deallocation strategy - if any deallocation
-   * fails, then we report that fact without trying to deallocate
-   * anything else
-   */
-
-  /* deallocate cipher, if it is not the same as that in template */
-  if (session->stream_template
-      && stream->rtp_cipher == session->stream_template->rtp_cipher) {
-    /* do nothing */
-  } else {
-    status = cipher_dealloc(stream->rtp_cipher); 
-    if (status) 
-      return status;
-  }
-
-  /* deallocate auth function, if it is not the same as that in template */
-  if (session->stream_template
-      && stream->rtp_auth == session->stream_template->rtp_auth) {
-    /* do nothing */
-  } else {
-    status = auth_dealloc(stream->rtp_auth);
+srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr,
+                                    const srtp_policy_t *p)
+{
+    srtp_stream_ctx_t *str;
+    srtp_err_status_t stat;
+    unsigned int i = 0;
+    srtp_session_keys_t *session_keys = NULL;
+
+    /*
+     * This function allocates the stream context, rtp and rtcp ciphers
+     * and auth functions, and key limit structure.  If there is a
+     * failure during allocation, we free all previously allocated
+     * memory and return a failure code.  The code could probably
+     * be improved, but it works and should be clear.
+     */
+
+    /* allocate srtp stream and set str_ptr */
+    str = (srtp_stream_ctx_t *)srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
+    if (str == NULL)
+        return srtp_err_status_alloc_fail;
+
+    *str_ptr = str;
+
+    /*
+     *To keep backwards API compatible if someone is using multiple master
+     * keys then key should be set to NULL
+     */
+    if (p->key != NULL) {
+        str->num_master_keys = 1;
+    } else {
+        str->num_master_keys = p->num_master_keys;
+    }
+
+    str->session_keys = (srtp_session_keys_t *)srtp_crypto_alloc(
+        sizeof(srtp_session_keys_t) * str->num_master_keys);
+
+    if (str->session_keys == NULL) {
+        srtp_stream_free(str);
+        return srtp_err_status_alloc_fail;
+    }
+
+    for (i = 0; i < str->num_master_keys; i++) {
+        session_keys = &str->session_keys[i];
+
+        /* allocate cipher */
+        stat = srtp_crypto_kernel_alloc_cipher(
+            p->rtp.cipher_type, &session_keys->rtp_cipher,
+            p->rtp.cipher_key_len, p->rtp.auth_tag_len);
+        if (stat) {
+            srtp_stream_free(str);
+            return stat;
+        }
+
+        /* allocate auth function */
+        stat = srtp_crypto_kernel_alloc_auth(
+            p->rtp.auth_type, &session_keys->rtp_auth, p->rtp.auth_key_len,
+            p->rtp.auth_tag_len);
+        if (stat) {
+            srtp_stream_free(str);
+            return stat;
+        }
+
+        /*
+         * ...and now the RTCP-specific initialization - first, allocate
+         * the cipher
+         */
+        stat = srtp_crypto_kernel_alloc_cipher(
+            p->rtcp.cipher_type, &session_keys->rtcp_cipher,
+            p->rtcp.cipher_key_len, p->rtcp.auth_tag_len);
+        if (stat) {
+            srtp_stream_free(str);
+            return stat;
+        }
+
+        /* allocate auth function */
+        stat = srtp_crypto_kernel_alloc_auth(
+            p->rtcp.auth_type, &session_keys->rtcp_auth, p->rtcp.auth_key_len,
+            p->rtcp.auth_tag_len);
+        if (stat) {
+            srtp_stream_free(str);
+            return stat;
+        }
+
+        session_keys->mki_id = NULL;
+
+        /* allocate key limit structure */
+        session_keys->limit = (srtp_key_limit_ctx_t *)srtp_crypto_alloc(
+            sizeof(srtp_key_limit_ctx_t));
+        if (session_keys->limit == NULL) {
+            srtp_stream_free(str);
+            return srtp_err_status_alloc_fail;
+        }
+    }
+
+    /* allocate ekt data associated with stream */
+    stat = srtp_ekt_alloc(&str->ekt, p->ekt);
+    if (stat) {
+        srtp_stream_free(str);
+        return stat;
+    }
+
+    if (p->enc_xtn_hdr && p->enc_xtn_hdr_count > 0) {
+        srtp_cipher_type_id_t enc_xtn_hdr_cipher_type;
+        int enc_xtn_hdr_cipher_key_len;
+
+        str->enc_xtn_hdr = (int *)srtp_crypto_alloc(p->enc_xtn_hdr_count *
+                                                    sizeof(p->enc_xtn_hdr[0]));
+        if (!str->enc_xtn_hdr) {
+            srtp_stream_free(str);
+            return srtp_err_status_alloc_fail;
+        }
+        memcpy(str->enc_xtn_hdr, p->enc_xtn_hdr,
+               p->enc_xtn_hdr_count * sizeof(p->enc_xtn_hdr[0]));
+        str->enc_xtn_hdr_count = p->enc_xtn_hdr_count;
+
+        /*
+         * For GCM ciphers, the corresponding ICM cipher is used for header
+         * extensions encryption.
+         */
+        switch (p->rtp.cipher_type) {
+        case SRTP_AES_GCM_128:
+            enc_xtn_hdr_cipher_type = SRTP_AES_ICM_128;
+            enc_xtn_hdr_cipher_key_len = SRTP_AES_ICM_128_KEY_LEN_WSALT;
+            break;
+        case SRTP_AES_GCM_256:
+            enc_xtn_hdr_cipher_type = SRTP_AES_ICM_256;
+            enc_xtn_hdr_cipher_key_len = SRTP_AES_ICM_256_KEY_LEN_WSALT;
+            break;
+        default:
+            enc_xtn_hdr_cipher_type = p->rtp.cipher_type;
+            enc_xtn_hdr_cipher_key_len = p->rtp.cipher_key_len;
+            break;
+        }
+
+        for (i = 0; i < str->num_master_keys; i++) {
+            session_keys = &str->session_keys[i];
+
+            /* allocate cipher for extensions header encryption */
+            stat = srtp_crypto_kernel_alloc_cipher(
+                enc_xtn_hdr_cipher_type, &session_keys->rtp_xtn_hdr_cipher,
+                enc_xtn_hdr_cipher_key_len, 0);
+            if (stat) {
+                srtp_stream_free(str);
+                return stat;
+            }
+        }
+    } else {
+        for (i = 0; i < str->num_master_keys; i++) {
+            session_keys = &str->session_keys[i];
+            session_keys->rtp_xtn_hdr_cipher = NULL;
+        }
+
+        str->enc_xtn_hdr = NULL;
+        str->enc_xtn_hdr_count = 0;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
+                                      srtp_stream_ctx_t *stream_template)
+{
+    srtp_err_status_t status;
+    unsigned int i = 0;
+    srtp_session_keys_t *session_keys = NULL;
+    srtp_session_keys_t *template_session_keys = NULL;
+
+    /*
+     * we use a conservative deallocation strategy - if any deallocation
+     * fails, then we report that fact without trying to deallocate
+     * anything else
+     */
+    for (i = 0; i < stream->num_master_keys; i++) {
+        session_keys = &stream->session_keys[i];
+
+        if (stream_template) {
+            template_session_keys = &stream_template->session_keys[i];
+        } else {
+            template_session_keys = NULL;
+        }
+
+        /*
+        * deallocate cipher, if it is not the same as that in template
+        */
+        if (template_session_keys &&
+            session_keys->rtp_cipher == template_session_keys->rtp_cipher) {
+            /* do nothing */
+        } else {
+            status = srtp_cipher_dealloc(session_keys->rtp_cipher);
+            if (status)
+                return status;
+        }
+
+        /*
+         * deallocate auth function, if it is not the same as that in template
+         */
+        if (template_session_keys &&
+            session_keys->rtp_auth == template_session_keys->rtp_auth) {
+            /* do nothing */
+        } else {
+            status = srtp_auth_dealloc(session_keys->rtp_auth);
+            if (status)
+                return status;
+        }
+
+        if (template_session_keys &&
+            session_keys->rtp_xtn_hdr_cipher ==
+                template_session_keys->rtp_xtn_hdr_cipher) {
+            /* do nothing */
+        } else if (session_keys->rtp_xtn_hdr_cipher) {
+            status = srtp_cipher_dealloc(session_keys->rtp_xtn_hdr_cipher);
+            if (status)
+                return status;
+        }
+
+        /*
+         * deallocate rtcp cipher, if it is not the same as that in
+         * template
+         */
+        if (template_session_keys &&
+            session_keys->rtcp_cipher == template_session_keys->rtcp_cipher) {
+            /* do nothing */
+        } else {
+            status = srtp_cipher_dealloc(session_keys->rtcp_cipher);
+            if (status)
+                return status;
+        }
+
+        /*
+         * deallocate rtcp auth function, if it is not the same as that in
+         * template
+         */
+        if (template_session_keys &&
+            session_keys->rtcp_auth == template_session_keys->rtcp_auth) {
+            /* do nothing */
+        } else {
+            status = srtp_auth_dealloc(session_keys->rtcp_auth);
+            if (status)
+                return status;
+        }
+
+        /*
+         * zeroize the salt value
+         */
+        octet_string_set_to_zero(session_keys->salt, SRTP_AEAD_SALT_LEN);
+        octet_string_set_to_zero(session_keys->c_salt, SRTP_AEAD_SALT_LEN);
+
+        if (session_keys->mki_id) {
+            octet_string_set_to_zero(session_keys->mki_id,
+                                     session_keys->mki_size);
+            srtp_crypto_free(session_keys->mki_id);
+            session_keys->mki_id = NULL;
+        }
+
+        /*
+         * deallocate key usage limit, if it is not the same as that in template
+         */
+        if (template_session_keys &&
+            session_keys->limit == template_session_keys->limit) {
+            /* do nothing */
+        } else {
+            srtp_crypto_free(session_keys->limit);
+        }
+    }
+
+    if (stream_template &&
+        stream->session_keys == stream_template->session_keys) {
+        /* do nothing */
+    } else {
+        srtp_crypto_free(stream->session_keys);
+    }
+
+    status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
     if (status)
-      return status;
-  }
-
-  /* deallocate key usage limit, if it is not the same as that in template */
-  if (session->stream_template
-      && stream->limit == session->stream_template->limit) {
-    /* do nothing */
-  } else {
-    crypto_free(stream->limit);
-  }   
-
-  /* 
-   * deallocate rtcp cipher, if it is not the same as that in
-   * template 
-   */
-  if (session->stream_template
-      && stream->rtcp_cipher == session->stream_template->rtcp_cipher) {
-    /* do nothing */
-  } else {
-    status = cipher_dealloc(stream->rtcp_cipher); 
-    if (status) 
-      return status;
-  }
-
-  /*
-   * deallocate rtcp auth function, if it is not the same as that in
-   * template 
-   */
-  if (session->stream_template
-      && stream->rtcp_auth == session->stream_template->rtcp_auth) {
-    /* do nothing */
-  } else {
-    status = auth_dealloc(stream->rtcp_auth);
-    if (status)
-      return status;
-  }
-
-  status = rdbx_dealloc(&stream->rtp_rdbx);
-  if (status)
-    return status;
-
-  /* DAM - need to deallocate EKT here */
-  
-  /* deallocate srtp stream context */
-  crypto_free(stream);
-
-  return err_status_ok;
+        return status;
+
+    /* DAM - need to deallocate EKT here */
+
+    if (stream_template &&
+        stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) {
+        /* do nothing */
+    } else if (stream->enc_xtn_hdr) {
+        srtp_crypto_free(stream->enc_xtn_hdr);
+    }
+
+    /* deallocate srtp stream context */
+    srtp_crypto_free(stream);
+
+    return srtp_err_status_ok;
 }
 
-
 /*
  * srtp_stream_clone(stream_template, new) allocates a new stream and
  * initializes it using the cipher and auth of the stream_template
- * 
+ *
  * the only unique data in a cloned stream is the replay database and
  * the SSRC
  */
 
-err_status_t
-srtp_stream_clone(const srtp_stream_ctx_t *stream_template, 
-		  uint32_t ssrc, 
-		  srtp_stream_ctx_t **str_ptr) {
-  err_status_t status;
-  srtp_stream_ctx_t *str;
-
-  debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ssrc);
-
-  /* allocate srtp stream and set str_ptr */
-  str = (srtp_stream_ctx_t *) crypto_alloc(sizeof(srtp_stream_ctx_t));
-  if (str == NULL)
-    return err_status_alloc_fail;
-  *str_ptr = str;  
-
-  /* set cipher and auth pointers to those of the template */
-  str->rtp_cipher  = stream_template->rtp_cipher;
-  str->rtp_auth    = stream_template->rtp_auth;
-  str->rtcp_cipher = stream_template->rtcp_cipher;
-  str->rtcp_auth   = stream_template->rtcp_auth;
-
-  /* set key limit to point to that of the template */
-  status = key_limit_clone(stream_template->limit, &str->limit);
-  if (status) 
-    return status;
-
-  /* initialize replay databases */
-  status = rdbx_init(&str->rtp_rdbx,
-		     rdbx_get_window_size(&stream_template->rtp_rdbx));
-  if (status)
-    return status;
-  rdb_init(&str->rtcp_rdb);
-  str->allow_repeat_tx = stream_template->allow_repeat_tx;
-  
-  /* set ssrc to that provided */
-  str->ssrc = ssrc;
-
-  /* set direction and security services */
-  str->direction     = stream_template->direction;
-  str->rtp_services  = stream_template->rtp_services;
-  str->rtcp_services = stream_template->rtcp_services;
-
-  /* set pointer to EKT data associated with stream */
-  str->ekt = stream_template->ekt;
-
-  /* defensive coding */
-  str->next = NULL;
-
-  return err_status_ok;
+srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template,
+                                    uint32_t ssrc,
+                                    srtp_stream_ctx_t **str_ptr)
+{
+    srtp_err_status_t status;
+    srtp_stream_ctx_t *str;
+    unsigned int i = 0;
+    srtp_session_keys_t *session_keys = NULL;
+    const srtp_session_keys_t *template_session_keys = NULL;
+
+    debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ntohl(ssrc));
+
+    /* allocate srtp stream and set str_ptr */
+    str = (srtp_stream_ctx_t *)srtp_crypto_alloc(sizeof(srtp_stream_ctx_t));
+    if (str == NULL)
+        return srtp_err_status_alloc_fail;
+    *str_ptr = str;
+
+    str->num_master_keys = stream_template->num_master_keys;
+    str->session_keys = (srtp_session_keys_t *)srtp_crypto_alloc(
+        sizeof(srtp_session_keys_t) * str->num_master_keys);
+
+    if (str->session_keys == NULL) {
+        srtp_stream_free(*str_ptr);
+        *str_ptr = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    for (i = 0; i < stream_template->num_master_keys; i++) {
+        session_keys = &str->session_keys[i];
+        template_session_keys = &stream_template->session_keys[i];
+
+        /* set cipher and auth pointers to those of the template */
+        session_keys->rtp_cipher = template_session_keys->rtp_cipher;
+        session_keys->rtp_auth = template_session_keys->rtp_auth;
+        session_keys->rtp_xtn_hdr_cipher =
+            template_session_keys->rtp_xtn_hdr_cipher;
+        session_keys->rtcp_cipher = template_session_keys->rtcp_cipher;
+        session_keys->rtcp_auth = template_session_keys->rtcp_auth;
+        session_keys->mki_size = template_session_keys->mki_size;
+
+        if (template_session_keys->mki_size == 0) {
+            session_keys->mki_id = NULL;
+        } else {
+            session_keys->mki_id =
+                srtp_crypto_alloc(template_session_keys->mki_size);
+
+            if (session_keys->mki_id == NULL) {
+                srtp_stream_free(*str_ptr);
+                *str_ptr = NULL;
+                return srtp_err_status_init_fail;
+            }
+            memcpy(session_keys->mki_id, template_session_keys->mki_id,
+                   session_keys->mki_size);
+        }
+        /* Copy the salt values */
+        memcpy(session_keys->salt, template_session_keys->salt,
+               SRTP_AEAD_SALT_LEN);
+        memcpy(session_keys->c_salt, template_session_keys->c_salt,
+               SRTP_AEAD_SALT_LEN);
+
+        /* set key limit to point to that of the template */
+        status = srtp_key_limit_clone(template_session_keys->limit,
+                                      &session_keys->limit);
+        if (status) {
+            srtp_stream_free(*str_ptr);
+            *str_ptr = NULL;
+            return status;
+        }
+    }
+
+    /* initialize replay databases */
+    status = srtp_rdbx_init(
+        &str->rtp_rdbx, srtp_rdbx_get_window_size(&stream_template->rtp_rdbx));
+    if (status) {
+        srtp_stream_free(*str_ptr);
+        *str_ptr = NULL;
+        return status;
+    }
+    srtp_rdb_init(&str->rtcp_rdb);
+    str->allow_repeat_tx = stream_template->allow_repeat_tx;
+
+    /* set ssrc to that provided */
+    str->ssrc = ssrc;
+
+    /* reset pending ROC */
+    str->pending_roc = 0;
+
+    /* set direction and security services */
+    str->direction = stream_template->direction;
+    str->rtp_services = stream_template->rtp_services;
+    str->rtcp_services = stream_template->rtcp_services;
+
+    /* set pointer to EKT data associated with stream */
+    str->ekt = stream_template->ekt;
+
+    /* copy information about extensions header encryption */
+    str->enc_xtn_hdr = stream_template->enc_xtn_hdr;
+    str->enc_xtn_hdr_count = stream_template->enc_xtn_hdr_count;
+
+    /* defensive coding */
+    str->next = NULL;
+    return srtp_err_status_ok;
 }
 
-
 /*
  * key derivation functions, internal to libSRTP
  *
  * srtp_kdf_t is a key derivation context
  *
  * srtp_kdf_init(&kdf, cipher_id, k, keylen) initializes kdf to use cipher
  * described by cipher_id, with the master key k with length in octets keylen.
- * 
+ *
  * srtp_kdf_generate(&kdf, l, kl, keylen) derives the key
  * corresponding to label l and puts it into kl; the length
  * of the key in octets is provided as keylen.  this function
  * should be called once for each subkey that is derived.
  *
  * srtp_kdf_clear(&kdf) zeroizes and deallocates the kdf state
  */
 
 typedef enum {
-  label_rtp_encryption  = 0x00,
-  label_rtp_msg_auth    = 0x01,
-  label_rtp_salt        = 0x02,
-  label_rtcp_encryption = 0x03,
-  label_rtcp_msg_auth   = 0x04,
-  label_rtcp_salt       = 0x05
+    label_rtp_encryption = 0x00,
+    label_rtp_msg_auth = 0x01,
+    label_rtp_salt = 0x02,
+    label_rtcp_encryption = 0x03,
+    label_rtcp_msg_auth = 0x04,
+    label_rtcp_salt = 0x05,
+    label_rtp_header_encryption = 0x06,
+    label_rtp_header_salt = 0x07
 } srtp_prf_label;
 
+#define MAX_SRTP_KEY_LEN 256
+
+#if defined(OPENSSL) && defined(OPENSSL_KDF)
+#define MAX_SRTP_AESKEY_LEN 32
+#define MAX_SRTP_SALT_LEN 14
+
+/*
+ * srtp_kdf_t represents a key derivation function.  The SRTP
+ * default KDF is the only one implemented at present.
+ */
+typedef struct {
+    uint8_t master_key[MAX_SRTP_AESKEY_LEN];
+    uint8_t master_salt[MAX_SRTP_SALT_LEN];
+    const EVP_CIPHER *evp;
+} srtp_kdf_t;
+
+static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
+                                       const uint8_t *key,
+                                       int key_len,
+                                       int salt_len)
+{
+    memset(kdf, 0x0, sizeof(srtp_kdf_t));
+
+    /* The NULL cipher has zero key length */
+    if (key_len == 0)
+        return srtp_err_status_ok;
+
+    if ((key_len > MAX_SRTP_AESKEY_LEN) || (salt_len > MAX_SRTP_SALT_LEN)) {
+        return srtp_err_status_bad_param;
+    }
+    switch (key_len) {
+    case SRTP_AES_256_KEYSIZE:
+        kdf->evp = EVP_aes_256_ctr();
+        break;
+    case SRTP_AES_192_KEYSIZE:
+        kdf->evp = EVP_aes_192_ctr();
+        break;
+    case SRTP_AES_128_KEYSIZE:
+        kdf->evp = EVP_aes_128_ctr();
+        break;
+    default:
+        return srtp_err_status_bad_param;
+        break;
+    }
+    memcpy(kdf->master_key, key, key_len);
+    memcpy(kdf->master_salt, key + key_len, salt_len);
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_kdf_generate(srtp_kdf_t *kdf,
+                                           srtp_prf_label label,
+                                           uint8_t *key,
+                                           unsigned int length)
+{
+    int ret;
+
+    /* The NULL cipher will not have an EVP */
+    if (!kdf->evp)
+        return srtp_err_status_ok;
+    octet_string_set_to_zero(key, length);
+
+    /*
+     * Invoke the OpenSSL SRTP KDF function
+     * This is useful if OpenSSL is in FIPS mode and FIP
+     * compliance is required for SRTP.
+     */
+    ret = kdf_srtp(kdf->evp, (char *)&kdf->master_key,
+                   (char *)&kdf->master_salt, NULL, NULL, label, (char *)key);
+    if (ret == -1) {
+        return (srtp_err_status_algo_fail);
+    }
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_kdf_clear(srtp_kdf_t *kdf)
+{
+    octet_string_set_to_zero(kdf->master_key, MAX_SRTP_AESKEY_LEN);
+    octet_string_set_to_zero(kdf->master_salt, MAX_SRTP_SALT_LEN);
+    kdf->evp = NULL;
+
+    return srtp_err_status_ok;
+}
+
+#else  /* if OPENSSL_KDF */
 
 /*
  * srtp_kdf_t represents a key derivation function.  The SRTP
  * default KDF is the only one implemented at present.
  */
-
-typedef struct { 
-  cipher_t *cipher;    /* cipher used for key derivation  */  
+typedef struct {
+    srtp_cipher_t *cipher; /* cipher used for key derivation  */
 } srtp_kdf_t;
 
-err_status_t
-srtp_kdf_init(srtp_kdf_t *kdf, cipher_type_id_t cipher_id, const uint8_t *key, int length) {
-
-  err_status_t stat;
-  stat = crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, length);
-  if (stat)
-    return stat;
-
-  stat = cipher_init(kdf->cipher, key, direction_encrypt);
-  if (stat) {
-    cipher_dealloc(kdf->cipher);
-    return stat;
-  }
-
-  return err_status_ok;
+static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf,
+                                       const uint8_t *key,
+                                       int key_len)
+{
+    srtp_cipher_type_id_t cipher_id;
+    switch (key_len) {
+    case SRTP_AES_ICM_256_KEY_LEN_WSALT:
+        cipher_id = SRTP_AES_ICM_256;
+        break;
+    case SRTP_AES_ICM_192_KEY_LEN_WSALT:
+        cipher_id = SRTP_AES_ICM_192;
+        break;
+    case SRTP_AES_ICM_128_KEY_LEN_WSALT:
+        cipher_id = SRTP_AES_ICM_128;
+        break;
+    default:
+        return srtp_err_status_bad_param;
+        break;
+    }
+
+    srtp_err_status_t stat;
+    stat = srtp_crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, key_len, 0);
+    if (stat)
+        return stat;
+
+    stat = srtp_cipher_init(kdf->cipher, key);
+    if (stat) {
+        srtp_cipher_dealloc(kdf->cipher);
+        return stat;
+    }
+    return srtp_err_status_ok;
 }
 
-err_status_t
-srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
-		  uint8_t *key, unsigned length) {
-
-  v128_t nonce;
-  err_status_t status;
-  
-  /* set eigth octet of nonce to <label>, set the rest of it to zero */
-  v128_set_to_zero(&nonce);
-  nonce.v8[7] = label;
- 
-  status = cipher_set_iv(kdf->cipher, &nonce);
-  if (status)
-    return status;
-  
-  /* generate keystream output */
-  octet_string_set_to_zero(key, length);
-  status = cipher_encrypt(kdf->cipher, key, &length);
-  if (status)
-    return status;
-
-  return err_status_ok;
+static srtp_err_status_t srtp_kdf_generate(srtp_kdf_t *kdf,
+                                           srtp_prf_label label,
+                                           uint8_t *key,
+                                           unsigned int length)
+{
+    srtp_err_status_t status;
+    v128_t nonce;
+
+    /* set eigth octet of nonce to <label>, set the rest of it to zero */
+    v128_set_to_zero(&nonce);
+    nonce.v8[7] = label;
+
+    status = srtp_cipher_set_iv(kdf->cipher, (uint8_t *)&nonce,
+                                srtp_direction_encrypt);
+    if (status)
+        return status;
+
+    /* generate keystream output */
+    octet_string_set_to_zero(key, length);
+    status = srtp_cipher_encrypt(kdf->cipher, key, &length);
+    if (status)
+        return status;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-srtp_kdf_clear(srtp_kdf_t *kdf) {
-  err_status_t status;
-  status = cipher_dealloc(kdf->cipher);
-  if (status)
-    return status;
-  kdf->cipher = NULL;
-
-  return err_status_ok;  
+static srtp_err_status_t srtp_kdf_clear(srtp_kdf_t *kdf)
+{
+    srtp_err_status_t status;
+    status = srtp_cipher_dealloc(kdf->cipher);
+    if (status)
+        return status;
+    kdf->cipher = NULL;
+    return srtp_err_status_ok;
 }
+#endif /* else OPENSSL_KDF */
 
 /*
- *  end of key derivation functions 
+ *  end of key derivation functions
  */
 
-#define MAX_SRTP_KEY_LEN 256
-
-
 /* Get the base key length corresponding to a given combined key+salt
  * length for the given cipher.
- * Assumption is that for AES-ICM a key length < 30 is Ismacryp using
- * AES-128 and short salts; everything else uses a salt length of 14.
  * TODO: key and salt lengths should be separate fields in the policy.  */
-static inline int base_key_length(const cipher_type_t *cipher, int key_length)
+static inline int base_key_length(const srtp_cipher_type_t *cipher,
+                                  int key_length)
 {
-  if (cipher->id != AES_ICM)
-    return key_length;
-  else if (key_length > 16 && key_length < 30)
-    return 16;
-  return key_length - 14;
+    switch (cipher->id) {
+    case SRTP_AES_ICM_128:
+    case SRTP_AES_ICM_192:
+    case SRTP_AES_ICM_256:
+        /* The legacy modes are derived from
+         * the configured key length on the policy */
+        return key_length - SRTP_SALT_LEN;
+        break;
+    case SRTP_AES_GCM_128:
+        return key_length - SRTP_AEAD_SALT_LEN;
+        break;
+    case SRTP_AES_GCM_256:
+        return key_length - SRTP_AEAD_SALT_LEN;
+        break;
+    default:
+        return key_length;
+        break;
+    }
 }
 
-err_status_t
-srtp_stream_init_keys(srtp_stream_ctx_t *srtp, const void *key) {
-  err_status_t stat;
-  srtp_kdf_t kdf;
-  uint8_t tmp_key[MAX_SRTP_KEY_LEN];
-  int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
-  int rtp_base_key_len, rtp_salt_len;
-  int rtcp_base_key_len, rtcp_salt_len;
-
-  /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
-  /* TODO: kdf algorithm, master key length, and master salt length should
-   * be part of srtp_policy_t. */
-  rtp_keylen = cipher_get_key_length(srtp->rtp_cipher);
-  if (rtp_keylen > kdf_keylen)
-    kdf_keylen = rtp_keylen;
-
-  rtcp_keylen = cipher_get_key_length(srtp->rtcp_cipher);
-  if (rtcp_keylen > kdf_keylen)
-    kdf_keylen = rtcp_keylen;
-
-  /* initialize KDF state     */
-  stat = srtp_kdf_init(&kdf, AES_ICM, (const uint8_t *)key, kdf_keylen);
-  if (stat) {
-    return err_status_init_fail;
-  }
-
-  rtp_base_key_len = base_key_length(srtp->rtp_cipher->type, rtp_keylen);
-  rtp_salt_len = rtp_keylen - rtp_base_key_len;
-  
-  /* generate encryption key  */
-  stat = srtp_kdf_generate(&kdf, label_rtp_encryption, 
-			   tmp_key, rtp_base_key_len);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /* 
-   * if the cipher in the srtp context uses a salt, then we need
-   * to generate the salt value
-   */
-  if (rtp_salt_len > 0) {
-    debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
-
-    /* generate encryption salt, put after encryption key */
-    stat = srtp_kdf_generate(&kdf, label_rtp_salt, 
-			     tmp_key + rtp_base_key_len, rtp_salt_len);
-    if (stat) {
-      /* zeroize temp buffer */
-      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-      return err_status_init_fail;
+unsigned int srtp_validate_policy_master_keys(const srtp_policy_t *policy)
+{
+    unsigned long i = 0;
+
+    if (policy->key == NULL) {
+        if (policy->num_master_keys <= 0)
+            return 0;
+
+        if (policy->num_master_keys > SRTP_MAX_NUM_MASTER_KEYS)
+            return 0;
+
+        for (i = 0; i < policy->num_master_keys; i++) {
+            if (policy->keys[i]->key == NULL)
+                return 0;
+            if (policy->keys[i]->mki_size > SRTP_MAX_MKI_LEN)
+                return 0;
+        }
+    }
+
+    return 1;
+}
+
+srtp_session_keys_t *srtp_get_session_keys_with_mki_index(
+    srtp_stream_ctx_t *stream,
+    unsigned int use_mki,
+    unsigned int mki_index)
+{
+    if (use_mki) {
+        if (mki_index < stream->num_master_keys) {
+            return &stream->session_keys[mki_index];
+        }
     }
-  }
-  debug_print(mod_srtp, "cipher key: %s", 
-	      octet_string_hex_string(tmp_key, rtp_keylen));
-
-  /* initialize cipher */
-  stat = cipher_init(srtp->rtp_cipher, tmp_key, direction_any);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /* generate authentication key */
-  stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth,
-			   tmp_key, auth_get_key_length(srtp->rtp_auth));
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-  debug_print(mod_srtp, "auth key:   %s",
-	      octet_string_hex_string(tmp_key, 
-				      auth_get_key_length(srtp->rtp_auth))); 
-
-  /* initialize auth function */
-  stat = auth_init(srtp->rtp_auth, tmp_key);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /*
-   * ...now initialize SRTCP keys
-   */
-
-  rtcp_base_key_len = base_key_length(srtp->rtcp_cipher->type, rtcp_keylen);
-  rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
-  
-  /* generate encryption key  */
-  stat = srtp_kdf_generate(&kdf, label_rtcp_encryption, 
-			   tmp_key, rtcp_base_key_len);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /* 
-   * if the cipher in the srtp context uses a salt, then we need
-   * to generate the salt value
-   */
-  if (rtcp_salt_len > 0) {
-    debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
-		NULL);
-
-    /* generate encryption salt, put after encryption key */
-    stat = srtp_kdf_generate(&kdf, label_rtcp_salt, 
-			     tmp_key + rtcp_base_key_len, rtcp_salt_len);
-    if (stat) {
-      /* zeroize temp buffer */
-      octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-      return err_status_init_fail;
+
+    return &stream->session_keys[0];
+}
+
+unsigned int srtp_inject_mki(uint8_t *mki_tag_location,
+                             srtp_session_keys_t *session_keys,
+                             unsigned int use_mki)
+{
+    unsigned int mki_size = 0;
+
+    if (use_mki) {
+        mki_size = session_keys->mki_size;
+
+        if (mki_size != 0) {
+            // Write MKI into memory
+            memcpy(mki_tag_location, session_keys->mki_id, mki_size);
+        }
     }
-  }
-  debug_print(mod_srtp, "rtcp cipher key: %s", 
-	      octet_string_hex_string(tmp_key, rtcp_keylen));  
-
-  /* initialize cipher */
-  stat = cipher_init(srtp->rtcp_cipher, tmp_key, direction_any);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /* generate authentication key */
-  stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
-			   tmp_key, auth_get_key_length(srtp->rtcp_auth));
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  debug_print(mod_srtp, "rtcp auth key:   %s",
-	      octet_string_hex_string(tmp_key, 
-		     auth_get_key_length(srtp->rtcp_auth))); 
-
-  /* initialize auth function */
-  stat = auth_init(srtp->rtcp_auth, tmp_key);
-  if (stat) {
-    /* zeroize temp buffer */
-    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-    return err_status_init_fail;
-  }
-
-  /* clear memory then return */
-  stat = srtp_kdf_clear(&kdf);
-  octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);  
-  if (stat)
-    return err_status_init_fail;
-
-  return err_status_ok;
+
+    return mki_size;
 }
 
-err_status_t
-srtp_stream_init(srtp_stream_ctx_t *srtp, 
-		  const srtp_policy_t *p) {
-  err_status_t err;
-
-   debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", 
-	       p->ssrc.value);
-
-   /* initialize replay database */
-   /* window size MUST be at least 64.  MAY be larger.  Values more than
-    * 2^15 aren't meaningful due to how extended sequence numbers are
-    * calculated.   Let a window size of 0 imply the default value. */
-
-   if (p->window_size != 0 && (p->window_size < 64 || p->window_size >= 0x8000))
-     return err_status_bad_param;
-
-   if (p->window_size != 0)
-     err = rdbx_init(&srtp->rtp_rdbx, p->window_size);
-   else
-     err = rdbx_init(&srtp->rtp_rdbx, 128);
-   if (err) return err;
-
-   /* initialize key limit to maximum value */
-#ifdef NO_64BIT_MATH
+srtp_err_status_t srtp_stream_init_all_master_keys(
+    srtp_stream_ctx_t *srtp,
+    unsigned char *key,
+    srtp_master_key_t **keys,
+    const unsigned int max_master_keys)
 {
-   uint64_t temp;
-   temp = make64(UINT_MAX,UINT_MAX);
-   key_limit_set(srtp->limit, temp);
+    unsigned int i = 0;
+    srtp_err_status_t status = srtp_err_status_ok;
+    srtp_master_key_t single_master_key;
+
+    if (key != NULL) {
+        srtp->num_master_keys = 1;
+        single_master_key.key = key;
+        single_master_key.mki_id = NULL;
+        single_master_key.mki_size = 0;
+        status = srtp_stream_init_keys(srtp, &single_master_key, 0);
+    } else {
+        srtp->num_master_keys = max_master_keys;
+
+        for (i = 0; i < srtp->num_master_keys && i < SRTP_MAX_NUM_MASTER_KEYS;
+             i++) {
+            status = srtp_stream_init_keys(srtp, keys[i], i);
+
+            if (status) {
+                return status;
+            }
+        }
+    }
+
+    return status;
 }
-#else
-   key_limit_set(srtp->limit, 0xffffffffffffLL);
-#endif
-
-   /* set the SSRC value */
-   srtp->ssrc = htonl(p->ssrc.value);
-
-   /* set the security service flags */
-   srtp->rtp_services  = p->rtp.sec_serv;
-   srtp->rtcp_services = p->rtcp.sec_serv;
-
-   /*
-    * set direction to unknown - this flag gets checked in srtp_protect(),
-    * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and 
-    * gets set appropriately if it is set to unknown.
+
+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)
+{
+    srtp_err_status_t stat;
+    srtp_kdf_t kdf;
+    uint8_t tmp_key[MAX_SRTP_KEY_LEN];
+    int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
+    int rtp_base_key_len, rtp_salt_len;
+    int rtcp_base_key_len, rtcp_salt_len;
+    srtp_session_keys_t *session_keys = NULL;
+    unsigned char *key = master_key->key;
+
+    /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */
+    /* TODO: kdf algorithm, master key length, and master salt length should
+     * be part of srtp_policy_t.
     */
-   srtp->direction = dir_unknown;
-
-   /* initialize SRTCP replay database */
-   rdb_init(&srtp->rtcp_rdb);
-
-   /* initialize allow_repeat_tx */
-   /* guard against uninitialized memory: allow only 0 or 1 here */
-   if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
-     rdbx_dealloc(&srtp->rtp_rdbx);
-     return err_status_bad_param;
-   }
-   srtp->allow_repeat_tx = p->allow_repeat_tx;
-
-   /* DAM - no RTCP key limit at present */
-
-   /* initialize keys */
-   err = srtp_stream_init_keys(srtp, p->key);
-   if (err) {
-     rdbx_dealloc(&srtp->rtp_rdbx);
-     return err;
-   }
-
-   /* 
-    * if EKT is in use, then initialize the EKT data associated with
-    * the stream
-    */
-   err = ekt_stream_init_from_policy(srtp->ekt, p->ekt);
-   if (err) {
-     rdbx_dealloc(&srtp->rtp_rdbx);
-     return err;
-   }
-
-   return err_status_ok;  
- }
-
-
- /*
-  * srtp_event_reporter is an event handler function that merely
-  * reports the events that are reported by the callbacks
-  */
-
- void
- srtp_event_reporter(srtp_event_data_t *data) {
-
-   err_report(err_level_warning, "srtp: in stream 0x%x: ", 
-	      data->stream->ssrc);
-
-   switch(data->event) {
-   case event_ssrc_collision:
-     err_report(err_level_warning, "\tSSRC collision\n");
-     break;
-   case event_key_soft_limit:
-     err_report(err_level_warning, "\tkey usage soft limit reached\n");
-     break;
-   case event_key_hard_limit:
-     err_report(err_level_warning, "\tkey usage hard limit reached\n");
-     break;
-   case event_packet_index_limit:
-     err_report(err_level_warning, "\tpacket index limit reached\n");
-     break;
-   default:
-     err_report(err_level_warning, "\tunknown event reported to handler\n");
-   }
- }
-
- /*
-  * srtp_event_handler is a global variable holding a pointer to the
-  * event handler function; this function is called for any unexpected
-  * event that needs to be handled out of the SRTP data path.  see
-  * srtp_event_t in srtp.h for more info
-  *
-  * it is okay to set srtp_event_handler to NULL, but we set 
-  * it to the srtp_event_reporter.
-  */
-
- static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
-
- err_status_t
- srtp_install_event_handler(srtp_event_handler_func_t func) {
-
-   /* 
-    * note that we accept NULL arguments intentionally - calling this
-    * function with a NULL arguments removes an event handler that's
-    * been previously installed
-    */
-
-   /* set global event handling function */
-   srtp_event_handler = func;
-   return err_status_ok;
- }
-
- err_status_t
- srtp_protect(srtp_ctx_t *ctx, void *rtp_hdr, int *pkt_octet_len) {
-   srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
-   uint32_t *enc_start;        /* pointer to start of encrypted portion  */
-   uint32_t *auth_start;       /* pointer to start of auth. portion      */
-   unsigned enc_octet_len = 0; /* number of octets in encrypted portion  */
-   xtd_seq_num_t est;          /* estimated xtd_seq_num_t of *hdr        */
-   int delta;                  /* delta of local pkt idx and that in hdr */
-   uint8_t *auth_tag = NULL;   /* location of auth_tag within packet     */
-   err_status_t status;   
-   int tag_len;
-   srtp_stream_ctx_t *stream;
-   int prefix_len;
-
-   debug_print(mod_srtp, "function srtp_protect", NULL);
-
-  /* we assume the hdr is 32-bit aligned to start */
-
-   /* check the packet length - it must at least contain a full header */
-   if (*pkt_octet_len < octets_in_rtp_header)
-     return err_status_bad_param;
-
-   /*
-    * look up ssrc in srtp_stream list, and process the packet with
-    * the appropriate stream.  if we haven't seen this stream before,
-    * there's a template key for this srtp_session, and the cipher
-    * supports key-sharing, then we assume that a new stream using
-    * that key has just started up
-    */
-   stream = srtp_get_stream(ctx, hdr->ssrc);
-   if (stream == NULL) {
-     if (ctx->stream_template != NULL) {
-       srtp_stream_ctx_t *new_stream;
-
-       /* allocate and initialize a new stream */
-       status = srtp_stream_clone(ctx->stream_template, 
-				  hdr->ssrc, &new_stream); 
-       if (status)
-	 return status;
-
-       /* add new stream to the head of the stream_list */
-       new_stream->next = ctx->stream_list;
-       ctx->stream_list = new_stream;
-
-       /* set direction to outbound */
-       new_stream->direction = dir_srtp_sender;
-
-       /* set stream (the pointer used in this function) */
-       stream = new_stream;
-     } else {
-       /* no template stream, so we return an error */
-       return err_status_no_ctx;
-     } 
-   }
-
-   /* 
-    * verify that stream is for sending traffic - this check will
-    * detect SSRC collisions, since a stream that appears in both
-    * srtp_protect() and srtp_unprotect() will fail this test in one of
-    * those functions.
-    */
-   if (stream->direction != dir_srtp_sender) {
-     if (stream->direction == dir_unknown) {
-       stream->direction = dir_srtp_sender;
-     } else {
-       srtp_handle_event(ctx, stream, event_ssrc_collision);
-     }
-   }
-
-  /* 
-   * update the key usage limit, and check it to make sure that we
-   * didn't just hit either the soft limit or the hard limit, and call
-   * the event handler if we hit either.
-   */
-  switch(key_limit_update(stream->limit)) {
-  case key_event_normal:
-    break;
-  case key_event_soft_limit: 
-    srtp_handle_event(ctx, stream, event_key_soft_limit);
-    break; 
-  case key_event_hard_limit:
-    srtp_handle_event(ctx, stream, event_key_hard_limit);
-	return err_status_key_expired;
-  default:
-    break;
-  }
-
-   /* get tag length from stream */
-   tag_len = auth_get_tag_length(stream->rtp_auth); 
-
-   /*
-    * find starting point for encryption and length of data to be
-    * encrypted - the encrypted portion starts after the rtp header
-    * extension, if present; otherwise, it starts after the last csrc,
-    * if any are present
-    *
-    * if we're not providing confidentiality, set enc_start to NULL
-    */
-   if (stream->rtp_services & sec_serv_conf) {
-     enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
-     if (hdr->x == 1) {
-       srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
-       enc_start += (ntohs(xtn_hdr->length) + 1);
-     }
-     if (!((uint8_t*)enc_start <= (uint8_t*)hdr + *pkt_octet_len))
-       return err_status_parse_err;
-     enc_octet_len = (unsigned int)(*pkt_octet_len 
-				    - ((enc_start - (uint32_t *)hdr) << 2));
-   } else {
-     enc_start = NULL;
-   }
-
-   /* 
-    * if we're providing authentication, set the auth_start and auth_tag
-    * pointers to the proper locations; otherwise, set auth_start to NULL
-    * to indicate that no authentication is needed
-    */
-   if (stream->rtp_services & sec_serv_auth) {
-     auth_start = (uint32_t *)hdr;
-     auth_tag = (uint8_t *)hdr + *pkt_octet_len;
-   } else {
-     auth_start = NULL;
-     auth_tag = NULL;
-   }
-
-   /*
-    * estimate the packet index using the start of the replay window   
-    * and the sequence number from the header
-    */
-   delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
-   status = rdbx_check(&stream->rtp_rdbx, delta);
-   if (status) {
-     if (status != err_status_replay_fail || !stream->allow_repeat_tx)
-       return status;  /* we've been asked to reuse an index */
-   }
-   else
-     rdbx_add_index(&stream->rtp_rdbx, delta);
+    session_keys = &srtp->session_keys[current_mki_index];
+
+/* initialize key limit to maximum value */
+#ifdef NO_64BIT_MATH
+    {
+        uint64_t temp;
+        temp = make64(UINT_MAX, UINT_MAX);
+        srtp_key_limit_set(session_keys->limit, temp);
+    }
+#else
+    srtp_key_limit_set(session_keys->limit, 0xffffffffffffLL);
+#endif
+
+    if (master_key->mki_size != 0) {
+        session_keys->mki_id = srtp_crypto_alloc(master_key->mki_size);
+
+        if (session_keys->mki_id == NULL) {
+            return srtp_err_status_init_fail;
+        }
+        memcpy(session_keys->mki_id, master_key->mki_id, master_key->mki_size);
+    } else {
+        session_keys->mki_id = NULL;
+    }
+
+    session_keys->mki_size = master_key->mki_size;
+
+    rtp_keylen = srtp_cipher_get_key_length(session_keys->rtp_cipher);
+    rtcp_keylen = srtp_cipher_get_key_length(session_keys->rtcp_cipher);
+    rtp_base_key_len =
+        base_key_length(session_keys->rtp_cipher->type, rtp_keylen);
+    rtp_salt_len = rtp_keylen - rtp_base_key_len;
+
+    if (rtp_keylen > kdf_keylen) {
+        kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
+    }
+
+    if (rtcp_keylen > kdf_keylen) {
+        kdf_keylen = 46; /* AES-CTR mode is always used for KDF */
+    }
+
+    debug_print(mod_srtp, "srtp key len: %d", rtp_keylen);
+    debug_print(mod_srtp, "srtcp key len: %d", rtcp_keylen);
+    debug_print(mod_srtp, "base key len: %d", rtp_base_key_len);
+    debug_print(mod_srtp, "kdf key len: %d", kdf_keylen);
+    debug_print(mod_srtp, "rtp salt len: %d", rtp_salt_len);
+
+    /*
+     * Make sure the key given to us is 'zero' appended.  GCM
+     * mode uses a shorter master SALT (96 bits), but still relies on
+     * the legacy CTR mode KDF, which uses a 112 bit master SALT.
+     */
+    memset(tmp_key, 0x0, MAX_SRTP_KEY_LEN);
+    memcpy(tmp_key, key, (rtp_base_key_len + rtp_salt_len));
+
+/* initialize KDF state     */
+#if defined(OPENSSL) && defined(OPENSSL_KDF)
+    stat = srtp_kdf_init(&kdf, (const uint8_t *)tmp_key, rtp_base_key_len,
+                         rtp_salt_len);
+#else
+    stat = srtp_kdf_init(&kdf, (const uint8_t *)tmp_key, kdf_keylen);
+#endif
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    /* generate encryption key  */
+    stat = srtp_kdf_generate(&kdf, label_rtp_encryption, tmp_key,
+                             rtp_base_key_len);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+    debug_print(mod_srtp, "cipher key: %s",
+                srtp_octet_string_hex_string(tmp_key, rtp_base_key_len));
+
+    /*
+     * if the cipher in the srtp context uses a salt, then we need
+     * to generate the salt value
+     */
+    if (rtp_salt_len > 0) {
+        debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL);
+
+        /* generate encryption salt, put after encryption key */
+        stat = srtp_kdf_generate(&kdf, label_rtp_salt,
+                                 tmp_key + rtp_base_key_len, rtp_salt_len);
+        if (stat) {
+            /* zeroize temp buffer */
+            octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+            return srtp_err_status_init_fail;
+        }
+        memcpy(session_keys->salt, tmp_key + rtp_base_key_len,
+               SRTP_AEAD_SALT_LEN);
+    }
+    if (rtp_salt_len > 0) {
+        debug_print(mod_srtp, "cipher salt: %s",
+                    srtp_octet_string_hex_string(tmp_key + rtp_base_key_len,
+                                                 rtp_salt_len));
+    }
+
+    /* initialize cipher */
+    stat = srtp_cipher_init(session_keys->rtp_cipher, tmp_key);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    if (session_keys->rtp_xtn_hdr_cipher) {
+        /* generate extensions header encryption key  */
+        int rtp_xtn_hdr_keylen;
+        int rtp_xtn_hdr_base_key_len;
+        int rtp_xtn_hdr_salt_len;
+        srtp_kdf_t tmp_kdf;
+        srtp_kdf_t *xtn_hdr_kdf;
+
+        if (session_keys->rtp_xtn_hdr_cipher->type !=
+            session_keys->rtp_cipher->type) {
+            /*
+             * With GCM ciphers, the header extensions are still encrypted using
+             * the corresponding ICM cipher.
+             * See https://tools.ietf.org/html/rfc7714#section-8.3
+             */
+            uint8_t tmp_xtn_hdr_key[MAX_SRTP_KEY_LEN];
+            rtp_xtn_hdr_keylen =
+                srtp_cipher_get_key_length(session_keys->rtp_xtn_hdr_cipher);
+            rtp_xtn_hdr_base_key_len = base_key_length(
+                session_keys->rtp_xtn_hdr_cipher->type, rtp_xtn_hdr_keylen);
+            rtp_xtn_hdr_salt_len =
+                rtp_xtn_hdr_keylen - rtp_xtn_hdr_base_key_len;
+            if (rtp_xtn_hdr_salt_len > rtp_salt_len) {
+                switch (session_keys->rtp_cipher->type->id) {
+                case SRTP_AES_GCM_128:
+                case SRTP_AES_GCM_256:
+                    /*
+                     * The shorter GCM salt is padded to the required ICM salt
+                     * length.
+                     */
+                    rtp_xtn_hdr_salt_len = rtp_salt_len;
+                    break;
+                default:
+                    /* zeroize temp buffer */
+                    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+                    return srtp_err_status_bad_param;
+                }
+            }
+            memset(tmp_xtn_hdr_key, 0x0, MAX_SRTP_KEY_LEN);
+            memcpy(tmp_xtn_hdr_key, key,
+                   (rtp_xtn_hdr_base_key_len + rtp_xtn_hdr_salt_len));
+            xtn_hdr_kdf = &tmp_kdf;
+
+/* initialize KDF state */
+#if defined(OPENSSL) && defined(OPENSSL_KDF)
+            stat =
+                srtp_kdf_init(xtn_hdr_kdf, (const uint8_t *)tmp_xtn_hdr_key,
+                              rtp_xtn_hdr_base_key_len, rtp_xtn_hdr_salt_len);
+#else
+            stat = srtp_kdf_init(xtn_hdr_kdf, (const uint8_t *)tmp_xtn_hdr_key,
+                                 kdf_keylen);
+#endif
+            octet_string_set_to_zero(tmp_xtn_hdr_key, MAX_SRTP_KEY_LEN);
+            if (stat) {
+                /* zeroize temp buffer */
+                octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+                return srtp_err_status_init_fail;
+            }
+        } else {
+            /* Reuse main KDF. */
+            rtp_xtn_hdr_keylen = rtp_keylen;
+            rtp_xtn_hdr_base_key_len = rtp_base_key_len;
+            rtp_xtn_hdr_salt_len = rtp_salt_len;
+            xtn_hdr_kdf = &kdf;
+        }
+
+        stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_encryption,
+                                 tmp_key, rtp_xtn_hdr_base_key_len);
+        if (stat) {
+            /* zeroize temp buffer */
+            octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+            return srtp_err_status_init_fail;
+        }
+        debug_print(
+            mod_srtp, "extensions cipher key: %s",
+            srtp_octet_string_hex_string(tmp_key, rtp_xtn_hdr_base_key_len));
+
+        /*
+         * if the cipher in the srtp context uses a salt, then we need
+         * to generate the salt value
+         */
+        if (rtp_xtn_hdr_salt_len > 0) {
+            debug_print(mod_srtp,
+                        "found rtp_xtn_hdr_salt_len > 0, generating salt",
+                        NULL);
+
+            /* generate encryption salt, put after encryption key */
+            stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt,
+                                     tmp_key + rtp_xtn_hdr_base_key_len,
+                                     rtp_xtn_hdr_salt_len);
+            if (stat) {
+                /* zeroize temp buffer */
+                octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+                return srtp_err_status_init_fail;
+            }
+        }
+        if (rtp_xtn_hdr_salt_len > 0) {
+            debug_print(
+                mod_srtp, "extensions cipher salt: %s",
+                srtp_octet_string_hex_string(tmp_key + rtp_xtn_hdr_base_key_len,
+                                             rtp_xtn_hdr_salt_len));
+        }
+
+        /* initialize extensions header cipher */
+        stat = srtp_cipher_init(session_keys->rtp_xtn_hdr_cipher, tmp_key);
+        if (stat) {
+            /* zeroize temp buffer */
+            octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+            return srtp_err_status_init_fail;
+        }
+
+        if (xtn_hdr_kdf != &kdf) {
+            /* release memory for custom header extension encryption kdf */
+            stat = srtp_kdf_clear(xtn_hdr_kdf);
+            if (stat) {
+                /* zeroize temp buffer */
+                octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+                return srtp_err_status_init_fail;
+            }
+        }
+    }
+
+    /* generate authentication key */
+    stat = srtp_kdf_generate(&kdf, label_rtp_msg_auth, tmp_key,
+                             srtp_auth_get_key_length(session_keys->rtp_auth));
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+    debug_print(mod_srtp, "auth key:   %s",
+                srtp_octet_string_hex_string(
+                    tmp_key, srtp_auth_get_key_length(session_keys->rtp_auth)));
+
+    /* initialize auth function */
+    stat = srtp_auth_init(session_keys->rtp_auth, tmp_key);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    /*
+     * ...now initialize SRTCP keys
+     */
+
+    rtcp_base_key_len =
+        base_key_length(session_keys->rtcp_cipher->type, rtcp_keylen);
+    rtcp_salt_len = rtcp_keylen - rtcp_base_key_len;
+    debug_print(mod_srtp, "rtcp salt len: %d", rtcp_salt_len);
+
+    /* generate encryption key  */
+    stat = srtp_kdf_generate(&kdf, label_rtcp_encryption, tmp_key,
+                             rtcp_base_key_len);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    /*
+     * if the cipher in the srtp context uses a salt, then we need
+     * to generate the salt value
+     */
+    if (rtcp_salt_len > 0) {
+        debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt",
+                    NULL);
+
+        /* generate encryption salt, put after encryption key */
+        stat = srtp_kdf_generate(&kdf, label_rtcp_salt,
+                                 tmp_key + rtcp_base_key_len, rtcp_salt_len);
+        if (stat) {
+            /* zeroize temp buffer */
+            octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+            return srtp_err_status_init_fail;
+        }
+        memcpy(session_keys->c_salt, tmp_key + rtcp_base_key_len,
+               SRTP_AEAD_SALT_LEN);
+    }
+    debug_print(mod_srtp, "rtcp cipher key: %s",
+                srtp_octet_string_hex_string(tmp_key, rtcp_base_key_len));
+    if (rtcp_salt_len > 0) {
+        debug_print(mod_srtp, "rtcp cipher salt: %s",
+                    srtp_octet_string_hex_string(tmp_key + rtcp_base_key_len,
+                                                 rtcp_salt_len));
+    }
+
+    /* initialize cipher */
+    stat = srtp_cipher_init(session_keys->rtcp_cipher, tmp_key);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    /* generate authentication key */
+    stat = srtp_kdf_generate(&kdf, label_rtcp_msg_auth, tmp_key,
+                             srtp_auth_get_key_length(session_keys->rtcp_auth));
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    debug_print(
+        mod_srtp, "rtcp auth key:   %s",
+        srtp_octet_string_hex_string(
+            tmp_key, srtp_auth_get_key_length(session_keys->rtcp_auth)));
+
+    /* initialize auth function */
+    stat = srtp_auth_init(session_keys->rtcp_auth, tmp_key);
+    if (stat) {
+        /* zeroize temp buffer */
+        octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+        return srtp_err_status_init_fail;
+    }
+
+    /* clear memory then return */
+    stat = srtp_kdf_clear(&kdf);
+    octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
+    if (stat)
+        return srtp_err_status_init_fail;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp,
+                                   const srtp_policy_t *p)
+{
+    srtp_err_status_t err;
+
+    debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", p->ssrc.value);
+
+    /* initialize replay database */
+    /*
+     * window size MUST be at least 64.  MAY be larger.  Values more than
+     * 2^15 aren't meaningful due to how extended sequence numbers are
+     * calculated.
+     * Let a window size of 0 imply the default value.
+     */
+
+    if (p->window_size != 0 &&
+        (p->window_size < 64 || p->window_size >= 0x8000))
+        return srtp_err_status_bad_param;
+
+    if (p->window_size != 0)
+        err = srtp_rdbx_init(&srtp->rtp_rdbx, p->window_size);
+    else
+        err = srtp_rdbx_init(&srtp->rtp_rdbx, 128);
+    if (err)
+        return err;
+
+    /* set the SSRC value */
+    srtp->ssrc = htonl(p->ssrc.value);
+
+    /* reset pending ROC */
+    srtp->pending_roc = 0;
+
+    /* set the security service flags */
+    srtp->rtp_services = p->rtp.sec_serv;
+    srtp->rtcp_services = p->rtcp.sec_serv;
+
+    /*
+     * set direction to unknown - this flag gets checked in srtp_protect(),
+     * srtp_unprotect(), srtp_protect_rtcp(), and srtp_unprotect_rtcp(), and
+     * gets set appropriately if it is set to unknown.
+     */
+    srtp->direction = dir_unknown;
+
+    /* initialize SRTCP replay database */
+    srtp_rdb_init(&srtp->rtcp_rdb);
+
+    /* initialize allow_repeat_tx */
+    /* guard against uninitialized memory: allow only 0 or 1 here */
+    if (p->allow_repeat_tx != 0 && p->allow_repeat_tx != 1) {
+        srtp_rdbx_dealloc(&srtp->rtp_rdbx);
+        return srtp_err_status_bad_param;
+    }
+    srtp->allow_repeat_tx = p->allow_repeat_tx;
+
+    /* DAM - no RTCP key limit at present */
+
+    /* initialize keys */
+    err = srtp_stream_init_all_master_keys(srtp, p->key, p->keys,
+                                           p->num_master_keys);
+    if (err) {
+        srtp_rdbx_dealloc(&srtp->rtp_rdbx);
+        return err;
+    }
+
+    /*
+     * if EKT is in use, then initialize the EKT data associated with
+     * the stream
+     */
+    err = srtp_ekt_stream_init_from_policy(srtp->ekt, p->ekt);
+    if (err) {
+        srtp_rdbx_dealloc(&srtp->rtp_rdbx);
+        return err;
+    }
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * srtp_event_reporter is an event handler function that merely
+ * reports the events that are reported by the callbacks
+ */
+
+void srtp_event_reporter(srtp_event_data_t *data)
+{
+    srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ",
+                    data->ssrc);
+
+    switch (data->event) {
+    case event_ssrc_collision:
+        srtp_err_report(srtp_err_level_warning, "\tSSRC collision\n");
+        break;
+    case event_key_soft_limit:
+        srtp_err_report(srtp_err_level_warning,
+                        "\tkey usage soft limit reached\n");
+        break;
+    case event_key_hard_limit:
+        srtp_err_report(srtp_err_level_warning,
+                        "\tkey usage hard limit reached\n");
+        break;
+    case event_packet_index_limit:
+        srtp_err_report(srtp_err_level_warning,
+                        "\tpacket index limit reached\n");
+        break;
+    default:
+        srtp_err_report(srtp_err_level_warning,
+                        "\tunknown event reported to handler\n");
+    }
+}
+
+/*
+ * srtp_event_handler is a global variable holding a pointer to the
+ * event handler function; this function is called for any unexpected
+ * event that needs to be handled out of the SRTP data path.  see
+ * srtp_event_t in srtp.h for more info
+ *
+ * it is okay to set srtp_event_handler to NULL, but we set
+ * it to the srtp_event_reporter.
+ */
+
+static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
+
+srtp_err_status_t srtp_install_event_handler(srtp_event_handler_func_t func)
+{
+    /*
+     * note that we accept NULL arguments intentionally - calling this
+     * function with a NULL arguments removes an event handler that's
+     * been previously installed
+     */
+
+    /* set global event handling function */
+    srtp_event_handler = func;
+    return srtp_err_status_ok;
+}
+
+/*
+ * Check if the given extension header id is / should be encrypted.
+ * Returns 1 if yes, otherwise 0.
+ */
+static int srtp_protect_extension_header(srtp_stream_ctx_t *stream, int id)
+{
+    int *enc_xtn_hdr = stream->enc_xtn_hdr;
+    int count = stream->enc_xtn_hdr_count;
+
+    if (!enc_xtn_hdr || count <= 0) {
+        return 0;
+    }
+
+    while (count > 0) {
+        if (*enc_xtn_hdr == id) {
+            return 1;
+        }
+
+        enc_xtn_hdr++;
+        count--;
+    }
+    return 0;
+}
+
+/*
+ * extensions header encryption RFC 6904
+ */
+static srtp_err_status_t srtp_process_header_encryption(
+    srtp_stream_ctx_t *stream,
+    srtp_hdr_xtnd_t *xtn_hdr,
+    srtp_session_keys_t *session_keys)
+{
+    srtp_err_status_t status;
+    uint8_t keystream[257]; /* Maximum 2 bytes header + 255 bytes data. */
+    int keystream_pos;
+    uint8_t *xtn_hdr_data = ((uint8_t *)xtn_hdr) + octets_in_rtp_extn_hdr;
+    uint8_t *xtn_hdr_end =
+        xtn_hdr_data + (ntohs(xtn_hdr->length) * sizeof(uint32_t));
+
+    if (ntohs(xtn_hdr->profile_specific) == 0xbede) {
+        /* RFC 5285, section 4.2. One-Byte Header */
+        while (xtn_hdr_data < xtn_hdr_end) {
+            uint8_t xid = (*xtn_hdr_data & 0xf0) >> 4;
+            unsigned int xlen = (*xtn_hdr_data & 0x0f) + 1;
+            uint32_t xlen_with_header = 1 + xlen;
+            xtn_hdr_data++;
+
+            if (xtn_hdr_data + xlen > xtn_hdr_end)
+                return srtp_err_status_parse_err;
+
+            if (xid == 15) {
+                /* found header 15, stop further processing. */
+                break;
+            }
+
+            status = srtp_cipher_output(session_keys->rtp_xtn_hdr_cipher,
+                                        keystream, &xlen_with_header);
+            if (status)
+                return srtp_err_status_cipher_fail;
+
+            if (srtp_protect_extension_header(stream, xid)) {
+                keystream_pos = 1;
+                while (xlen > 0) {
+                    *xtn_hdr_data ^= keystream[keystream_pos++];
+                    xtn_hdr_data++;
+                    xlen--;
+                }
+            } else {
+                xtn_hdr_data += xlen;
+            }
+
+            /* skip padding bytes. */
+            while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
+                xtn_hdr_data++;
+            }
+        }
+    } else if ((ntohs(xtn_hdr->profile_specific) & 0x1fff) == 0x100) {
+        /* RFC 5285, section 4.3. Two-Byte Header */
+        while (xtn_hdr_data + 1 < xtn_hdr_end) {
+            uint8_t xid = *xtn_hdr_data;
+            unsigned int xlen = *(xtn_hdr_data + 1);
+            uint32_t xlen_with_header = 2 + xlen;
+            xtn_hdr_data += 2;
+
+            if (xtn_hdr_data + xlen > xtn_hdr_end)
+                return srtp_err_status_parse_err;
+
+            status = srtp_cipher_output(session_keys->rtp_xtn_hdr_cipher,
+                                        keystream, &xlen_with_header);
+            if (status)
+                return srtp_err_status_cipher_fail;
+
+            if (xlen > 0 && srtp_protect_extension_header(stream, xid)) {
+                keystream_pos = 2;
+                while (xlen > 0) {
+                    *xtn_hdr_data ^= keystream[keystream_pos++];
+                    xtn_hdr_data++;
+                    xlen--;
+                }
+            } else {
+                xtn_hdr_data += xlen;
+            }
+
+            /* skip padding bytes. */
+            while (xtn_hdr_data < xtn_hdr_end && *xtn_hdr_data == 0) {
+                xtn_hdr_data++;
+            }
+        }
+    } else {
+        /* unsupported extension header format. */
+        return srtp_err_status_parse_err;
+    }
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * AEAD uses a new IV formation method.  This function implements
+ * section 8.1. (SRTP IV Formation for AES-GCM) of RFC7714.
+ * The calculation is defined as, where (+) is the xor operation:
+ *
+ *
+ *              0  0  0  0  0  0  0  0  0  0  1  1
+ *              0  1  2  3  4  5  6  7  8  9  0  1
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+
+ *            |00|00|    SSRC   |     ROC   | SEQ |---+
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *                                                    |
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *            |         Encryption Salt           |->(+)
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *                                                    |
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *            |       Initialization Vector       |<--+
+ *            +--+--+--+--+--+--+--+--+--+--+--+--+*
+ *
+ * Input:  *session_keys - pointer to SRTP stream context session keys,
+ *                         used to retrieve the SALT
+ *         *iv     - Pointer to receive the calculated IV
+ *         *seq    - The ROC and SEQ value to use for the
+ *                   IV calculation.
+ *         *hdr    - The RTP header, used to get the SSRC value
+ *
+ */
+
+static void srtp_calc_aead_iv(srtp_session_keys_t *session_keys,
+                              v128_t *iv,
+                              srtp_xtd_seq_num_t *seq,
+                              srtp_hdr_t *hdr)
+{
+    v128_t in;
+    v128_t salt;
 
 #ifdef NO_64BIT_MATH
-   debug_print2(mod_srtp, "estimated packet index: %08x%08x", 
-		high32(est),low32(est));
+    uint32_t local_roc = ((high32(*seq) << 16) | (low32(*seq) >> 16));
+    uint16_t local_seq = (uint16_t)(low32(*seq));
 #else
-   debug_print(mod_srtp, "estimated packet index: %016llx", est);
-#endif
-
-   /* 
-    * if we're using rindael counter mode, set nonce and seq 
-    */
-   if (stream->rtp_cipher->type->id == AES_ICM) {
-     v128_t iv;
-
-     iv.v32[0] = 0;
-     iv.v32[1] = hdr->ssrc;
-#ifdef NO_64BIT_MATH
-     iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
-								 low32(est) << 16));
-#else
-     iv.v64[1] = be64_to_cpu(est << 16);
+    uint32_t local_roc = (uint32_t)(*seq >> 16);
+    uint16_t local_seq = (uint16_t)*seq;
 #endif
-     status = cipher_set_iv(stream->rtp_cipher, &iv);
-
-   } else {  
-     v128_t iv;
-
-     /* otherwise, set the index to est */  
+
+    memset(&in, 0, sizeof(v128_t));
+    memset(&salt, 0, sizeof(v128_t));
+
+    in.v16[5] = htons(local_seq);
+    local_roc = htonl(local_roc);
+    memcpy(&in.v16[3], &local_roc, sizeof(local_roc));
+
+    /*
+     * Copy in the RTP SSRC value
+     */
+    memcpy(&in.v8[2], &hdr->ssrc, 4);
+    debug_print(mod_srtp, "Pre-salted RTP IV = %s\n", v128_hex_string(&in));
+
+    /*
+     * Get the SALT value from the context
+     */
+    memcpy(salt.v8, session_keys->salt, SRTP_AEAD_SALT_LEN);
+    debug_print(mod_srtp, "RTP SALT = %s\n", v128_hex_string(&salt));
+
+    /*
+     * Finally, apply tyhe SALT to the input
+     */
+    v128_xor(iv, &in, &salt);
+}
+
+srtp_session_keys_t *srtp_get_session_keys(srtp_stream_ctx_t *stream,
+                                           uint8_t *hdr,
+                                           const unsigned int *pkt_octet_len,
+                                           unsigned int *mki_size)
+{
+    unsigned int base_mki_start_location = *pkt_octet_len;
+    unsigned int mki_start_location = 0;
+    unsigned int tag_len = 0;
+    unsigned int i = 0;
+
+    // Determine the authentication tag size
+    if (stream->session_keys[0].rtp_cipher->algorithm == SRTP_AES_GCM_128 ||
+        stream->session_keys[0].rtp_cipher->algorithm == SRTP_AES_GCM_256) {
+        tag_len = 0;
+    } else {
+        tag_len = srtp_auth_get_tag_length(stream->session_keys[0].rtp_auth);
+    }
+
+    if (tag_len > base_mki_start_location) {
+        *mki_size = 0;
+        return NULL;
+    }
+
+    base_mki_start_location -= tag_len;
+
+    for (i = 0; i < stream->num_master_keys; i++) {
+        if (stream->session_keys[i].mki_size != 0) {
+            *mki_size = stream->session_keys[i].mki_size;
+            mki_start_location = base_mki_start_location - *mki_size;
+
+            if (mki_start_location >= *mki_size &&
+                memcmp(hdr + mki_start_location, stream->session_keys[i].mki_id,
+                       *mki_size) == 0) {
+                return &stream->session_keys[i];
+            }
+        }
+    }
+
+    *mki_size = 0;
+    return NULL;
+}
+
+static srtp_err_status_t srtp_estimate_index(srtp_rdbx_t *rdbx,
+                                             uint32_t roc,
+                                             srtp_xtd_seq_num_t *est,
+                                             srtp_sequence_number_t seq,
+                                             int *delta)
+{
 #ifdef NO_64BIT_MATH
-     iv.v32[0] = 0;
-     iv.v32[1] = 0;
-#else
-     iv.v64[0] = 0;
+    uint32_t internal_pkt_idx_reduced;
+    uint32_t external_pkt_idx_reduced;
+    uint32_t internal_roc;
+    uint32_t roc_difference;
 #endif
-     iv.v64[1] = be64_to_cpu(est);
-     status = cipher_set_iv(stream->rtp_cipher, &iv);
-   }
-   if (status)
-     return err_status_cipher_fail;
-
-   /* shift est, put into network byte order */
+
+#ifdef NO_64BIT_MATH
+    *est = (srtp_xtd_seq_num_t)make64(roc >> 16, (roc << 16) | seq);
+    *delta = low32(est) - rdbx->index;
+#else
+    *est = (srtp_xtd_seq_num_t)(((uint64_t)roc) << 16) | seq;
+    *delta = (int)(*est - rdbx->index);
+#endif
+
+    if (*est > rdbx->index) {
 #ifdef NO_64BIT_MATH
-   est = be64_to_cpu(make64((high32(est) << 16) |
-						 (low32(est) >> 16),
-						 low32(est) << 16));
+        internal_roc = (uint32_t)(rdbx->index >> 16);
+        roc_difference = roc - internal_roc;
+        if (roc_difference > 1) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_adv;
+        }
+
+        internal_pkt_idx_reduced = (uint32_t)(rdbx->index & 0xFFFF);
+        external_pkt_idx_reduced = (uint32_t)((roc_difference << 16) | seq);
+
+        if (external_pkt_idx_reduced - internal_pkt_idx_reduced >
+            seq_num_median) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_adv;
+        }
 #else
-   est = be64_to_cpu(est << 16);
+        if (*est - rdbx->index > seq_num_median) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_adv;
+        }
+#endif
+    } else if (*est < rdbx->index) {
+#ifdef NO_64BIT_MATH
+
+        internal_roc = (uint32_t)(rdbx->index >> 16);
+        roc_difference = internal_roc - roc;
+        if (roc_difference > 1) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_adv;
+        }
+
+        internal_pkt_idx_reduced =
+            (uint32_t)((roc_difference << 16) | rdbx->index & 0xFFFF);
+        external_pkt_idx_reduced = (uint32_t)(seq);
+
+        if (internal_pkt_idx_reduced - external_pkt_idx_reduced >
+            seq_num_median) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_old;
+        }
+#else
+        if (rdbx->index - *est > seq_num_median) {
+            *delta = 0;
+            return srtp_err_status_pkt_idx_old;
+        }
 #endif
-   
-   /* 
-    * if we're authenticating using a universal hash, put the keystream
-    * prefix into the authentication tag
-    */
-   if (auth_start) {
-     
-    prefix_len = auth_get_prefix_length(stream->rtp_auth);    
-    if (prefix_len) {
-      status = cipher_output(stream->rtp_cipher, auth_tag, prefix_len);
-      if (status)
-	return err_status_cipher_fail;
-      debug_print(mod_srtp, "keystream prefix: %s", 
-		  octet_string_hex_string(auth_tag, prefix_len));
+    }
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_get_est_pkt_index(srtp_hdr_t *hdr,
+                                                srtp_stream_ctx_t *stream,
+                                                srtp_xtd_seq_num_t *est,
+                                                int *delta)
+{
+    srtp_err_status_t result = srtp_err_status_ok;
+
+    if (stream->pending_roc) {
+        result = srtp_estimate_index(&stream->rtp_rdbx, stream->pending_roc,
+                                     est, ntohs(hdr->seq), delta);
+    } else {
+        /* estimate packet index from seq. num. in header */
+        *delta =
+            srtp_rdbx_estimate_index(&stream->rtp_rdbx, est, ntohs(hdr->seq));
+    }
+
+#ifdef NO_64BIT_MATH
+    debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(*est),
+                 low32(*est));
+#else
+    debug_print(mod_srtp, "estimated u_packet index: %016llx", *est);
+#endif
+    return result;
+}
+
+/*
+ * This function handles outgoing SRTP packets while in AEAD mode,
+ * which currently supports AES-GCM encryption.  All packets are
+ * encrypted and authenticated.
+ */
+static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx,
+                                           srtp_stream_ctx_t *stream,
+                                           void *rtp_hdr,
+                                           unsigned int *pkt_octet_len,
+                                           srtp_session_keys_t *session_keys,
+                                           unsigned int use_mki)
+{
+    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
+    uint32_t *enc_start;    /* pointer to start of encrypted portion  */
+    int enc_octet_len = 0;  /* number of octets in encrypted portion  */
+    srtp_xtd_seq_num_t est; /* estimated xtd_seq_num_t of *hdr        */
+    int delta;              /* delta of local pkt idx and that in hdr */
+    srtp_err_status_t status;
+    uint32_t tag_len;
+    v128_t iv;
+    unsigned int aad_len;
+    srtp_hdr_xtnd_t *xtn_hdr = NULL;
+    unsigned int mki_size = 0;
+    uint8_t *mki_location = NULL;
+
+    debug_print(mod_srtp, "function srtp_protect_aead", NULL);
+
+    /*
+     * update the key usage limit, and check it to make sure that we
+     * didn't just hit either the soft limit or the hard limit, and call
+     * the event handler if we hit either.
+     */
+    switch (srtp_key_limit_update(session_keys->limit)) {
+    case srtp_key_event_normal:
+        break;
+    case srtp_key_event_hard_limit:
+        srtp_handle_event(ctx, stream, event_key_hard_limit);
+        return srtp_err_status_key_expired;
+    case srtp_key_event_soft_limit:
+    default:
+        srtp_handle_event(ctx, stream, event_key_soft_limit);
+        break;
+    }
+
+    /* get tag length from stream */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtp_auth);
+
+    /*
+     * find starting point for encryption and length of data to be
+     * encrypted - the encrypted portion starts after the rtp header
+     * extension, if present; otherwise, it starts after the last csrc,
+     * if any are present
+     */
+    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
+    if (hdr->x == 1) {
+        xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+        enc_start += (ntohs(xtn_hdr->length) + 1);
     }
-  }
-
-  /* if we're encrypting, exor keystream into the message */
-  if (enc_start) {
-    status = cipher_encrypt(stream->rtp_cipher, 
-			    (uint8_t *)enc_start, &enc_octet_len);
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /*
-   *  if we're authenticating, run authentication function and put result
-   *  into the auth_tag 
-   */
-  if (auth_start) {        
-
-    /* initialize auth func context */
-    status = auth_start(stream->rtp_auth);
-    if (status) return status;
-
-    /* run auth func over packet */
-    status = auth_update(stream->rtp_auth, 
-			 (uint8_t *)auth_start, *pkt_octet_len);
-    if (status) return status;
-    
-    /* run auth func over ROC, put result into auth_tag */
+    /* note: the passed size is without the auth tag */
+    if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len))
+        return srtp_err_status_parse_err;
+    enc_octet_len =
+        (int)(*pkt_octet_len - ((uint8_t *)enc_start - (uint8_t *)hdr));
+    if (enc_octet_len < 0)
+        return srtp_err_status_parse_err;
+
+    /*
+     * estimate the packet index using the start of the replay window
+     * and the sequence number from the header
+     */
+    delta = srtp_rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
+    status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
+    if (status) {
+        if (status != srtp_err_status_replay_fail || !stream->allow_repeat_tx) {
+            return status; /* we've been asked to reuse an index */
+        }
+    } else {
+        srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
+    }
+
+#ifdef NO_64BIT_MATH
+    debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
+                 low32(est));
+#else
     debug_print(mod_srtp, "estimated packet index: %016llx", est);
-    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, auth_tag); 
-    debug_print(mod_srtp, "srtp auth tag:    %s", 
-		octet_string_hex_string(auth_tag, tag_len));
-    if (status)
-      return err_status_auth_fail;   
-
-  }
-
-  if (auth_tag) {
+#endif
+
+    /*
+     * AEAD uses a new IV formation method
+     */
+    srtp_calc_aead_iv(session_keys, &iv, &est, hdr);
+/* shift est, put into network byte order */
+#ifdef NO_64BIT_MATH
+    est = be64_to_cpu(
+        make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
+#else
+    est = be64_to_cpu(est << 16);
+#endif
+
+    status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                srtp_direction_encrypt);
+    if (!status && session_keys->rtp_xtn_hdr_cipher) {
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc;
+        iv.v64[1] = est;
+        status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                    (uint8_t *)&iv, srtp_direction_encrypt);
+    }
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) {
+        /*
+         * extensions header encryption RFC 6904
+         */
+        status = srtp_process_header_encryption(stream, xtn_hdr, session_keys);
+        if (status) {
+            return status;
+        }
+    }
+
+    /*
+     * Set the AAD over the RTP header
+     */
+    aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
+    status =
+        srtp_cipher_set_aad(session_keys->rtp_cipher, (uint8_t *)hdr, aad_len);
+    if (status) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* Encrypt the payload  */
+    status = srtp_cipher_encrypt(session_keys->rtp_cipher, (uint8_t *)enc_start,
+                                 (unsigned int *)&enc_octet_len);
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+    /*
+     * If we're doing GCM, we need to get the tag
+     * and append that to the output
+     */
+    status =
+        srtp_cipher_get_tag(session_keys->rtp_cipher,
+                            (uint8_t *)enc_start + enc_octet_len, &tag_len);
+    if (status) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    mki_location = (uint8_t *)hdr + *pkt_octet_len + tag_len;
+    mki_size = srtp_inject_mki(mki_location, session_keys, use_mki);
 
     /* increase the packet length by the length of the auth tag */
     *pkt_octet_len += tag_len;
-  }
-
-  return err_status_ok;  
+
+    /* increase the packet length by the length of the mki_size */
+    *pkt_octet_len += mki_size;
+
+    return srtp_err_status_ok;
 }
 
-
-err_status_t
-srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
-  srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
-  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
-  uint32_t *auth_start;     /* pointer to start of auth. portion      */
-  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
-  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  xtd_seq_num_t est;        /* estimated xtd_seq_num_t of *hdr        */
-  int delta;                /* delta of local pkt idx and that in hdr */
-  v128_t iv;
-  err_status_t status;
-  srtp_stream_ctx_t *stream;
-  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
-  int tag_len, prefix_len;
-
-  debug_print(mod_srtp, "function srtp_unprotect", NULL);
-
-  /* we assume the hdr is 32-bit aligned to start */
-
-  /* check the packet length - it must at least contain a full header */
-  if (*pkt_octet_len < octets_in_rtp_header)
-    return err_status_bad_param;
-
-  /*
-   * look up ssrc in srtp_stream list, and process the packet with 
-   * the appropriate stream.  if we haven't seen this stream before,
-   * there's only one key for this srtp_session, and the cipher
-   * supports key-sharing, then we assume that a new stream using
-   * that key has just started up
-   */
-  stream = srtp_get_stream(ctx, hdr->ssrc);
-  if (stream == NULL) {
-    if (ctx->stream_template != NULL) {
-      stream = ctx->stream_template;
-      debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
-		  hdr->ssrc);
-      
-      /* 
-       * set estimated packet index to sequence number from header,
-       * and set delta equal to the same value
-       */
+/*
+ * This function handles incoming SRTP packets while in AEAD mode,
+ * which currently supports AES-GCM encryption.  All packets are
+ * encrypted and authenticated.  Note, the auth tag is at the end
+ * of the packet stream and is automatically checked by GCM
+ * when decrypting the payload.
+ */
+static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx,
+                                             srtp_stream_ctx_t *stream,
+                                             int delta,
+                                             srtp_xtd_seq_num_t est,
+                                             void *srtp_hdr,
+                                             unsigned int *pkt_octet_len,
+                                             srtp_session_keys_t *session_keys,
+                                             unsigned int mki_size)
+{
+    srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    v128_t iv;
+    srtp_err_status_t status;
+    int tag_len;
+    unsigned int aad_len;
+    srtp_hdr_xtnd_t *xtn_hdr = NULL;
+
+    debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
+
+#ifdef NO_64BIT_MATH
+    debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
+                 low32(est));
+#else
+    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
+#endif
+
+    /* get tag length from stream */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtp_auth);
+
+    /*
+     * AEAD uses a new IV formation method
+     */
+    srtp_calc_aead_iv(session_keys, &iv, &est, hdr);
+    status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                srtp_direction_decrypt);
+    if (!status && session_keys->rtp_xtn_hdr_cipher) {
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc;
 #ifdef NO_64BIT_MATH
-      est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
-      delta = low32(est);
+        iv.v64[1] = be64_to_cpu(
+            make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
 #else
-      est = (xtd_seq_num_t) ntohs(hdr->seq);
-      delta = (int)est;
+        iv.v64[1] = be64_to_cpu(est << 16);
 #endif
+        status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                    (uint8_t *)&iv, srtp_direction_encrypt);
+    }
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     * find starting point for decryption and length of data to be
+     * decrypted - the encrypted portion starts after the rtp header
+     * extension, if present; otherwise, it starts after the last csrc,
+     * if any are present
+     */
+    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
+    if (hdr->x == 1) {
+        xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+        enc_start += (ntohs(xtn_hdr->length) + 1);
+    }
+    if (!((uint8_t *)enc_start <=
+          (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size)))
+        return srtp_err_status_parse_err;
+    /*
+     * We pass the tag down to the cipher when doing GCM mode
+     */
+    enc_octet_len = (unsigned int)(*pkt_octet_len - mki_size -
+                                   ((uint8_t *)enc_start - (uint8_t *)hdr));
+
+    /*
+     * Sanity check the encrypted payload length against
+     * the tag size.  It must always be at least as large
+     * as the tag length.
+     */
+    if (enc_octet_len < (unsigned int)tag_len) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     * update the key usage limit, and check it to make sure that we
+     * didn't just hit either the soft limit or the hard limit, and call
+     * the event handler if we hit either.
+     */
+    switch (srtp_key_limit_update(session_keys->limit)) {
+    case srtp_key_event_normal:
+        break;
+    case srtp_key_event_soft_limit:
+        srtp_handle_event(ctx, stream, event_key_soft_limit);
+        break;
+    case srtp_key_event_hard_limit:
+        srtp_handle_event(ctx, stream, event_key_hard_limit);
+        return srtp_err_status_key_expired;
+    default:
+        break;
+    }
+
+    /*
+     * Set the AAD for AES-GCM, which is the RTP header
+     */
+    aad_len = (uint8_t *)enc_start - (uint8_t *)hdr;
+    status =
+        srtp_cipher_set_aad(session_keys->rtp_cipher, (uint8_t *)hdr, aad_len);
+    if (status) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* Decrypt the ciphertext.  This also checks the auth tag based
+     * on the AAD we just specified above */
+    status = srtp_cipher_decrypt(session_keys->rtp_cipher, (uint8_t *)enc_start,
+                                 &enc_octet_len);
+    if (status) {
+        return status;
+    }
+
+    if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) {
+        /*
+         * extensions header encryption RFC 6904
+         */
+        status = srtp_process_header_encryption(stream, xtn_hdr, session_keys);
+        if (status) {
+            return status;
+        }
+    }
+
+    /*
+     * verify that stream is for received traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     *
+     * we do this check *after* the authentication check, so that the
+     * latter check will catch any attempts to fool us into thinking
+     * that we've got a collision
+     */
+    if (stream->direction != dir_srtp_receiver) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_receiver;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    /*
+     * if the stream is a 'provisional' one, in which the template context
+     * is used, then we need to allocate a new stream at this point, since
+     * the authentication passed
+     */
+    if (stream == ctx->stream_template) {
+        srtp_stream_ctx_t *new_stream;
+
+        /*
+         * allocate and initialize a new stream
+         *
+         * note that we indicate failure if we can't allocate the new
+         * stream, and some implementations will want to not return
+         * failure here
+         */
+        status =
+            srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+        if (status) {
+            return status;
+        }
+
+        /* add new stream to the head of the stream_list */
+        new_stream->next = ctx->stream_list;
+        ctx->stream_list = new_stream;
+
+        /* set stream (the pointer used in this function) */
+        stream = new_stream;
+    }
+
+    /*
+     * the message authentication function passed, so add the packet
+     * index into the replay database
+     */
+    srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
+
+    /* decrease the packet length by the length of the auth tag */
+    *pkt_octet_len -= tag_len;
+
+    /* decrease the packet length by the length of the mki_size */
+    *pkt_octet_len -= mki_size;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_protect(srtp_ctx_t *ctx,
+                               void *rtp_hdr,
+                               int *pkt_octet_len)
+{
+    return srtp_protect_mki(ctx, rtp_hdr, pkt_octet_len, 0, 0);
+}
+
+srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
+                                   void *rtp_hdr,
+                                   int *pkt_octet_len,
+                                   unsigned int use_mki,
+                                   unsigned int mki_index)
+{
+    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
+    uint32_t *enc_start;      /* pointer to start of encrypted portion  */
+    uint32_t *auth_start;     /* pointer to start of auth. portion      */
+    int enc_octet_len = 0;    /* number of octets in encrypted portion  */
+    srtp_xtd_seq_num_t est;   /* estimated xtd_seq_num_t of *hdr        */
+    int delta;                /* delta of local pkt idx and that in hdr */
+    uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
+    srtp_err_status_t status;
+    int tag_len;
+    srtp_stream_ctx_t *stream;
+    uint32_t prefix_len;
+    srtp_hdr_xtnd_t *xtn_hdr = NULL;
+    unsigned int mki_size = 0;
+    srtp_session_keys_t *session_keys = NULL;
+    uint8_t *mki_location = NULL;
+    int advance_packet_index = 0;
+
+    debug_print(mod_srtp, "function srtp_protect", NULL);
+
+    /* we assume the hdr is 32-bit aligned to start */
+
+    /* Verify RTP header */
+    status = srtp_validate_rtp_header(rtp_hdr, pkt_octet_len);
+    if (status)
+        return status;
+
+    /* check the packet length - it must at least contain a full header */
+    if (*pkt_octet_len < octets_in_rtp_header)
+        return srtp_err_status_bad_param;
+
+    /*
+     * look up ssrc in srtp_stream list, and process the packet with
+     * the appropriate stream.  if we haven't seen this stream before,
+     * there's a template key for this srtp_session, and the cipher
+     * supports key-sharing, then we assume that a new stream using
+     * that key has just started up
+     */
+    stream = srtp_get_stream(ctx, hdr->ssrc);
+    if (stream == NULL) {
+        if (ctx->stream_template != NULL) {
+            srtp_stream_ctx_t *new_stream;
+
+            /* allocate and initialize a new stream */
+            status =
+                srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+            if (status)
+                return status;
+
+            /* add new stream to the head of the stream_list */
+            new_stream->next = ctx->stream_list;
+            ctx->stream_list = new_stream;
+
+            /* set direction to outbound */
+            new_stream->direction = dir_srtp_sender;
+
+            /* set stream (the pointer used in this function) */
+            stream = new_stream;
+        } else {
+            /* no template stream, so we return an error */
+            return srtp_err_status_no_ctx;
+        }
+    }
+
+    /*
+     * verify that stream is for sending traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     */
+
+    if (stream->direction != dir_srtp_sender) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_sender;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    session_keys =
+        srtp_get_session_keys_with_mki_index(stream, use_mki, mki_index);
+
+    /*
+     * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
+     * the request to our AEAD handler.
+     */
+    if (session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_128 ||
+        session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_256) {
+        return srtp_protect_aead(ctx, stream, rtp_hdr,
+                                 (unsigned int *)pkt_octet_len, session_keys,
+                                 use_mki);
+    }
+
+    /*
+     * update the key usage limit, and check it to make sure that we
+     * didn't just hit either the soft limit or the hard limit, and call
+     * the event handler if we hit either.
+     */
+    switch (srtp_key_limit_update(session_keys->limit)) {
+    case srtp_key_event_normal:
+        break;
+    case srtp_key_event_soft_limit:
+        srtp_handle_event(ctx, stream, event_key_soft_limit);
+        break;
+    case srtp_key_event_hard_limit:
+        srtp_handle_event(ctx, stream, event_key_hard_limit);
+        return srtp_err_status_key_expired;
+    default:
+        break;
+    }
+
+    /* get tag length from stream */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtp_auth);
+
+    /*
+     * find starting point for encryption and length of data to be
+     * encrypted - the encrypted portion starts after the rtp header
+     * extension, if present; otherwise, it starts after the last csrc,
+     * if any are present
+     *
+     * if we're not providing confidentiality, set enc_start to NULL
+     */
+    if (stream->rtp_services & sec_serv_conf) {
+        enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
+        if (hdr->x == 1) {
+            xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+            enc_start += (ntohs(xtn_hdr->length) + 1);
+        }
+        /* note: the passed size is without the auth tag */
+        if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len))
+            return srtp_err_status_parse_err;
+        enc_octet_len =
+            (int)(*pkt_octet_len - ((uint8_t *)enc_start - (uint8_t *)hdr));
+        if (enc_octet_len < 0)
+            return srtp_err_status_parse_err;
     } else {
-      
-      /*
-       * no stream corresponding to SSRC found, and we don't do
-       * key-sharing, so return an error
-       */
-      return err_status_no_ctx;
+        enc_start = NULL;
+    }
+
+    mki_location = (uint8_t *)hdr + *pkt_octet_len;
+    mki_size = srtp_inject_mki(mki_location, session_keys, use_mki);
+
+    /*
+     * if we're providing authentication, set the auth_start and auth_tag
+     * pointers to the proper locations; otherwise, set auth_start to NULL
+     * to indicate that no authentication is needed
+     */
+    if (stream->rtp_services & sec_serv_auth) {
+        auth_start = (uint32_t *)hdr;
+        auth_tag = (uint8_t *)hdr + *pkt_octet_len + mki_size;
+    } else {
+        auth_start = NULL;
+        auth_tag = NULL;
     }
-  } else {
-  
-    /* estimate packet index from seq. num. in header */
-    delta = rdbx_estimate_index(&stream->rtp_rdbx, &est, ntohs(hdr->seq));
-    
-    /* check replay database */
-    status = rdbx_check(&stream->rtp_rdbx, delta);
-    if (status)
-      return status;
-  }
+
+    /*
+     * estimate the packet index using the start of the replay window
+     * and the sequence number from the header
+     */
+    status = srtp_get_est_pkt_index(hdr, stream, &est, &delta);
+
+    if (status && (status != srtp_err_status_pkt_idx_adv))
+        return status;
+
+    if (status == srtp_err_status_pkt_idx_adv)
+        advance_packet_index = 1;
+
+    if (advance_packet_index) {
+        srtp_rdbx_set_roc_seq(&stream->rtp_rdbx, (uint32_t)(est >> 16),
+                              (uint16_t)(est & 0xFFFF));
+        stream->pending_roc = 0;
+        srtp_rdbx_add_index(&stream->rtp_rdbx, 0);
+    } else {
+        status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
+        if (status) {
+            if (status != srtp_err_status_replay_fail ||
+                !stream->allow_repeat_tx)
+                return status; /* we've been asked to reuse an index */
+        }
+        srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
+    }
 
 #ifdef NO_64BIT_MATH
-  debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),low32(est));
+    debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est),
+                 low32(est));
 #else
-  debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
+    debug_print(mod_srtp, "estimated packet index: %016llx", est);
 #endif
 
-  /* get tag length from stream */
-  tag_len = auth_get_tag_length(stream->rtp_auth); 
-
-  /* 
-   * set the cipher's IV properly, depending on whatever cipher we
-   * happen to be using
-   */
-  if (stream->rtp_cipher->type->id == AES_ICM) {
-
-    /* aes counter mode */
-    iv.v32[0] = 0;
-    iv.v32[1] = hdr->ssrc;  /* still in network order */
+    /*
+     * if we're using rindael counter mode, set nonce and seq
+     */
+    if (session_keys->rtp_cipher->type->id == SRTP_AES_ICM_128 ||
+        session_keys->rtp_cipher->type->id == SRTP_AES_ICM_192 ||
+        session_keys->rtp_cipher->type->id == SRTP_AES_ICM_256) {
+        v128_t iv;
+
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc;
 #ifdef NO_64BIT_MATH
-    iv.v64[1] = be64_to_cpu(make64((high32(est) << 16) | (low32(est) >> 16),
-			         low32(est) << 16));
+        iv.v64[1] = be64_to_cpu(
+            make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
 #else
-    iv.v64[1] = be64_to_cpu(est << 16);
+        iv.v64[1] = be64_to_cpu(est << 16);
 #endif
-    status = cipher_set_iv(stream->rtp_cipher, &iv);
-  } else {  
-    
-    /* no particular format - set the iv to the pakcet index */  
+        status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_encrypt);
+        if (!status && session_keys->rtp_xtn_hdr_cipher) {
+            status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                        (uint8_t *)&iv, srtp_direction_encrypt);
+        }
+    } else {
+        v128_t iv;
+
+/* otherwise, set the index to est */
 #ifdef NO_64BIT_MATH
-    iv.v32[0] = 0;
-    iv.v32[1] = 0;
+        iv.v32[0] = 0;
+        iv.v32[1] = 0;
 #else
-    iv.v64[0] = 0;
+        iv.v64[0] = 0;
 #endif
-    iv.v64[1] = be64_to_cpu(est);
-    status = cipher_set_iv(stream->rtp_cipher, &iv);
-  }
-  if (status)
-    return err_status_cipher_fail;
-
-  /* shift est, put into network byte order */
+        iv.v64[1] = be64_to_cpu(est);
+        status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_encrypt);
+        if (!status && session_keys->rtp_xtn_hdr_cipher) {
+            status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                        (uint8_t *)&iv, srtp_direction_encrypt);
+        }
+    }
+    if (status)
+        return srtp_err_status_cipher_fail;
+
+/* shift est, put into network byte order */
 #ifdef NO_64BIT_MATH
-  est = be64_to_cpu(make64((high32(est) << 16) |
-					    (low32(est) >> 16),
-					    low32(est) << 16));
+    est = be64_to_cpu(
+        make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
 #else
-  est = be64_to_cpu(est << 16);
+    est = be64_to_cpu(est << 16);
 #endif
 
-  /*
-   * find starting point for decryption and length of data to be
-   * decrypted - the encrypted portion starts after the rtp header
-   * extension, if present; otherwise, it starts after the last csrc,
-   * if any are present
-   *
-   * if we're not providing confidentiality, set enc_start to NULL
-   */
-  if (stream->rtp_services & sec_serv_conf) {
-    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
-    if (hdr->x == 1) {
-      srtp_hdr_xtnd_t *xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
-      enc_start += (ntohs(xtn_hdr->length) + 1);
-    }  
-    if (!((uint8_t*)enc_start < (uint8_t*)hdr + (*pkt_octet_len - tag_len)))
-      return err_status_parse_err;
-    enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len 
-			       - ((enc_start - (uint32_t *)hdr) << 2));
-  } else {
-    enc_start = NULL;
-  }
-
-  /* 
-   * if we're providing authentication, set the auth_start and auth_tag
-   * pointers to the proper locations; otherwise, set auth_start to NULL
-   * to indicate that no authentication is needed
-   */
-  if (stream->rtp_services & sec_serv_auth) {
-    auth_start = (uint32_t *)hdr;
-    auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
-  } else {
-    auth_start = NULL;
-    auth_tag = NULL;
-  } 
-
-  /*
-   * if we expect message authentication, run the authentication
-   * function and compare the result with the value of the auth_tag
-   */
-  if (auth_start) {        
-
-    /* 
-     * if we're using a universal hash, then we need to compute the
-     * keystream prefix for encrypting the universal hash output
-     *
-     * if the keystream prefix length is zero, then we know that
-     * the authenticator isn't using a universal hash function
-     */  
-    if (stream->rtp_auth->prefix_len != 0) {
-      
-      prefix_len = auth_get_prefix_length(stream->rtp_auth);    
-      status = cipher_output(stream->rtp_cipher, tmp_tag, prefix_len);
-      debug_print(mod_srtp, "keystream prefix: %s", 
-		  octet_string_hex_string(tmp_tag, prefix_len));
-      if (status)
-	return err_status_cipher_fail;
-    } 
-
-    /* initialize auth func context */
-    status = auth_start(stream->rtp_auth);
-    if (status) return status;
- 
-    /* now compute auth function over packet */
-    status = auth_update(stream->rtp_auth, (uint8_t *)auth_start,  
-			 *pkt_octet_len - tag_len);
-
-    /* run auth func over ROC, then write tmp tag */
-    status = auth_compute(stream->rtp_auth, (uint8_t *)&est, 4, tmp_tag);  
-
-    debug_print(mod_srtp, "computed auth tag:    %s", 
-		octet_string_hex_string(tmp_tag, tag_len));
-    debug_print(mod_srtp, "packet auth tag:      %s", 
-		octet_string_hex_string(auth_tag, tag_len));
+    /*
+     * if we're authenticating using a universal hash, put the keystream
+     * prefix into the authentication tag
+     */
+    if (auth_start) {
+        prefix_len = srtp_auth_get_prefix_length(session_keys->rtp_auth);
+        if (prefix_len) {
+            status = srtp_cipher_output(session_keys->rtp_cipher, auth_tag,
+                                        &prefix_len);
+            if (status)
+                return srtp_err_status_cipher_fail;
+            debug_print(mod_srtp, "keystream prefix: %s",
+                        srtp_octet_string_hex_string(auth_tag, prefix_len));
+        }
+    }
+
+    if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) {
+        /*
+         * extensions header encryption RFC 6904
+         */
+        status = srtp_process_header_encryption(stream, xtn_hdr, session_keys);
+        if (status) {
+            return status;
+        }
+    }
+
+    /* if we're encrypting, exor keystream into the message */
+    if (enc_start) {
+        status =
+            srtp_cipher_encrypt(session_keys->rtp_cipher, (uint8_t *)enc_start,
+                                (unsigned int *)&enc_octet_len);
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     *  if we're authenticating, run authentication function and put result
+     *  into the auth_tag
+     */
+    if (auth_start) {
+        /* initialize auth func context */
+        status = srtp_auth_start(session_keys->rtp_auth);
+        if (status)
+            return status;
+
+        /* run auth func over packet */
+        status = srtp_auth_update(session_keys->rtp_auth, (uint8_t *)auth_start,
+                                  *pkt_octet_len);
+        if (status)
+            return status;
+
+        /* run auth func over ROC, put result into auth_tag */
+        debug_print(mod_srtp, "estimated packet index: %016llx", est);
+        status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4,
+                                   auth_tag);
+        debug_print(mod_srtp, "srtp auth tag:    %s",
+                    srtp_octet_string_hex_string(auth_tag, tag_len));
+        if (status)
+            return srtp_err_status_auth_fail;
+    }
+
+    if (auth_tag) {
+        /* increase the packet length by the length of the auth tag */
+        *pkt_octet_len += tag_len;
+    }
+
+    if (use_mki) {
+        /* increate the packet length by the mki size */
+        *pkt_octet_len += mki_size;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_unprotect(srtp_ctx_t *ctx,
+                                 void *srtp_hdr,
+                                 int *pkt_octet_len)
+{
+    return srtp_unprotect_mki(ctx, srtp_hdr, pkt_octet_len, 0);
+}
+
+srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx,
+                                     void *srtp_hdr,
+                                     int *pkt_octet_len,
+                                     unsigned int use_mki)
+{
+    srtp_hdr_t *hdr = (srtp_hdr_t *)srtp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    uint32_t *auth_start;           /* pointer to start of auth. portion      */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
+    srtp_xtd_seq_num_t est;         /* estimated xtd_seq_num_t of *hdr        */
+    int delta;                      /* delta of local pkt idx and that in hdr */
+    v128_t iv;
+    srtp_err_status_t status;
+    srtp_stream_ctx_t *stream;
+    uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
+    uint32_t tag_len, prefix_len;
+    srtp_hdr_xtnd_t *xtn_hdr = NULL;
+    unsigned int mki_size = 0;
+    srtp_session_keys_t *session_keys = NULL;
+    int advance_packet_index = 0;
+    uint32_t roc_to_set = 0;
+    uint16_t seq_to_set = 0;
+
+    debug_print(mod_srtp, "function srtp_unprotect", NULL);
+
+    /* we assume the hdr is 32-bit aligned to start */
+
+    /* Verify RTP header */
+    status = srtp_validate_rtp_header(srtp_hdr, pkt_octet_len);
     if (status)
-      return err_status_auth_fail;   
-
-    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
-      return err_status_auth_fail;
-  }
-
-  /* 
-   * update the key usage limit, and check it to make sure that we
-   * didn't just hit either the soft limit or the hard limit, and call
-   * the event handler if we hit either.
-   */
-  switch(key_limit_update(stream->limit)) {
-  case key_event_normal:
-    break;
-  case key_event_soft_limit: 
-    srtp_handle_event(ctx, stream, event_key_soft_limit);
-    break; 
-  case key_event_hard_limit:
-    srtp_handle_event(ctx, stream, event_key_hard_limit);
-    return err_status_key_expired;
-  default:
-    break;
-  }
-
-  /* if we're decrypting, add keystream into ciphertext */
-  if (enc_start) {
-    status = cipher_decrypt(stream->rtp_cipher, 
-			    (uint8_t *)enc_start, &enc_octet_len);
+        return status;
+
+    /* check the packet length - it must at least contain a full header */
+    if (*pkt_octet_len < octets_in_rtp_header)
+        return srtp_err_status_bad_param;
+
+    /*
+     * look up ssrc in srtp_stream list, and process the packet with
+     * the appropriate stream.  if we haven't seen this stream before,
+     * there's only one key for this srtp_session, and the cipher
+     * supports key-sharing, then we assume that a new stream using
+     * that key has just started up
+     */
+    stream = srtp_get_stream(ctx, hdr->ssrc);
+    if (stream == NULL) {
+        if (ctx->stream_template != NULL) {
+            stream = ctx->stream_template;
+            debug_print(mod_srtp, "using provisional stream (SSRC: 0x%08x)",
+                        ntohl(hdr->ssrc));
+
+/*
+ * set estimated packet index to sequence number from header,
+ * and set delta equal to the same value
+ */
+#ifdef NO_64BIT_MATH
+            est = (srtp_xtd_seq_num_t)make64(0, ntohs(hdr->seq));
+            delta = low32(est);
+#else
+            est = (srtp_xtd_seq_num_t)ntohs(hdr->seq);
+            delta = (int)est;
+#endif
+        } else {
+            /*
+             * no stream corresponding to SSRC found, and we don't do
+             * key-sharing, so return an error
+             */
+            return srtp_err_status_no_ctx;
+        }
+    } else {
+        status = srtp_get_est_pkt_index(hdr, stream, &est, &delta);
+
+        if (status && (status != srtp_err_status_pkt_idx_adv))
+            return status;
+
+        if (status == srtp_err_status_pkt_idx_adv) {
+            advance_packet_index = 1;
+            roc_to_set = (uint32_t)(est >> 16);
+            seq_to_set = (uint16_t)(est & 0xFFFF);
+        }
+
+        /* check replay database */
+        if (!advance_packet_index) {
+            status = srtp_rdbx_check(&stream->rtp_rdbx, delta);
+            if (status)
+                return status;
+        }
+    }
+
+#ifdef NO_64BIT_MATH
+    debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
+                 low32(est));
+#else
+    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
+#endif
+
+    /* Determine if MKI is being used and what session keys should be used */
+    if (use_mki) {
+        session_keys = srtp_get_session_keys(
+            stream, (uint8_t *)hdr, (const unsigned int *)pkt_octet_len,
+            &mki_size);
+
+        if (session_keys == NULL)
+            return srtp_err_status_bad_mki;
+    } else {
+        session_keys = &stream->session_keys[0];
+    }
+
+    /*
+     * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
+     * the request to our AEAD handler.
+     */
+    if (session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_128 ||
+        session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_256) {
+        return srtp_unprotect_aead(ctx, stream, delta, est, srtp_hdr,
+                                   (unsigned int *)pkt_octet_len, session_keys,
+                                   mki_size);
+    }
+
+    /* get tag length from stream */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtp_auth);
+
+    /*
+     * set the cipher's IV properly, depending on whatever cipher we
+     * happen to be using
+     */
+    if (session_keys->rtp_cipher->type->id == SRTP_AES_ICM_128 ||
+        session_keys->rtp_cipher->type->id == SRTP_AES_ICM_192 ||
+        session_keys->rtp_cipher->type->id == SRTP_AES_ICM_256) {
+        /* aes counter mode */
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc; /* still in network order */
+#ifdef NO_64BIT_MATH
+        iv.v64[1] = be64_to_cpu(
+            make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
+#else
+        iv.v64[1] = be64_to_cpu(est << 16);
+#endif
+        status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_decrypt);
+        if (!status && session_keys->rtp_xtn_hdr_cipher) {
+            status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                        (uint8_t *)&iv, srtp_direction_decrypt);
+        }
+    } else {
+/* no particular format - set the iv to the pakcet index */
+#ifdef NO_64BIT_MATH
+        iv.v32[0] = 0;
+        iv.v32[1] = 0;
+#else
+        iv.v64[0] = 0;
+#endif
+        iv.v64[1] = be64_to_cpu(est);
+        status = srtp_cipher_set_iv(session_keys->rtp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_decrypt);
+        if (!status && session_keys->rtp_xtn_hdr_cipher) {
+            status = srtp_cipher_set_iv(session_keys->rtp_xtn_hdr_cipher,
+                                        (uint8_t *)&iv, srtp_direction_decrypt);
+        }
+    }
     if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* 
-   * verify that stream is for received traffic - this check will
-   * detect SSRC collisions, since a stream that appears in both
-   * srtp_protect() and srtp_unprotect() will fail this test in one of
-   * those functions.
-   *
-   * we do this check *after* the authentication check, so that the
-   * latter check will catch any attempts to fool us into thinking
-   * that we've got a collision
-   */
-  if (stream->direction != dir_srtp_receiver) {
-    if (stream->direction == dir_unknown) {
-      stream->direction = dir_srtp_receiver;
+        return srtp_err_status_cipher_fail;
+
+/* shift est, put into network byte order */
+#ifdef NO_64BIT_MATH
+    est = be64_to_cpu(
+        make64((high32(est) << 16) | (low32(est) >> 16), low32(est) << 16));
+#else
+    est = be64_to_cpu(est << 16);
+#endif
+
+    /*
+     * find starting point for decryption and length of data to be
+     * decrypted - the encrypted portion starts after the rtp header
+     * extension, if present; otherwise, it starts after the last csrc,
+     * if any are present
+     *
+     * if we're not providing confidentiality, set enc_start to NULL
+     */
+    if (stream->rtp_services & sec_serv_conf) {
+        enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
+        if (hdr->x == 1) {
+            xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
+            enc_start += (ntohs(xtn_hdr->length) + 1);
+        }
+        if (!((uint8_t *)enc_start <=
+              (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size)))
+            return srtp_err_status_parse_err;
+        enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len - mki_size -
+                                   ((uint8_t *)enc_start - (uint8_t *)hdr));
     } else {
-      srtp_handle_event(ctx, stream, event_ssrc_collision);
+        enc_start = NULL;
+    }
+
+    /*
+     * if we're providing authentication, set the auth_start and auth_tag
+     * pointers to the proper locations; otherwise, set auth_start to NULL
+     * to indicate that no authentication is needed
+     */
+    if (stream->rtp_services & sec_serv_auth) {
+        auth_start = (uint32_t *)hdr;
+        auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len;
+    } else {
+        auth_start = NULL;
+        auth_tag = NULL;
     }
-  }
-
-  /* 
-   * if the stream is a 'provisional' one, in which the template context
-   * is used, then we need to allocate a new stream at this point, since
-   * the authentication passed
-   */
-  if (stream == ctx->stream_template) {  
-    srtp_stream_ctx_t *new_stream;
-
-    /* 
-     * allocate and initialize a new stream 
-     * 
-     * note that we indicate failure if we can't allocate the new
-     * stream, and some implementations will want to not return
-     * failure here
+
+    /*
+     * if we expect message authentication, run the authentication
+     * function and compare the result with the value of the auth_tag
+     */
+    if (auth_start) {
+        /*
+         * if we're using a universal hash, then we need to compute the
+         * keystream prefix for encrypting the universal hash output
+         *
+         * if the keystream prefix length is zero, then we know that
+         * the authenticator isn't using a universal hash function
+         */
+        if (session_keys->rtp_auth->prefix_len != 0) {
+            prefix_len = srtp_auth_get_prefix_length(session_keys->rtp_auth);
+            status = srtp_cipher_output(session_keys->rtp_cipher, tmp_tag,
+                                        &prefix_len);
+            debug_print(mod_srtp, "keystream prefix: %s",
+                        srtp_octet_string_hex_string(tmp_tag, prefix_len));
+            if (status)
+                return srtp_err_status_cipher_fail;
+        }
+
+        /* initialize auth func context */
+        status = srtp_auth_start(session_keys->rtp_auth);
+        if (status)
+            return status;
+
+        /* now compute auth function over packet */
+        status = srtp_auth_update(session_keys->rtp_auth, (uint8_t *)auth_start,
+                                  *pkt_octet_len - tag_len - mki_size);
+
+        /* run auth func over ROC, then write tmp tag */
+        status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4,
+                                   tmp_tag);
+
+        debug_print(mod_srtp, "computed auth tag:    %s",
+                    srtp_octet_string_hex_string(tmp_tag, tag_len));
+        debug_print(mod_srtp, "packet auth tag:      %s",
+                    srtp_octet_string_hex_string(auth_tag, tag_len));
+        if (status)
+            return srtp_err_status_auth_fail;
+
+        if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
+            return srtp_err_status_auth_fail;
+    }
+
+    /*
+     * update the key usage limit, and check it to make sure that we
+     * didn't just hit either the soft limit or the hard limit, and call
+     * the event handler if we hit either.
      */
-    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
+    switch (srtp_key_limit_update(session_keys->limit)) {
+    case srtp_key_event_normal:
+        break;
+    case srtp_key_event_soft_limit:
+        srtp_handle_event(ctx, stream, event_key_soft_limit);
+        break;
+    case srtp_key_event_hard_limit:
+        srtp_handle_event(ctx, stream, event_key_hard_limit);
+        return srtp_err_status_key_expired;
+    default:
+        break;
+    }
+
+    if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) {
+        /* extensions header encryption RFC 6904 */
+        status = srtp_process_header_encryption(stream, xtn_hdr, session_keys);
+        if (status) {
+            return status;
+        }
+    }
+
+    /* if we're decrypting, add keystream into ciphertext */
+    if (enc_start) {
+        status = srtp_cipher_decrypt(session_keys->rtp_cipher,
+                                     (uint8_t *)enc_start, &enc_octet_len);
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     * verify that stream is for received traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     *
+     * we do this check *after* the authentication check, so that the
+     * latter check will catch any attempts to fool us into thinking
+     * that we've got a collision
+     */
+    if (stream->direction != dir_srtp_receiver) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_receiver;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    /*
+     * if the stream is a 'provisional' one, in which the template context
+     * is used, then we need to allocate a new stream at this point, since
+     * the authentication passed
+     */
+    if (stream == ctx->stream_template) {
+        srtp_stream_ctx_t *new_stream;
+
+        /*
+         * allocate and initialize a new stream
+         *
+         * note that we indicate failure if we can't allocate the new
+         * stream, and some implementations will want to not return
+         * failure here
+         */
+        status =
+            srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+        if (status)
+            return status;
+
+        /* add new stream to the head of the stream_list */
+        new_stream->next = ctx->stream_list;
+        ctx->stream_list = new_stream;
+
+        /* set stream (the pointer used in this function) */
+        stream = new_stream;
+    }
+
+    /*
+     * the message authentication function passed, so add the packet
+     * index into the replay database
+     */
+    if (advance_packet_index) {
+        srtp_rdbx_set_roc_seq(&stream->rtp_rdbx, roc_to_set, seq_to_set);
+        stream->pending_roc = 0;
+        srtp_rdbx_add_index(&stream->rtp_rdbx, 0);
+    } else {
+        srtp_rdbx_add_index(&stream->rtp_rdbx, delta);
+    }
+
+    /* decrease the packet length by the length of the auth tag */
+    *pkt_octet_len -= tag_len;
+
+    /* decrease the packet length by the mki size */
+    *pkt_octet_len -= mki_size;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_init()
+{
+    srtp_err_status_t status;
+
+    /* initialize crypto kernel */
+    status = srtp_crypto_kernel_init();
     if (status)
-      return status;
-    
-    /* add new stream to the head of the stream_list */
-    new_stream->next = ctx->stream_list;
-    ctx->stream_list = new_stream;
-    
-    /* set stream (the pointer used in this function) */
-    stream = new_stream;
-  }
-  
-  /* 
-   * the message authentication function passed, so add the packet
-   * index into the replay database 
-   */
-  rdbx_add_index(&stream->rtp_rdbx, delta);
-
-  /* decrease the packet length by the length of the auth tag */
-  *pkt_octet_len -= tag_len;
-
-  return err_status_ok;  
+        return status;
+
+    /* load srtp debug module into the kernel */
+    status = srtp_crypto_kernel_load_debug_module(&mod_srtp);
+    if (status)
+        return status;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-srtp_init() {
-  err_status_t status;
-
-  /* initialize crypto kernel */
-  status = crypto_kernel_init();
-  if (status) 
-    return status;
-
-  /* load srtp debug module into the kernel */
-  status = crypto_kernel_load_debug_module(&mod_srtp);
-  if (status)
-    return status;
-
-  return err_status_ok;
+srtp_err_status_t srtp_shutdown()
+{
+    srtp_err_status_t status;
+
+    /* shut down crypto kernel */
+    status = srtp_crypto_kernel_shutdown();
+    if (status)
+        return status;
+
+    /* shutting down crypto kernel frees the srtp debug module as well */
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-srtp_shutdown() {
-  err_status_t status;
-
-  /* shut down crypto kernel */
-  status = crypto_kernel_shutdown();
-  if (status) 
-    return status;
-
-  /* shutting down crypto kernel frees the srtp debug module as well */
-
-  return err_status_ok;
-}
-
-
-/* 
+/*
  * The following code is under consideration for removal.  See
- * SRTP_MAX_TRAILER_LEN 
+ * SRTP_MAX_TRAILER_LEN
  */
 #if 0
 
 /*
  * srtp_get_trailer_length(&a) returns the number of octets that will
  * be added to an RTP packet by the SRTP processing.  This value
  * is constant for a given srtp_stream_t (i.e. between initializations).
  */
 
 int
 srtp_get_trailer_length(const srtp_stream_t s) {
-  return auth_get_tag_length(s->rtp_auth);
+  return srtp_auth_get_tag_length(s->rtp_auth);
 }
 
 #endif
 
 /*
  * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
  * to ssrc, or NULL if no stream exists for that ssrc
  *
- * this is an internal function 
+ * this is an internal function
  */
 
-srtp_stream_ctx_t *
-srtp_get_stream(srtp_t srtp, uint32_t ssrc) {
-  srtp_stream_ctx_t *stream;
-
-  /* walk down list until ssrc is found */
-  stream = srtp->stream_list;
-  while (stream != NULL) {
-    if (stream->ssrc == ssrc)
-      return stream;
-    stream = stream->next;
-  }
-  
-  /* we haven't found our ssrc, so return a null */
-  return NULL;
+srtp_stream_ctx_t *srtp_get_stream(srtp_t srtp, uint32_t ssrc)
+{
+    srtp_stream_ctx_t *stream;
+
+    /* walk down list until ssrc is found */
+    stream = srtp->stream_list;
+    while (stream != NULL) {
+        if (stream->ssrc == ssrc)
+            return stream;
+        stream = stream->next;
+    }
+
+    /* we haven't found our ssrc, so return a null */
+    return NULL;
+}
+
+srtp_err_status_t srtp_dealloc(srtp_t session)
+{
+    srtp_stream_ctx_t *stream;
+    srtp_err_status_t status;
+
+    /*
+     * we take a conservative deallocation strategy - if we encounter an
+     * error deallocating a stream, then we stop trying to deallocate
+     * memory and just return an error
+     */
+
+    /* walk list of streams, deallocating as we go */
+    stream = session->stream_list;
+    while (stream != NULL) {
+        srtp_stream_t next = stream->next;
+        status = srtp_stream_dealloc(stream, session->stream_template);
+        if (status)
+            return status;
+        stream = next;
+    }
+
+    /* deallocate stream template, if there is one */
+    if (session->stream_template != NULL) {
+        status = srtp_stream_dealloc(session->stream_template, NULL);
+        if (status)
+            return status;
+    }
+
+    /* deallocate session context */
+    srtp_crypto_free(session);
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-srtp_dealloc(srtp_t session) {
-  srtp_stream_ctx_t *stream;
-  err_status_t status;
-
-  /*
-   * we take a conservative deallocation strategy - if we encounter an
-   * error deallocating a stream, then we stop trying to deallocate
-   * memory and just return an error
-   */
-
-  /* walk list of streams, deallocating as we go */
-  stream = session->stream_list;
-  while (stream != NULL) {
-    srtp_stream_t next = stream->next;
-    status = srtp_stream_dealloc(session, stream);
+srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+    srtp_stream_t tmp;
+
+    /* sanity check arguments */
+    if ((session == NULL) || (policy == NULL) ||
+        (!srtp_validate_policy_master_keys(policy)))
+        return srtp_err_status_bad_param;
+
+    /* allocate stream  */
+    status = srtp_stream_alloc(&tmp, policy);
+    if (status) {
+        return status;
+    }
+
+    /* initialize stream  */
+    status = srtp_stream_init(tmp, policy);
+    if (status) {
+        srtp_stream_free(tmp);
+        return status;
+    }
+
+    /*
+     * set the head of the stream list or the template to point to the
+     * stream that we've just alloced and init'ed, depending on whether
+     * or not it has a wildcard SSRC value or not
+     *
+     * if the template stream has already been set, then the policy is
+     * inconsistent, so we return a bad_param error code
+     */
+    switch (policy->ssrc.type) {
+    case (ssrc_any_outbound):
+        if (session->stream_template) {
+            srtp_stream_free(tmp);
+            return srtp_err_status_bad_param;
+        }
+        session->stream_template = tmp;
+        session->stream_template->direction = dir_srtp_sender;
+        break;
+    case (ssrc_any_inbound):
+        if (session->stream_template) {
+            srtp_stream_free(tmp);
+            return srtp_err_status_bad_param;
+        }
+        session->stream_template = tmp;
+        session->stream_template->direction = dir_srtp_receiver;
+        break;
+    case (ssrc_specific):
+        tmp->next = session->stream_list;
+        session->stream_list = tmp;
+        break;
+    case (ssrc_undefined):
+    default:
+        srtp_stream_free(tmp);
+        return srtp_err_status_bad_param;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_create(srtp_t *session, /* handle for session     */
+                              const srtp_policy_t *policy)
+{ /* SRTP policy (list)     */
+    srtp_err_status_t stat;
+    srtp_ctx_t *ctx;
+
+    /* sanity check arguments */
+    if (session == NULL)
+        return srtp_err_status_bad_param;
+
+    /* allocate srtp context and set ctx_ptr */
+    ctx = (srtp_ctx_t *)srtp_crypto_alloc(sizeof(srtp_ctx_t));
+    if (ctx == NULL)
+        return srtp_err_status_alloc_fail;
+    *session = ctx;
+
+    /*
+     * loop over elements in the policy list, allocating and
+     * initializing a stream for each element
+     */
+    ctx->stream_template = NULL;
+    ctx->stream_list = NULL;
+    ctx->user_data = NULL;
+    while (policy != NULL) {
+        stat = srtp_add_stream(ctx, policy);
+        if (stat) {
+            /* clean up everything */
+            srtp_dealloc(*session);
+            *session = NULL;
+            return stat;
+        }
+
+        /* set policy to next item in list  */
+        policy = policy->next;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_remove_stream(srtp_t session, uint32_t ssrc)
+{
+    srtp_stream_ctx_t *stream, *last_stream;
+    srtp_err_status_t status;
+
+    /* sanity check arguments */
+    if (session == NULL)
+        return srtp_err_status_bad_param;
+
+    /* find stream in list; complain if not found */
+    last_stream = stream = session->stream_list;
+    while ((stream != NULL) && (ssrc != stream->ssrc)) {
+        last_stream = stream;
+        stream = stream->next;
+    }
+    if (stream == NULL)
+        return srtp_err_status_no_ctx;
+
+    /* remove stream from the list */
+    if (last_stream == stream)
+        /* stream was first in list */
+        session->stream_list = stream->next;
+    else
+        last_stream->next = stream->next;
+
+    /* deallocate the stream */
+    status = srtp_stream_dealloc(stream, session->stream_template);
     if (status)
-      return status;
-    stream = next;
-  }
-  
-  /* deallocate stream template, if there is one */
-  if (session->stream_template != NULL) {
-    status = auth_dealloc(session->stream_template->rtcp_auth); 
-    if (status) 
-      return status; 
-    status = cipher_dealloc(session->stream_template->rtcp_cipher); 
-    if (status) 
-      return status; 
-    crypto_free(session->stream_template->limit);
-    status = cipher_dealloc(session->stream_template->rtp_cipher); 
-    if (status) 
-      return status; 
-    status = auth_dealloc(session->stream_template->rtp_auth);
-    if (status)
-      return status;
-    status = rdbx_dealloc(&session->stream_template->rtp_rdbx);
-    if (status)
-      return status;
-    crypto_free(session->stream_template);
-  }
-
-  /* deallocate session context */
-  crypto_free(session);
-
-  return err_status_ok;
+        return status;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy)
+{
+    srtp_err_status_t stat;
+
+    /* sanity check arguments */
+    if ((session == NULL) || (policy == NULL) ||
+        (!srtp_validate_policy_master_keys(policy))) {
+        return srtp_err_status_bad_param;
+    }
+
+    while (policy != NULL) {
+        stat = srtp_update_stream(session, policy);
+        if (stat) {
+            return stat;
+        }
+
+        /* set policy to next item in list  */
+        policy = policy->next;
+    }
+    return srtp_err_status_ok;
 }
 
-
-err_status_t
-srtp_add_stream(srtp_t session, 
-		const srtp_policy_t *policy)  {
-  err_status_t status;
-  srtp_stream_t tmp;
-
-  /* sanity check arguments */
-  if ((session == NULL) || (policy == NULL) || (policy->key == NULL))
-    return err_status_bad_param;
-
-  /* allocate stream  */
-  status = srtp_stream_alloc(&tmp, policy);
-  if (status) {
-    return status;
-  }
-  
-  /* initialize stream  */
-  status = srtp_stream_init(tmp, policy);
-  if (status) {
-    crypto_free(tmp);
+static srtp_err_status_t update_template_streams(srtp_t session,
+                                                 const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+    srtp_stream_t new_stream_template;
+    srtp_stream_t new_stream_list = NULL;
+
+    if (session->stream_template == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* allocate new template stream  */
+    status = srtp_stream_alloc(&new_stream_template, policy);
+    if (status) {
+        return status;
+    }
+
+    /* initialize new template stream  */
+    status = srtp_stream_init(new_stream_template, policy);
+    if (status) {
+        srtp_crypto_free(new_stream_template);
+        return status;
+    }
+
+    /* for all old templated streams */
+    for (;;) {
+        srtp_stream_t stream;
+        uint32_t ssrc;
+        srtp_xtd_seq_num_t old_index;
+        srtp_rdb_t old_rtcp_rdb;
+
+        stream = session->stream_list;
+        while ((stream != NULL) &&
+               (stream->session_keys[0].rtp_auth !=
+                session->stream_template->session_keys[0].rtp_auth)) {
+            stream = stream->next;
+        }
+        if (stream == NULL) {
+            /* no more templated streams */
+            break;
+        }
+
+        /* save old extendard seq */
+        ssrc = stream->ssrc;
+        old_index = stream->rtp_rdbx.index;
+        old_rtcp_rdb = stream->rtcp_rdb;
+
+        /* remove stream */
+        status = srtp_remove_stream(session, ssrc);
+        if (status) {
+            /* free new allocations */
+            while (new_stream_list != NULL) {
+                srtp_stream_t next = new_stream_list->next;
+                srtp_stream_dealloc(new_stream_list, new_stream_template);
+                new_stream_list = next;
+            }
+            srtp_stream_dealloc(new_stream_template, NULL);
+            return status;
+        }
+
+        /* allocate and initialize a new stream */
+        status = srtp_stream_clone(new_stream_template, ssrc, &stream);
+        if (status) {
+            /* free new allocations */
+            while (new_stream_list != NULL) {
+                srtp_stream_t next = new_stream_list->next;
+                srtp_stream_dealloc(new_stream_list, new_stream_template);
+                new_stream_list = next;
+            }
+            srtp_stream_dealloc(new_stream_template, NULL);
+            return status;
+        }
+
+        /* add new stream to the head of the new_stream_list */
+        stream->next = new_stream_list;
+        new_stream_list = stream;
+
+        /* restore old extended seq */
+        stream->rtp_rdbx.index = old_index;
+        stream->rtcp_rdb = old_rtcp_rdb;
+    }
+    /* dealloc old template */
+    srtp_stream_dealloc(session->stream_template, NULL);
+    /* set new template */
+    session->stream_template = new_stream_template;
+    /* add new list */
+    if (new_stream_list) {
+        srtp_stream_t tail = new_stream_list;
+        while (tail->next) {
+            tail = tail->next;
+        }
+        tail->next = session->stream_list;
+        session->stream_list = new_stream_list;
+    }
     return status;
-  }
-  
-  /* 
-   * set the head of the stream list or the template to point to the
-   * stream that we've just alloced and init'ed, depending on whether
-   * or not it has a wildcard SSRC value or not
-   *
-   * if the template stream has already been set, then the policy is
-   * inconsistent, so we return a bad_param error code
-   */
-  switch (policy->ssrc.type) {
-  case (ssrc_any_outbound):
-    if (session->stream_template) {
-      return err_status_bad_param;
-    }
-    session->stream_template = tmp;
-    session->stream_template->direction = dir_srtp_sender;
-    break;
-  case (ssrc_any_inbound):
-    if (session->stream_template) {
-      return err_status_bad_param;
-    }
-    session->stream_template = tmp;
-    session->stream_template->direction = dir_srtp_receiver;
-    break;
-  case (ssrc_specific):
-    tmp->next = session->stream_list;
-    session->stream_list = tmp;
-    break;
-  case (ssrc_undefined):
-  default:
-    crypto_free(tmp);
-    return err_status_bad_param;
-  }
-    
-  return err_status_ok;
 }
 
-
-err_status_t
-srtp_create(srtp_t *session,               /* handle for session     */ 
-	    const srtp_policy_t *policy) { /* SRTP policy (list)     */
-  err_status_t stat;
-  srtp_ctx_t *ctx;
-
-  /* sanity check arguments */
-  if (session == NULL)
-    return err_status_bad_param;
-
-  /* allocate srtp context and set ctx_ptr */
-  ctx = (srtp_ctx_t *) crypto_alloc(sizeof(srtp_ctx_t));
-  if (ctx == NULL)
-    return err_status_alloc_fail;
-  *session = ctx;
-
-  /* 
-   * loop over elements in the policy list, allocating and
-   * initializing a stream for each element
-   */
-  ctx->stream_template = NULL;
-  ctx->stream_list = NULL;
-  while (policy != NULL) {    
-
-    stat = srtp_add_stream(ctx, policy);
-    if (stat) {
-      /* clean up everything */
-      srtp_dealloc(*session);
-      return stat;
-    }    
-
-    /* set policy to next item in list  */
-    policy = policy->next;
-  }
-
-  return err_status_ok;
+static srtp_err_status_t update_stream(srtp_t session,
+                                       const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+    srtp_xtd_seq_num_t old_index;
+    srtp_rdb_t old_rtcp_rdb;
+    srtp_stream_t stream;
+
+    stream = srtp_get_stream(session, htonl(policy->ssrc.value));
+    if (stream == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* save old extendard seq */
+    old_index = stream->rtp_rdbx.index;
+    old_rtcp_rdb = stream->rtcp_rdb;
+
+    status = srtp_remove_stream(session, htonl(policy->ssrc.value));
+    if (status) {
+        return status;
+    }
+
+    status = srtp_add_stream(session, policy);
+    if (status) {
+        return status;
+    }
+
+    stream = srtp_get_stream(session, htonl(policy->ssrc.value));
+    if (stream == NULL) {
+        return srtp_err_status_fail;
+    }
+
+    /* restore old extended seq */
+    stream->rtp_rdbx.index = old_index;
+    stream->rtcp_rdb = old_rtcp_rdb;
+
+    return srtp_err_status_ok;
 }
 
-
-err_status_t
-srtp_remove_stream(srtp_t session, uint32_t ssrc) {
-  srtp_stream_ctx_t *stream, *last_stream;
-  err_status_t status;
-
-  /* sanity check arguments */
-  if (session == NULL)
-    return err_status_bad_param;
-  
-  /* find stream in list; complain if not found */
-  last_stream = stream = session->stream_list;
-  while ((stream != NULL) && (ssrc != stream->ssrc)) {
-    last_stream = stream;
-    stream = stream->next;
-  }
-  if (stream == NULL)
-    return err_status_no_ctx;
-
-  /* remove stream from the list */
-  if (last_stream == stream)
-    /* stream was first in list */
-    session->stream_list = stream->next;
-  else
-    last_stream->next = stream->next;
-
-  /* deallocate the stream */
-  status = srtp_stream_dealloc(session, stream);
-  if (status)
+srtp_err_status_t srtp_update_stream(srtp_t session,
+                                     const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+
+    /* sanity check arguments */
+    if ((session == NULL) || (policy == NULL) ||
+        (!srtp_validate_policy_master_keys(policy)))
+        return srtp_err_status_bad_param;
+
+    switch (policy->ssrc.type) {
+    case (ssrc_any_outbound):
+    case (ssrc_any_inbound):
+        status = update_template_streams(session, policy);
+        break;
+    case (ssrc_specific):
+        status = update_stream(session, policy);
+        break;
+    case (ssrc_undefined):
+    default:
+        return srtp_err_status_bad_param;
+    }
+
     return status;
-
-  return err_status_ok;
 }
 
-
 /*
- * the default policy - provides a convenient way for callers to use
+ * The default policy - provides a convenient way for callers to use
  * the default security policy
- * 
- * this policy is that defined in the current SRTP internet draft.
+ *
+ * The default policy is defined in RFC 3711
+ * (Section 5. Default and mandatory-to-implement Transforms)
  *
  */
 
-/* 
+/*
  * NOTE: cipher_key_len is really key len (128 bits) plus salt len
  *  (112 bits)
  */
 /* There are hard-coded 16's for base_key_len in the key generation code */
 
-void
-crypto_policy_set_rtp_default(crypto_policy_t *p) {
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 30;                /* default 128 bits per RFC 3711 */
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
-  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
-  p->sec_serv        = sec_serv_conf_and_auth;
-  
+void srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_ICM_128;
+    p->cipher_key_len =
+        SRTP_AES_ICM_128_KEY_LEN_WSALT; /* default 128 bits per RFC 3711 */
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+void srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_ICM_128;
+    p->cipher_key_len =
+        SRTP_AES_ICM_128_KEY_LEN_WSALT; /* default 128 bits per RFC 3711 */
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+void srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 4568
+     *
+     * note that this crypto policy is intended for SRTP, but not SRTCP
+     */
+
+    p->cipher_type = SRTP_AES_ICM_128;
+    p->cipher_key_len =
+        SRTP_AES_ICM_128_KEY_LEN_WSALT; /* 128 bit key, 112 bit salt */
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* 160 bit key               */
+    p->auth_tag_len = 4;  /* 32 bit tag                */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+void srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 4568
+     *
+     * note that this crypto policy is intended for SRTP, but not SRTCP
+     */
+
+    p->cipher_type = SRTP_AES_ICM_128;
+    p->cipher_key_len =
+        SRTP_AES_ICM_128_KEY_LEN_WSALT; /* 128 bit key, 112 bit salt */
+    p->auth_type = SRTP_NULL_AUTH;
+    p->auth_key_len = 0;
+    p->auth_tag_len = 0;
+    p->sec_serv = sec_serv_conf;
 }
 
-void
-crypto_policy_set_rtcp_default(crypto_policy_t *p) {
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 30;                 /* default 128 bits per RFC 3711 */
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20;                 /* default 160 bits per RFC 3711 */
-  p->auth_tag_len    = 10;                 /* default 80 bits per RFC 3711 */
-  p->sec_serv        = sec_serv_conf_and_auth;
-  
+void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 4568
+     */
+
+    p->cipher_type = SRTP_NULL_CIPHER;
+    p->cipher_key_len = 0;
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20;
+    p->auth_tag_len = 10;
+    p->sec_serv = sec_serv_auth;
+}
+
+void srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p)
+{
+    /*
+     * Should only be used for testing
+     */
+
+    p->cipher_type = SRTP_NULL_CIPHER;
+    p->cipher_key_len = 0;
+    p->auth_type = SRTP_NULL_AUTH;
+    p->auth_key_len = 0;
+    p->auth_tag_len = 0;
+    p->sec_serv = sec_serv_none;
 }
 
-void
-crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p) {
-
-  /*
-   * corresponds to RFC 4568
-   *
-   * note that this crypto policy is intended for SRTP, but not SRTCP
-   */
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20;                /* 160 bit key               */
-  p->auth_tag_len    = 4;                 /* 32 bit tag                */
-  p->sec_serv        = sec_serv_conf_and_auth;
-  
+void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 6188
+     */
+
+    p->cipher_type = SRTP_AES_ICM_256;
+    p->cipher_key_len = SRTP_AES_ICM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 6188
+     *
+     * note that this crypto policy is intended for SRTP, but not SRTCP
+     */
+
+    p->cipher_type = SRTP_AES_ICM_256;
+    p->cipher_key_len = SRTP_AES_ICM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 4;  /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+/*
+ * AES-256 with no authentication.
+ */
+void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_ICM_256;
+    p->cipher_key_len = SRTP_AES_ICM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH;
+    p->auth_key_len = 0;
+    p->auth_tag_len = 0;
+    p->sec_serv = sec_serv_conf;
 }
 
-
-void
-crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p) {
-
-  /*
-   * corresponds to RFC 4568
-   *
-   * note that this crypto policy is intended for SRTP, but not SRTCP
-   */
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 30;                /* 128 bit key, 112 bit salt */
-  p->auth_type       = NULL_AUTH;             
-  p->auth_key_len    = 0; 
-  p->auth_tag_len    = 0; 
-  p->sec_serv        = sec_serv_conf;
-  
+#ifdef OPENSSL
+void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 6188
+     */
+
+    p->cipher_type = SRTP_AES_ICM_192;
+    p->cipher_key_len = SRTP_AES_ICM_192_KEY_LEN_WSALT;
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 10; /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
 }
 
-
-void
-crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p) {
-
-  /*
-   * corresponds to RFC 4568
-   */
-
-  p->cipher_type     = NULL_CIPHER;           
-  p->cipher_key_len  = 0;
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20; 
-  p->auth_tag_len    = 10; 
-  p->sec_serv        = sec_serv_auth;
-  
+void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p)
+{
+    /*
+     * corresponds to RFC 6188
+     *
+     * note that this crypto policy is intended for SRTP, but not SRTCP
+     */
+
+    p->cipher_type = SRTP_AES_ICM_192;
+    p->cipher_key_len = SRTP_AES_ICM_192_KEY_LEN_WSALT;
+    p->auth_type = SRTP_HMAC_SHA1;
+    p->auth_key_len = 20; /* default 160 bits per RFC 3711 */
+    p->auth_tag_len = 4;  /* default 80 bits per RFC 3711 */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+/*
+ * AES-192 with no authentication.
+ */
+void srtp_crypto_policy_set_aes_cm_192_null_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_ICM_192;
+    p->cipher_key_len = SRTP_AES_ICM_192_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH;
+    p->auth_key_len = 0;
+    p->auth_tag_len = 0;
+    p->sec_serv = sec_serv_conf;
+}
+
+/*
+ * AES-128 GCM mode with 8 octet auth tag.
+ */
+void srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_128;
+    p->cipher_key_len = SRTP_AES_GCM_128_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 8; /* 8 octet tag length */
+    p->sec_serv = sec_serv_conf_and_auth;
 }
 
-
-void
-crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p) {
-
-  /*
-   * corresponds to draft-ietf-avt-big-aes-03.txt
-   */
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 46;
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
-  p->auth_tag_len    = 10;                /* default 80 bits per RFC 3711 */
-  p->sec_serv        = sec_serv_conf_and_auth;
+/*
+ * AES-256 GCM mode with 8 octet auth tag.
+ */
+void srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_256;
+    p->cipher_key_len = SRTP_AES_GCM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 8; /* 8 octet tag length */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+/*
+ * AES-128 GCM mode with 8 octet auth tag, no RTCP encryption.
+ */
+void srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_128;
+    p->cipher_key_len = SRTP_AES_GCM_128_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 8;         /* 8 octet tag length */
+    p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
 }
 
-
-void
-crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p) {
-
-  /*
-   * corresponds to draft-ietf-avt-big-aes-03.txt
-   *
-   * note that this crypto policy is intended for SRTP, but not SRTCP
-   */
-
-  p->cipher_type     = AES_ICM;           
-  p->cipher_key_len  = 46;
-  p->auth_type       = HMAC_SHA1;             
-  p->auth_key_len    = 20;                /* default 160 bits per RFC 3711 */
-  p->auth_tag_len    = 4;                 /* default 80 bits per RFC 3711 */
-  p->sec_serv        = sec_serv_conf_and_auth;
+/*
+ * AES-256 GCM mode with 8 octet auth tag, no RTCP encryption.
+ */
+void srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_256;
+    p->cipher_key_len = SRTP_AES_GCM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 8;         /* 8 octet tag length */
+    p->sec_serv = sec_serv_auth; /* This only applies to RTCP */
 }
 
-
-/* 
+/*
+ * AES-128 GCM mode with 16 octet auth tag.
+ */
+void srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_128;
+    p->cipher_key_len = SRTP_AES_GCM_128_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 16; /* 16 octet tag length */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+/*
+ * AES-256 GCM mode with 16 octet auth tag.
+ */
+void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p)
+{
+    p->cipher_type = SRTP_AES_GCM_256;
+    p->cipher_key_len = SRTP_AES_GCM_256_KEY_LEN_WSALT;
+    p->auth_type = SRTP_NULL_AUTH; /* GCM handles the auth for us */
+    p->auth_key_len = 0;
+    p->auth_tag_len = 16; /* 16 octet tag length */
+    p->sec_serv = sec_serv_conf_and_auth;
+}
+
+#endif
+
+/*
  * secure rtcp functions
  */
 
-err_status_t 
-srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
-  srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
-  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
-  uint32_t *auth_start;     /* pointer to start of auth. portion      */
-  uint32_t *trailer;        /* pointer to start of trailer            */
-  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
-  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  err_status_t status;   
-  int tag_len;
-  srtp_stream_ctx_t *stream;
-  int prefix_len;
-  uint32_t seq_num;
-
-  /* we assume the hdr is 32-bit aligned to start */
-  /*
-   * look up ssrc in srtp_stream list, and process the packet with 
-   * the appropriate stream.  if we haven't seen this stream before,
-   * there's only one key for this srtp_session, and the cipher
-   * supports key-sharing, then we assume that a new stream using
-   * that key has just started up
-   */
-  stream = srtp_get_stream(ctx, hdr->ssrc);
-  if (stream == NULL) {
-    if (ctx->stream_template != NULL) {
-      srtp_stream_ctx_t *new_stream;
-      
-      /* allocate and initialize a new stream */
-      status = srtp_stream_clone(ctx->stream_template,
-				 hdr->ssrc, &new_stream); 
-      if (status)
-	return status;
-      
-      /* add new stream to the head of the stream_list */
-      new_stream->next = ctx->stream_list;
-      ctx->stream_list = new_stream;
-      
-      /* set stream (the pointer used in this function) */
-      stream = new_stream;
-    } else {
-      /* no template stream, so we return an error */
-      return err_status_no_ctx;
-    } 
-  }
-  
-  /* 
-   * verify that stream is for sending traffic - this check will
-   * detect SSRC collisions, since a stream that appears in both
-   * srtp_protect() and srtp_unprotect() will fail this test in one of
-   * those functions.
-   */
-  if (stream->direction != dir_srtp_sender) {
-    if (stream->direction == dir_unknown) {
-      stream->direction = dir_srtp_sender;
-    } else {
-      srtp_handle_event(ctx, stream, event_ssrc_collision);
+/*
+ * AEAD uses a new IV formation method.  This function implements
+ * section 9.1 (SRTCP IV Formation for AES-GCM) from RFC7714.
+ * The calculation is defined as, where (+) is the xor operation:
+ *
+ *                0  1  2  3  4  5  6  7  8  9 10 11
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+
+ *               |00|00|    SSRC   |00|00|0+SRTCP Idx|---+
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *                                                       |
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *               |         Encryption Salt           |->(+)
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *                                                       |
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+   |
+ *               |       Initialization Vector       |<--+
+ *               +--+--+--+--+--+--+--+--+--+--+--+--+*
+ *
+ * Input:  *session_keys - pointer to SRTP stream context session keys,
+ *                        used to retrieve the SALT
+ *         *iv           - Pointer to recieve the calculated IV
+ *         seq_num       - The SEQ value to use for the IV calculation.
+ *         *hdr          - The RTP header, used to get the SSRC value
+ *
+ * Returns: srtp_err_status_ok if no error or srtp_err_status_bad_param
+ *          if seq_num is invalid
+ *
+ */
+static srtp_err_status_t srtp_calc_aead_iv_srtcp(
+    srtp_session_keys_t *session_keys,
+    v128_t *iv,
+    uint32_t seq_num,
+    srtcp_hdr_t *hdr)
+{
+    v128_t in;
+    v128_t salt;
+
+    memset(&in, 0, sizeof(v128_t));
+    memset(&salt, 0, sizeof(v128_t));
+
+    in.v16[0] = 0;
+    memcpy(&in.v16[1], &hdr->ssrc, 4); /* still in network order! */
+    in.v16[3] = 0;
+
+    /*
+     *  The SRTCP index (seq_num) spans bits 0 through 30 inclusive.
+     *  The most significant bit should be zero.
+     */
+    if (seq_num & 0x80000000UL) {
+        return srtp_err_status_bad_param;
     }
-  }  
-
-  /* get tag length from stream context */
-  tag_len = auth_get_tag_length(stream->rtcp_auth); 
-
-  /*
-   * set encryption start and encryption length - if we're not
-   * providing confidentiality, set enc_start to NULL
-   */
-  enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
-  enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
-
-  /* all of the packet, except the header, gets encrypted */
-  /* NOTE: hdr->length is not usable - it refers to only the first
-	 RTCP report in the compound packet! */
-  /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-	 multiples of 32-bits (RFC 3550 6.1) */
-  trailer = (uint32_t *) ((char *)enc_start + enc_octet_len);
-
-  if (stream->rtcp_services & sec_serv_conf) {
-    *trailer = htonl(SRTCP_E_BIT);     /* set encrypt bit */    
-  } else {
-    enc_start = NULL;
-    enc_octet_len = 0;
-	/* 0 is network-order independant */
-    *trailer = 0x00000000;     /* set encrypt bit */    
-  }
-
-  /* 
-   * set the auth_start and auth_tag pointers to the proper locations
-   * (note that srtpc *always* provides authentication, unlike srtp)
-   */
-  /* Note: This would need to change for optional mikey data */
-  auth_start = (uint32_t *)hdr;
-  auth_tag = (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); 
-
-  /* perform EKT processing if needed */
-  ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len, 
-		 rdbx_get_packet_index(&stream->rtp_rdbx));
-
-  /* 
-   * check sequence number for overruns, and copy it into the packet
-   * if its value isn't too big
-   */
-  status = rdb_increment(&stream->rtcp_rdb);
-  if (status)
-    return status;
-  seq_num = rdb_get_value(&stream->rtcp_rdb);
-  *trailer |= htonl(seq_num);
-  debug_print(mod_srtp, "srtcp index: %x", seq_num);
-
-  /* 
-   * if we're using rindael counter mode, set nonce and seq 
-   */
-  if (stream->rtcp_cipher->type->id == AES_ICM) {
-    v128_t iv;
-    
-    iv.v32[0] = 0;
-    iv.v32[1] = hdr->ssrc;  /* still in network order! */
-    iv.v32[2] = htonl(seq_num >> 16);
-    iv.v32[3] = htonl(seq_num << 16);
-    status = cipher_set_iv(stream->rtcp_cipher, &iv);
-
-  } else {  
-    v128_t iv;
-    
-    /* otherwise, just set the index to seq_num */  
-    iv.v32[0] = 0;
-    iv.v32[1] = 0;
-    iv.v32[2] = 0;
-    iv.v32[3] = htonl(seq_num);
-    status = cipher_set_iv(stream->rtcp_cipher, &iv);
-  }
-  if (status)
-    return err_status_cipher_fail;
-
-  /* 
-   * if we're authenticating using a universal hash, put the keystream
-   * prefix into the authentication tag
-   */
-  
-  /* if auth_start is non-null, then put keystream into tag  */
-  if (auth_start) {
-
-    /* put keystream prefix into auth_tag */
-    prefix_len = auth_get_prefix_length(stream->rtcp_auth);    
-    status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
-
-    debug_print(mod_srtp, "keystream prefix: %s", 
-		octet_string_hex_string(auth_tag, prefix_len));
-
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* if we're encrypting, exor keystream into the message */
-  if (enc_start) {
-    status = cipher_encrypt(stream->rtcp_cipher, 
-			    (uint8_t *)enc_start, &enc_octet_len);
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* initialize auth func context */
-  auth_start(stream->rtcp_auth);
-
-  /* 
-   * run auth func over packet (including trailer), and write the
-   * result at auth_tag 
-   */
-  status = auth_compute(stream->rtcp_auth, 
-			(uint8_t *)auth_start, 
-			(*pkt_octet_len) + sizeof(srtcp_trailer_t), 
-			auth_tag);
-  debug_print(mod_srtp, "srtcp auth tag:    %s", 
-	      octet_string_hex_string(auth_tag, tag_len));
-  if (status)
-    return err_status_auth_fail;   
-    
-  /* increase the packet length by the length of the auth tag and seq_num*/
-  *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
-    
-  return err_status_ok;  
+    in.v32[2] = htonl(seq_num);
+
+    debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
+
+    /*
+     * Get the SALT value from the context
+     */
+    memcpy(salt.v8, session_keys->c_salt, 12);
+    debug_print(mod_srtp, "RTCP SALT = %s\n", v128_hex_string(&salt));
+
+    /*
+     * Finally, apply the SALT to the input
+     */
+    v128_xor(iv, &in, &salt);
+
+    return srtp_err_status_ok;
 }
 
-
-err_status_t 
-srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len) {
-  srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
-  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
-  uint32_t *auth_start;     /* pointer to start of auth. portion      */
-  uint32_t *trailer;        /* pointer to start of trailer            */
-  unsigned enc_octet_len = 0;/* number of octets in encrypted portion */
-  uint8_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
-  uint8_t tag_copy[SRTP_MAX_TAG_LEN];
-  err_status_t status;   
-  unsigned auth_len;
-  int tag_len;
-  srtp_stream_ctx_t *stream;
-  int prefix_len;
-  uint32_t seq_num;
-
-  /* we assume the hdr is 32-bit aligned to start */
-  /*
-   * look up ssrc in srtp_stream list, and process the packet with 
-   * the appropriate stream.  if we haven't seen this stream before,
-   * there's only one key for this srtp_session, and the cipher
-   * supports key-sharing, then we assume that a new stream using
-   * that key has just started up
-   */
-  stream = srtp_get_stream(ctx, hdr->ssrc);
-  if (stream == NULL) {
-    if (ctx->stream_template != NULL) {
-      stream = ctx->stream_template;
-
-      /* 
-       * check to see if stream_template has an EKT data structure, in
-       * which case we initialize the template using the EKT policy
-       * referenced by that data (which consists of decrypting the
-       * master key from the EKT field)
-       *
-       * this function initializes a *provisional* stream, and this
-       * stream should not be accepted until and unless the packet
-       * passes its authentication check
-       */ 
-      if (stream->ekt != NULL) {
-	status = srtp_stream_init_from_ekt(stream, srtcp_hdr, *pkt_octet_len);
-	if (status)
-	  return status;
-      }
-
-      debug_print(mod_srtp, "srtcp using provisional stream (SSRC: 0x%08x)", 
-		  hdr->ssrc);
-    } else {
-      /* no template stream, so we return an error */
-      return err_status_no_ctx;
-    } 
-  }
-  
-  /* get tag length from stream context */
-  tag_len = auth_get_tag_length(stream->rtcp_auth); 
-
-  /*
-   * set encryption start, encryption length, and trailer
-   */
-  enc_octet_len = *pkt_octet_len - 
-                  (octets_in_rtcp_header + tag_len + sizeof(srtcp_trailer_t));
-  /* index & E (encryption) bit follow normal data.  hdr->len
-	 is the number of words (32-bit) in the normal packet minus 1 */
-  /* This should point trailer to the word past the end of the
-	 normal data. */
-  /* This would need to be modified for optional mikey data */
-  /*
-   * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
-   *	 multiples of 32-bits (RFC 3550 6.1)
-   */
-  trailer = (uint32_t *) ((char *) hdr +
-		     *pkt_octet_len -(tag_len + sizeof(srtcp_trailer_t)));
-  if (*((unsigned char *) trailer) & SRTCP_E_BYTE_BIT) {
-    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;  
-  } else {
-    enc_octet_len = 0;
-    enc_start = NULL; /* this indicates that there's no encryption */
-  }
-
-  /* 
-   * set the auth_start and auth_tag pointers to the proper locations
-   * (note that srtcp *always* uses authentication, unlike srtp)
-   */
-  auth_start = (uint32_t *)hdr;
-  auth_len = *pkt_octet_len - tag_len;
-  auth_tag = (uint8_t *)hdr + auth_len;
-
-  /* 
-   * if EKT is in use, then we make a copy of the tag from the packet,
-   * and then zeroize the location of the base tag
-   *
-   * we first re-position the auth_tag pointer so that it points to
-   * the base tag
-   */
-  if (stream->ekt) {
-    auth_tag -= ekt_octets_after_base_tag(stream->ekt);
-    memcpy(tag_copy, auth_tag, tag_len);
-    octet_string_set_to_zero(auth_tag, tag_len);
-    auth_tag = tag_copy;
-    auth_len += tag_len;
-  }
-
-  /* 
-   * check the sequence number for replays
-   */
-  /* this is easier than dealing with bitfield access */
-  seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
-  debug_print(mod_srtp, "srtcp index: %x", seq_num);
-  status = rdb_check(&stream->rtcp_rdb, seq_num);
-  if (status)
-    return status;
-
-  /* 
-   * if we're using aes counter mode, set nonce and seq 
-   */
-  if (stream->rtcp_cipher->type->id == AES_ICM) {
+/*
+ * This code handles AEAD ciphers for outgoing RTCP.  We currently support
+ * AES-GCM mode with 128 or 256 bit keys.
+ */
+static srtp_err_status_t srtp_protect_rtcp_aead(
+    srtp_t ctx,
+    srtp_stream_ctx_t *stream,
+    void *rtcp_hdr,
+    unsigned int *pkt_octet_len,
+    srtp_session_keys_t *session_keys,
+    unsigned int use_mki)
+{
+    srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    uint32_t *trailer;              /* pointer to start of trailer            */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
+    srtp_err_status_t status;
+    uint32_t tag_len;
+    uint32_t seq_num;
     v128_t iv;
-
-    iv.v32[0] = 0;
-    iv.v32[1] = hdr->ssrc; /* still in network order! */
-    iv.v32[2] = htonl(seq_num >> 16);
-    iv.v32[3] = htonl(seq_num << 16);
-    status = cipher_set_iv(stream->rtcp_cipher, &iv);
-
-  } else {  
-    v128_t iv;
-    
-    /* otherwise, just set the index to seq_num */  
-    iv.v32[0] = 0;
-    iv.v32[1] = 0;
-    iv.v32[2] = 0;
-    iv.v32[3] = htonl(seq_num);
-    status = cipher_set_iv(stream->rtcp_cipher, &iv);
-
-  }
-  if (status)
-    return err_status_cipher_fail;
-
-  /* initialize auth func context */
-  auth_start(stream->rtcp_auth);
-
-  /* run auth func over packet, put result into tmp_tag */
-  status = auth_compute(stream->rtcp_auth, (uint8_t *)auth_start,  
-			auth_len, tmp_tag);
-  debug_print(mod_srtp, "srtcp computed tag:       %s", 
-	      octet_string_hex_string(tmp_tag, tag_len));
-  if (status)
-    return err_status_auth_fail;   
-  
-  /* compare the tag just computed with the one in the packet */
-  debug_print(mod_srtp, "srtcp tag from packet:    %s", 
-	      octet_string_hex_string(auth_tag, tag_len));  
-  if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
-    return err_status_auth_fail;
-
-  /* 
-   * if we're authenticating using a universal hash, put the keystream
-   * prefix into the authentication tag
-   */
-  prefix_len = auth_get_prefix_length(stream->rtcp_auth);    
-  if (prefix_len) {
-    status = cipher_output(stream->rtcp_cipher, auth_tag, prefix_len);
-    debug_print(mod_srtp, "keystream prefix: %s", 
-		octet_string_hex_string(auth_tag, prefix_len));
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* if we're decrypting, exor keystream into the message */
-  if (enc_start) {
-    status = cipher_decrypt(stream->rtcp_cipher, 
-			    (uint8_t *)enc_start, &enc_octet_len);
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* decrease the packet length by the length of the auth tag and seq_num */
-  *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
-
-  /*
-   * if EKT is in effect, subtract the EKT data out of the packet
-   * length
-   */
-  *pkt_octet_len -= ekt_octets_after_base_tag(stream->ekt);
-
-  /* 
-   * verify that stream is for received traffic - this check will
-   * detect SSRC collisions, since a stream that appears in both
-   * srtp_protect() and srtp_unprotect() will fail this test in one of
-   * those functions.
-   *
-   * we do this check *after* the authentication check, so that the
-   * latter check will catch any attempts to fool us into thinking
-   * that we've got a collision
-   */
-  if (stream->direction != dir_srtp_receiver) {
-    if (stream->direction == dir_unknown) {
-      stream->direction = dir_srtp_receiver;
+    uint32_t tseq;
+    unsigned int mki_size = 0;
+
+    /* get tag length from stream context */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtcp_auth);
+
+    /*
+     * set encryption start and encryption length - if we're not
+     * providing confidentiality, set enc_start to NULL
+     */
+    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
+    enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
+
+    /* NOTE: hdr->length is not usable - it refers to only the first
+     * RTCP report in the compound packet!
+     */
+    /* NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
+     * multiples of 32-bits (RFC 3550 6.1)
+     */
+    trailer = (uint32_t *)((char *)enc_start + enc_octet_len + tag_len);
+
+    if (stream->rtcp_services & sec_serv_conf) {
+        *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
     } else {
-      srtp_handle_event(ctx, stream, event_ssrc_collision);
+        enc_start = NULL;
+        enc_octet_len = 0;
+        /* 0 is network-order independant */
+        *trailer = 0x00000000; /* set encrypt bit */
     }
-  }
-
-  /* 
-   * if the stream is a 'provisional' one, in which the template context
-   * is used, then we need to allocate a new stream at this point, since
-   * the authentication passed
-   */
-  if (stream == ctx->stream_template) {  
-    srtp_stream_ctx_t *new_stream;
-
-    /* 
-     * allocate and initialize a new stream 
-     * 
-     * note that we indicate failure if we can't allocate the new
-     * stream, and some implementations will want to not return
-     * failure here
+
+    mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len + tag_len +
+                                   sizeof(srtcp_trailer_t),
+                               session_keys, use_mki);
+
+    /*
+     * set the auth_tag pointer to the proper location, which is after
+     * the payload, but before the trailer
+     * (note that srtpc *always* provides authentication, unlike srtp)
+     */
+    /* Note: This would need to change for optional mikey data */
+    auth_tag = (uint8_t *)hdr + *pkt_octet_len;
+
+    /*
+     * check sequence number for overruns, and copy it into the packet
+     * if its value isn't too big
+     */
+    status = srtp_rdb_increment(&stream->rtcp_rdb);
+    if (status) {
+        return status;
+    }
+    seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
+    *trailer |= htonl(seq_num);
+    debug_print(mod_srtp, "srtcp index: %x", seq_num);
+
+    /*
+     * Calculate and set the IV
+     */
+    status = srtp_calc_aead_iv_srtcp(session_keys, &iv, seq_num, hdr);
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+    status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                srtp_direction_encrypt);
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     * Set the AAD for GCM mode
      */
-    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
-    if (status)
-      return status;
-    
-    /* add new stream to the head of the stream_list */
-    new_stream->next = ctx->stream_list;
-    ctx->stream_list = new_stream;
-    
-    /* set stream (the pointer used in this function) */
-    stream = new_stream;
-  }
-
-  /* we've passed the authentication check, so add seq_num to the rdb */
-  rdb_add_index(&stream->rtcp_rdb, seq_num);
-    
-    
-  return err_status_ok;  
+    if (enc_start) {
+        /*
+         * If payload encryption is enabled, then the AAD consist of
+         * the RTCP header and the seq# at the end of the packet
+         */
+        status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)hdr,
+                                     octets_in_rtcp_header);
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+    } else {
+        /*
+         * Since payload encryption is not enabled, we must authenticate
+         * the entire packet as described in RFC 7714 (Section 9.3. Data
+         * Types in Unencrypted SRTCP Compound Packets)
+         */
+        status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)hdr,
+                                     *pkt_octet_len);
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+    }
+    /*
+     * Process the sequence# as AAD
+     */
+    tseq = *trailer;
+    status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
+                                 sizeof(srtcp_trailer_t));
+    if (status) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* if we're encrypting, exor keystream into the message */
+    if (enc_start) {
+        status = srtp_cipher_encrypt(session_keys->rtcp_cipher,
+                                     (uint8_t *)enc_start, &enc_octet_len);
+        if (status) {
+            return srtp_err_status_cipher_fail;
+        }
+        /*
+         * Get the tag and append that to the output
+         */
+        status = srtp_cipher_get_tag(session_keys->rtcp_cipher,
+                                     (uint8_t *)auth_tag, &tag_len);
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+        enc_octet_len += tag_len;
+    } else {
+        /*
+         * Even though we're not encrypting the payload, we need
+         * to run the cipher to get the auth tag.
+         */
+        unsigned int nolen = 0;
+        status = srtp_cipher_encrypt(session_keys->rtcp_cipher, NULL, &nolen);
+        if (status) {
+            return srtp_err_status_cipher_fail;
+        }
+        /*
+         * Get the tag and append that to the output
+         */
+        status = srtp_cipher_get_tag(session_keys->rtcp_cipher,
+                                     (uint8_t *)auth_tag, &tag_len);
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+        enc_octet_len += tag_len;
+    }
+
+    /* increase the packet length by the length of the auth tag and seq_num*/
+    *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
+
+    /* increase the packet by the mki_size */
+    *pkt_octet_len += mki_size;
+
+    return srtp_err_status_ok;
 }
 
-
-
 /*
- * dtls keying for srtp 
+ * This function handles incoming SRTCP packets while in AEAD mode,
+ * which currently supports AES-GCM encryption.  Note, the auth tag is
+ * at the end of the packet stream and is automatically checked by GCM
+ * when decrypting the payload.
  */
-
-err_status_t
-crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy, 
-				       srtp_profile_t profile) {
-
-  /* set SRTP policy from the SRTP profile in the key set */
-  switch(profile) {
-  case srtp_profile_aes128_cm_sha1_80:
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes128_cm_sha1_32:
-    crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_null_sha1_80:
-    crypto_policy_set_null_cipher_hmac_sha1_80(policy);
-    crypto_policy_set_null_cipher_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes256_cm_sha1_80:
-    crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
-    crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes256_cm_sha1_32:
-    crypto_policy_set_aes_cm_256_hmac_sha1_32(policy);
-    crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
-    break;
-    /* the following profiles are not (yet) supported */
-  case srtp_profile_null_sha1_32:
-  default:
-    return err_status_bad_param;
-  }
-
-  return err_status_ok;
+static srtp_err_status_t srtp_unprotect_rtcp_aead(
+    srtp_t ctx,
+    srtp_stream_ctx_t *stream,
+    void *srtcp_hdr,
+    unsigned int *pkt_octet_len,
+    srtp_session_keys_t *session_keys,
+    unsigned int use_mki)
+{
+    srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    uint32_t *trailer;              /* pointer to start of trailer            */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
+    srtp_err_status_t status;
+    int tag_len;
+    unsigned int tmp_len;
+    uint32_t seq_num;
+    v128_t iv;
+    uint32_t tseq;
+    unsigned int mki_size = 0;
+
+    /* get tag length from stream context */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtcp_auth);
+
+    if (use_mki) {
+        mki_size = session_keys->mki_size;
+    }
+
+    /*
+     * set encryption start, encryption length, and trailer
+     */
+    /* index & E (encryption) bit follow normal data. hdr->len is the number of
+     * words (32-bit) in the normal packet minus 1
+     */
+    /* This should point trailer to the word past the end of the normal data. */
+    /* This would need to be modified for optional mikey data */
+    /*
+     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
+     *   multiples of 32-bits (RFC 3550 6.1)
+     */
+    trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                           sizeof(srtcp_trailer_t) - mki_size);
+    /*
+     * We pass the tag down to the cipher when doing GCM mode
+     */
+    enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header +
+                                      sizeof(srtcp_trailer_t) + mki_size);
+    auth_tag = (uint8_t *)hdr + *pkt_octet_len - tag_len - mki_size -
+               sizeof(srtcp_trailer_t);
+
+    if (*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) {
+        enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
+    } else {
+        enc_octet_len = 0;
+        enc_start = NULL; /* this indicates that there's no encryption */
+    }
+
+    /*
+     * check the sequence number for replays
+     */
+    /* this is easier than dealing with bitfield access */
+    seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
+    debug_print(mod_srtp, "srtcp index: %x", seq_num);
+    status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * Calculate and set the IV
+     */
+    status = srtp_calc_aead_iv_srtcp(session_keys, &iv, seq_num, hdr);
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+    status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                srtp_direction_decrypt);
+    if (status) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    /*
+     * Set the AAD for GCM mode
+     */
+    if (enc_start) {
+        /*
+         * If payload encryption is enabled, then the AAD consist of
+         * the RTCP header and the seq# at the end of the packet
+         */
+        status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)hdr,
+                                     octets_in_rtcp_header);
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+    } else {
+        /*
+         * Since payload encryption is not enabled, we must authenticate
+         * the entire packet as described in RFC 7714 (Section 9.3. Data
+         * Types in Unencrypted SRTCP Compound Packets)
+         */
+        status = srtp_cipher_set_aad(
+            session_keys->rtcp_cipher, (uint8_t *)hdr,
+            (*pkt_octet_len - tag_len - sizeof(srtcp_trailer_t) - mki_size));
+        if (status) {
+            return (srtp_err_status_cipher_fail);
+        }
+    }
+
+    /*
+     * Process the sequence# as AAD
+     */
+    tseq = *trailer;
+    status = srtp_cipher_set_aad(session_keys->rtcp_cipher, (uint8_t *)&tseq,
+                                 sizeof(srtcp_trailer_t));
+    if (status) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* if we're decrypting, exor keystream into the message */
+    if (enc_start) {
+        status = srtp_cipher_decrypt(session_keys->rtcp_cipher,
+                                     (uint8_t *)enc_start, &enc_octet_len);
+        if (status) {
+            return status;
+        }
+    } else {
+        /*
+         * Still need to run the cipher to check the tag
+         */
+        tmp_len = tag_len;
+        status = srtp_cipher_decrypt(session_keys->rtcp_cipher,
+                                     (uint8_t *)auth_tag, &tmp_len);
+        if (status) {
+            return status;
+        }
+    }
+
+    /* decrease the packet length by the length of the auth tag and seq_num*/
+    *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t) + mki_size);
+
+    /*
+     * verify that stream is for received traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     *
+     * we do this check *after* the authentication check, so that the
+     * latter check will catch any attempts to fool us into thinking
+     * that we've got a collision
+     */
+    if (stream->direction != dir_srtp_receiver) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_receiver;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    /*
+     * if the stream is a 'provisional' one, in which the template context
+     * is used, then we need to allocate a new stream at this point, since
+     * the authentication passed
+     */
+    if (stream == ctx->stream_template) {
+        srtp_stream_ctx_t *new_stream;
+
+        /*
+         * allocate and initialize a new stream
+         *
+         * note that we indicate failure if we can't allocate the new
+         * stream, and some implementations will want to not return
+         * failure here
+         */
+        status =
+            srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+        if (status) {
+            return status;
+        }
+
+        /* add new stream to the head of the stream_list */
+        new_stream->next = ctx->stream_list;
+        ctx->stream_list = new_stream;
+
+        /* set stream (the pointer used in this function) */
+        stream = new_stream;
+    }
+
+    /* we've passed the authentication check, so add seq_num to the rdb */
+    srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_protect_rtcp(srtp_t ctx,
+                                    void *rtcp_hdr,
+                                    int *pkt_octet_len)
+{
+    return srtp_protect_rtcp_mki(ctx, rtcp_hdr, pkt_octet_len, 0, 0);
 }
 
-err_status_t
-crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy, 
-					srtp_profile_t profile) {
-
-  /* set SRTP policy from the SRTP profile in the key set */
-  switch(profile) {
-  case srtp_profile_aes128_cm_sha1_80:
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes128_cm_sha1_32:
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_null_sha1_80:
-    crypto_policy_set_null_cipher_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes256_cm_sha1_80:
-    crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
-    break;
-  case srtp_profile_aes256_cm_sha1_32:
-    crypto_policy_set_aes_cm_256_hmac_sha1_80(policy);
-    break;
+srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx,
+                                        void *rtcp_hdr,
+                                        int *pkt_octet_len,
+                                        unsigned int use_mki,
+                                        unsigned int mki_index)
+{
+    srtcp_hdr_t *hdr = (srtcp_hdr_t *)rtcp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    uint32_t *auth_start;           /* pointer to start of auth. portion      */
+    uint32_t *trailer;              /* pointer to start of trailer            */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
+    srtp_err_status_t status;
+    int tag_len;
+    srtp_stream_ctx_t *stream;
+    uint32_t prefix_len;
+    uint32_t seq_num;
+    unsigned int mki_size = 0;
+    srtp_session_keys_t *session_keys = NULL;
+
+    /* we assume the hdr is 32-bit aligned to start */
+
+    /* check the packet length - it must at least contain a full header */
+    if (*pkt_octet_len < octets_in_rtcp_header)
+        return srtp_err_status_bad_param;
+
+    /*
+     * look up ssrc in srtp_stream list, and process the packet with
+     * the appropriate stream.  if we haven't seen this stream before,
+     * there's only one key for this srtp_session, and the cipher
+     * supports key-sharing, then we assume that a new stream using
+     * that key has just started up
+     */
+    stream = srtp_get_stream(ctx, hdr->ssrc);
+    if (stream == NULL) {
+        if (ctx->stream_template != NULL) {
+            srtp_stream_ctx_t *new_stream;
+
+            /* allocate and initialize a new stream */
+            status =
+                srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+            if (status)
+                return status;
+
+            /* add new stream to the head of the stream_list */
+            new_stream->next = ctx->stream_list;
+            ctx->stream_list = new_stream;
+
+            /* set stream (the pointer used in this function) */
+            stream = new_stream;
+        } else {
+            /* no template stream, so we return an error */
+            return srtp_err_status_no_ctx;
+        }
+    }
+
+    /*
+     * verify that stream is for sending traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     */
+    if (stream->direction != dir_srtp_sender) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_sender;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    session_keys =
+        srtp_get_session_keys_with_mki_index(stream, use_mki, mki_index);
+
+    /*
+     * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
+     * the request to our AEAD handler.
+     */
+    if (session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_128 ||
+        session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_256) {
+        return srtp_protect_rtcp_aead(ctx, stream, rtcp_hdr,
+                                      (unsigned int *)pkt_octet_len,
+                                      session_keys, use_mki);
+    }
+
+    /* get tag length from stream context */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtcp_auth);
+
+    /*
+     * set encryption start and encryption length - if we're not
+     * providing confidentiality, set enc_start to NULL
+     */
+    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
+    enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
+
+    /* all of the packet, except the header, gets encrypted */
+    /*
+     * NOTE: hdr->length is not usable - it refers to only the first RTCP report
+     * in the compound packet!
+     */
+    /*
+     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
+     * multiples of 32-bits (RFC 3550 6.1)
+     */
+    trailer = (uint32_t *)((char *)enc_start + enc_octet_len);
+
+    if (stream->rtcp_services & sec_serv_conf) {
+        *trailer = htonl(SRTCP_E_BIT); /* set encrypt bit */
+    } else {
+        enc_start = NULL;
+        enc_octet_len = 0;
+        /* 0 is network-order independant */
+        *trailer = 0x00000000; /* set encrypt bit */
+    }
+
+    mki_size = srtp_inject_mki((uint8_t *)hdr + *pkt_octet_len +
+                                   sizeof(srtcp_trailer_t),
+                               session_keys, use_mki);
+
+    /*
+     * set the auth_start and auth_tag pointers to the proper locations
+     * (note that srtpc *always* provides authentication, unlike srtp)
+     */
+    /* Note: This would need to change for optional mikey data */
+    auth_start = (uint32_t *)hdr;
+    auth_tag =
+        (uint8_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t) + mki_size;
+
+    /* perform EKT processing if needed */
+    srtp_ekt_write_data(stream->ekt, auth_tag, tag_len, pkt_octet_len,
+                        srtp_rdbx_get_packet_index(&stream->rtp_rdbx));
+
+    /*
+     * check sequence number for overruns, and copy it into the packet
+     * if its value isn't too big
+     */
+    status = srtp_rdb_increment(&stream->rtcp_rdb);
+    if (status)
+        return status;
+    seq_num = srtp_rdb_get_value(&stream->rtcp_rdb);
+    *trailer |= htonl(seq_num);
+    debug_print(mod_srtp, "srtcp index: %x", seq_num);
+
+    /*
+     * if we're using rindael counter mode, set nonce and seq
+     */
+    if (session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_128 ||
+        session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_192 ||
+        session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_256) {
+        v128_t iv;
+
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc; /* still in network order! */
+        iv.v32[2] = htonl(seq_num >> 16);
+        iv.v32[3] = htonl(seq_num << 16);
+        status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_encrypt);
+
+    } else {
+        v128_t iv;
+
+        /* otherwise, just set the index to seq_num */
+        iv.v32[0] = 0;
+        iv.v32[1] = 0;
+        iv.v32[2] = 0;
+        iv.v32[3] = htonl(seq_num);
+        status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_encrypt);
+    }
+    if (status)
+        return srtp_err_status_cipher_fail;
+
+    /*
+     * if we're authenticating using a universal hash, put the keystream
+     * prefix into the authentication tag
+     */
+
+    /* if auth_start is non-null, then put keystream into tag  */
+    if (auth_start) {
+        /* put keystream prefix into auth_tag */
+        prefix_len = srtp_auth_get_prefix_length(session_keys->rtcp_auth);
+        status = srtp_cipher_output(session_keys->rtcp_cipher, auth_tag,
+                                    &prefix_len);
+
+        debug_print(mod_srtp, "keystream prefix: %s",
+                    srtp_octet_string_hex_string(auth_tag, prefix_len));
+
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /* if we're encrypting, exor keystream into the message */
+    if (enc_start) {
+        status = srtp_cipher_encrypt(session_keys->rtcp_cipher,
+                                     (uint8_t *)enc_start, &enc_octet_len);
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /* initialize auth func context */
+    srtp_auth_start(session_keys->rtcp_auth);
+
+    /*
+     * run auth func over packet (including trailer), and write the
+     * result at auth_tag
+     */
+    status =
+        srtp_auth_compute(session_keys->rtcp_auth, (uint8_t *)auth_start,
+                          (*pkt_octet_len) + sizeof(srtcp_trailer_t), auth_tag);
+    debug_print(mod_srtp, "srtcp auth tag:    %s",
+                srtp_octet_string_hex_string(auth_tag, tag_len));
+    if (status)
+        return srtp_err_status_auth_fail;
+
+    /* increase the packet length by the length of the auth tag and seq_num*/
+    *pkt_octet_len += (tag_len + sizeof(srtcp_trailer_t));
+
+    /* increase the packet by the mki_size */
+    *pkt_octet_len += mki_size;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_unprotect_rtcp(srtp_t ctx,
+                                      void *srtcp_hdr,
+                                      int *pkt_octet_len)
+{
+    return srtp_unprotect_rtcp_mki(ctx, srtcp_hdr, pkt_octet_len, 0);
+}
+
+srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx,
+                                          void *srtcp_hdr,
+                                          int *pkt_octet_len,
+                                          unsigned int use_mki)
+{
+    srtcp_hdr_t *hdr = (srtcp_hdr_t *)srtcp_hdr;
+    uint32_t *enc_start;            /* pointer to start of encrypted portion  */
+    uint32_t *auth_start;           /* pointer to start of auth. portion      */
+    uint32_t *trailer;              /* pointer to start of trailer            */
+    unsigned int enc_octet_len = 0; /* number of octets in encrypted portion */
+    uint8_t *auth_tag = NULL;       /* location of auth_tag within packet     */
+    uint8_t tmp_tag[SRTP_MAX_TAG_LEN];
+    uint8_t tag_copy[SRTP_MAX_TAG_LEN];
+    srtp_err_status_t status;
+    unsigned int auth_len;
+    int tag_len;
+    srtp_stream_ctx_t *stream;
+    uint32_t prefix_len;
+    uint32_t seq_num;
+    int e_bit_in_packet; /* whether the E-bit was found in the packet */
+    int sec_serv_confidentiality; /* whether confidentiality was requested */
+    unsigned int mki_size = 0;
+    srtp_session_keys_t *session_keys = NULL;
+
+    /* we assume the hdr is 32-bit aligned to start */
+
+    if (*pkt_octet_len < 0)
+        return srtp_err_status_bad_param;
+
+    /*
+     * check that the length value is sane; we'll check again once we
+     * know the tag length, but we at least want to know that it is
+     * a positive value
+     */
+    if ((unsigned int)(*pkt_octet_len) <
+        octets_in_rtcp_header + sizeof(srtcp_trailer_t))
+        return srtp_err_status_bad_param;
+
+    /*
+     * look up ssrc in srtp_stream list, and process the packet with
+     * the appropriate stream.  if we haven't seen this stream before,
+     * there's only one key for this srtp_session, and the cipher
+     * supports key-sharing, then we assume that a new stream using
+     * that key has just started up
+     */
+    stream = srtp_get_stream(ctx, hdr->ssrc);
+    if (stream == NULL) {
+        if (ctx->stream_template != NULL) {
+            stream = ctx->stream_template;
+
+            /*
+             * check to see if stream_template has an EKT data structure, in
+             * which case we initialize the template using the EKT policy
+             * referenced by that data (which consists of decrypting the
+             * master key from the EKT field)
+             *
+             * this function initializes a *provisional* stream, and this
+             * stream should not be accepted until and unless the packet
+             * passes its authentication check
+             */
+            if (stream->ekt != NULL) {
+                status = srtp_stream_init_from_ekt(stream, srtcp_hdr,
+                                                   *pkt_octet_len);
+                if (status)
+                    return status;
+            }
+
+            debug_print(mod_srtp,
+                        "srtcp using provisional stream (SSRC: 0x%08x)",
+                        ntohl(hdr->ssrc));
+        } else {
+            /* no template stream, so we return an error */
+            return srtp_err_status_no_ctx;
+        }
+    }
+
+    /*
+     * Determine if MKI is being used and what session keys should be used
+     */
+    if (use_mki) {
+        session_keys = srtp_get_session_keys(
+            stream, (uint8_t *)hdr, (const unsigned int *)pkt_octet_len,
+            &mki_size);
+
+        if (session_keys == NULL)
+            return srtp_err_status_bad_mki;
+    } else {
+        session_keys = &stream->session_keys[0];
+    }
+
+    /* get tag length from stream context */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtcp_auth);
+
+    /* check the packet length - it must contain at least a full RTCP
+       header, an auth tag (if applicable), and the SRTCP encrypted flag
+       and 31-bit index value */
+    if (*pkt_octet_len < (int)(octets_in_rtcp_header + tag_len + mki_size +
+                               sizeof(srtcp_trailer_t))) {
+        return srtp_err_status_bad_param;
+    }
+
+    /*
+     * Check if this is an AEAD stream (GCM mode).  If so, then dispatch
+     * the request to our AEAD handler.
+     */
+    if (session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_128 ||
+        session_keys->rtp_cipher->algorithm == SRTP_AES_GCM_256) {
+        return srtp_unprotect_rtcp_aead(ctx, stream, srtcp_hdr,
+                                        (unsigned int *)pkt_octet_len,
+                                        session_keys, mki_size);
+    }
+
+    sec_serv_confidentiality = stream->rtcp_services == sec_serv_conf ||
+                               stream->rtcp_services == sec_serv_conf_and_auth;
+
+    /*
+     * set encryption start, encryption length, and trailer
+     */
+    enc_octet_len = *pkt_octet_len - (octets_in_rtcp_header + tag_len +
+                                      mki_size + sizeof(srtcp_trailer_t));
+    /*
+     *index & E (encryption) bit follow normal data. hdr->len is the number of
+     * words (32-bit) in the normal packet minus 1
+     */
+    /* This should point trailer to the word past the end of the normal data. */
+    /* This would need to be modified for optional mikey data */
+    /*
+     * NOTE: trailer is 32-bit aligned because RTCP 'packets' are always
+     *   multiples of 32-bits (RFC 3550 6.1)
+     */
+    trailer = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                           (tag_len + mki_size + sizeof(srtcp_trailer_t)));
+    e_bit_in_packet =
+        (*((unsigned char *)trailer) & SRTCP_E_BYTE_BIT) == SRTCP_E_BYTE_BIT;
+    if (e_bit_in_packet != sec_serv_confidentiality) {
+        return srtp_err_status_cant_check;
+    }
+    if (sec_serv_confidentiality) {
+        enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
+    } else {
+        enc_octet_len = 0;
+        enc_start = NULL; /* this indicates that there's no encryption */
+    }
+
+    /*
+     * set the auth_start and auth_tag pointers to the proper locations
+     * (note that srtcp *always* uses authentication, unlike srtp)
+     */
+    auth_start = (uint32_t *)hdr;
+
+    /*
+     * The location of the auth tag in the packet needs to know MKI
+     * could be present.  The data needed to calculate the Auth tag
+     * must not include the MKI
+     */
+    auth_len = *pkt_octet_len - tag_len - mki_size;
+    auth_tag = (uint8_t *)hdr + auth_len + mki_size;
+
+    /*
+     * if EKT is in use, then we make a copy of the tag from the packet,
+     * and then zeroize the location of the base tag
+     *
+     * we first re-position the auth_tag pointer so that it points to
+     * the base tag
+     */
+    if (stream->ekt) {
+        auth_tag -= srtp_ekt_octets_after_base_tag(stream->ekt);
+        memcpy(tag_copy, auth_tag, tag_len);
+        octet_string_set_to_zero(auth_tag, tag_len);
+        auth_tag = tag_copy;
+        auth_len += tag_len;
+    }
+
+    /*
+     * check the sequence number for replays
+     */
+    /* this is easier than dealing with bitfield access */
+    seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
+    debug_print(mod_srtp, "srtcp index: %x", seq_num);
+    status = srtp_rdb_check(&stream->rtcp_rdb, seq_num);
+    if (status)
+        return status;
+
+    /*
+     * if we're using aes counter mode, set nonce and seq
+     */
+    if (session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_128 ||
+        session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_192 ||
+        session_keys->rtcp_cipher->type->id == SRTP_AES_ICM_256) {
+        v128_t iv;
+
+        iv.v32[0] = 0;
+        iv.v32[1] = hdr->ssrc; /* still in network order! */
+        iv.v32[2] = htonl(seq_num >> 16);
+        iv.v32[3] = htonl(seq_num << 16);
+        status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_decrypt);
+
+    } else {
+        v128_t iv;
+
+        /* otherwise, just set the index to seq_num */
+        iv.v32[0] = 0;
+        iv.v32[1] = 0;
+        iv.v32[2] = 0;
+        iv.v32[3] = htonl(seq_num);
+        status = srtp_cipher_set_iv(session_keys->rtcp_cipher, (uint8_t *)&iv,
+                                    srtp_direction_decrypt);
+    }
+    if (status)
+        return srtp_err_status_cipher_fail;
+
+    /* initialize auth func context */
+    srtp_auth_start(session_keys->rtcp_auth);
+
+    /* run auth func over packet, put result into tmp_tag */
+    status = srtp_auth_compute(session_keys->rtcp_auth, (uint8_t *)auth_start,
+                               auth_len, tmp_tag);
+    debug_print(mod_srtp, "srtcp computed tag:       %s",
+                srtp_octet_string_hex_string(tmp_tag, tag_len));
+    if (status)
+        return srtp_err_status_auth_fail;
+
+    /* compare the tag just computed with the one in the packet */
+    debug_print(mod_srtp, "srtcp tag from packet:    %s",
+                srtp_octet_string_hex_string(auth_tag, tag_len));
+    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
+        return srtp_err_status_auth_fail;
+
+    /*
+     * if we're authenticating using a universal hash, put the keystream
+     * prefix into the authentication tag
+     */
+    prefix_len = srtp_auth_get_prefix_length(session_keys->rtcp_auth);
+    if (prefix_len) {
+        status = srtp_cipher_output(session_keys->rtcp_cipher, auth_tag,
+                                    &prefix_len);
+        debug_print(mod_srtp, "keystream prefix: %s",
+                    srtp_octet_string_hex_string(auth_tag, prefix_len));
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /* if we're decrypting, exor keystream into the message */
+    if (enc_start) {
+        status = srtp_cipher_decrypt(session_keys->rtcp_cipher,
+                                     (uint8_t *)enc_start, &enc_octet_len);
+        if (status)
+            return srtp_err_status_cipher_fail;
+    }
+
+    /* decrease the packet length by the length of the auth tag and seq_num */
+    *pkt_octet_len -= (tag_len + sizeof(srtcp_trailer_t));
+
+    /* decrease the packet length by the length of the mki_size */
+    *pkt_octet_len -= mki_size;
+
+    /*
+     * if EKT is in effect, subtract the EKT data out of the packet
+     * length
+     */
+    *pkt_octet_len -= srtp_ekt_octets_after_base_tag(stream->ekt);
+
+    /*
+     * verify that stream is for received traffic - this check will
+     * detect SSRC collisions, since a stream that appears in both
+     * srtp_protect() and srtp_unprotect() will fail this test in one of
+     * those functions.
+     *
+     * we do this check *after* the authentication check, so that the
+     * latter check will catch any attempts to fool us into thinking
+     * that we've got a collision
+     */
+    if (stream->direction != dir_srtp_receiver) {
+        if (stream->direction == dir_unknown) {
+            stream->direction = dir_srtp_receiver;
+        } else {
+            srtp_handle_event(ctx, stream, event_ssrc_collision);
+        }
+    }
+
+    /*
+     * if the stream is a 'provisional' one, in which the template context
+     * is used, then we need to allocate a new stream at this point, since
+     * the authentication passed
+     */
+    if (stream == ctx->stream_template) {
+        srtp_stream_ctx_t *new_stream;
+
+        /*
+         * allocate and initialize a new stream
+         *
+         * note that we indicate failure if we can't allocate the new
+         * stream, and some implementations will want to not return
+         * failure here
+         */
+        status =
+            srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream);
+        if (status)
+            return status;
+
+        /* add new stream to the head of the stream_list */
+        new_stream->next = ctx->stream_list;
+        ctx->stream_list = new_stream;
+
+        /* set stream (the pointer used in this function) */
+        stream = new_stream;
+    }
+
+    /* we've passed the authentication check, so add seq_num to the rdb */
+    srtp_rdb_add_index(&stream->rtcp_rdb, seq_num);
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * user data within srtp_t context
+ */
+
+void srtp_set_user_data(srtp_t ctx, void *data)
+{
+    ctx->user_data = data;
+}
+
+void *srtp_get_user_data(srtp_t ctx)
+{
+    return ctx->user_data;
+}
+
+/*
+ * dtls keying for srtp
+ */
+
+srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
+    srtp_crypto_policy_t *policy,
+    srtp_profile_t profile)
+{
+    /* set SRTP policy from the SRTP profile in the key set */
+    switch (profile) {
+    case srtp_profile_aes128_cm_sha1_80:
+        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
+        break;
+    case srtp_profile_aes128_cm_sha1_32:
+        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(policy);
+        break;
+    case srtp_profile_null_sha1_80:
+        srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
+        break;
+#if defined(OPENSSL)
+    case srtp_profile_aead_aes_128_gcm:
+        srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
+        break;
+    case srtp_profile_aead_aes_256_gcm:
+        srtp_crypto_policy_set_aes_gcm_256_16_auth(policy);
+        break;
+#endif
     /* the following profiles are not (yet) supported */
-  case srtp_profile_null_sha1_32:
-  default:
-    return err_status_bad_param;
-  }
-
-  return err_status_ok;
+    case srtp_profile_null_sha1_32:
+    default:
+        return srtp_err_status_bad_param;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtcp(
+    srtp_crypto_policy_t *policy,
+    srtp_profile_t profile)
+{
+    /* set SRTP policy from the SRTP profile in the key set */
+    switch (profile) {
+    case srtp_profile_aes128_cm_sha1_80:
+        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
+        break;
+    case srtp_profile_aes128_cm_sha1_32:
+        /* We do not honor the 32-bit auth tag request since
+         * this is not compliant with RFC 3711 */
+        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(policy);
+        break;
+    case srtp_profile_null_sha1_80:
+        srtp_crypto_policy_set_null_cipher_hmac_sha1_80(policy);
+        break;
+#if defined(OPENSSL)
+    case srtp_profile_aead_aes_128_gcm:
+        srtp_crypto_policy_set_aes_gcm_128_16_auth(policy);
+        break;
+    case srtp_profile_aead_aes_256_gcm:
+        srtp_crypto_policy_set_aes_gcm_256_16_auth(policy);
+        break;
+#endif
+    /* the following profiles are not (yet) supported */
+    case srtp_profile_null_sha1_32:
+    default:
+        return srtp_err_status_bad_param;
+    }
+
+    return srtp_err_status_ok;
+}
+
+void srtp_append_salt_to_key(uint8_t *key,
+                             unsigned int bytes_in_key,
+                             uint8_t *salt,
+                             unsigned int bytes_in_salt)
+{
+    memcpy(key + bytes_in_key, salt, bytes_in_salt);
 }
 
-void
-append_salt_to_key(uint8_t *key, unsigned int bytes_in_key,
-		   uint8_t *salt, unsigned int bytes_in_salt) {
-
-  memcpy(key + bytes_in_key, salt, bytes_in_salt);
-
+unsigned int srtp_profile_get_master_key_length(srtp_profile_t profile)
+{
+    switch (profile) {
+    case srtp_profile_aes128_cm_sha1_80:
+        return SRTP_AES_128_KEY_LEN;
+        break;
+    case srtp_profile_aes128_cm_sha1_32:
+        return SRTP_AES_128_KEY_LEN;
+        break;
+    case srtp_profile_null_sha1_80:
+        return SRTP_AES_128_KEY_LEN;
+        break;
+    case srtp_profile_aead_aes_128_gcm:
+        return SRTP_AES_128_KEY_LEN;
+        break;
+    case srtp_profile_aead_aes_256_gcm:
+        return SRTP_AES_256_KEY_LEN;
+        break;
+    /* the following profiles are not (yet) supported */
+    case srtp_profile_null_sha1_32:
+    default:
+        return 0; /* indicate error by returning a zero */
+    }
+}
+
+unsigned int srtp_profile_get_master_salt_length(srtp_profile_t profile)
+{
+    switch (profile) {
+    case srtp_profile_aes128_cm_sha1_80:
+        return SRTP_SALT_LEN;
+        break;
+    case srtp_profile_aes128_cm_sha1_32:
+        return SRTP_SALT_LEN;
+        break;
+    case srtp_profile_null_sha1_80:
+        return SRTP_SALT_LEN;
+        break;
+    case srtp_profile_aead_aes_128_gcm:
+        return SRTP_AEAD_SALT_LEN;
+        break;
+    case srtp_profile_aead_aes_256_gcm:
+        return SRTP_AEAD_SALT_LEN;
+        break;
+    /* the following profiles are not (yet) supported */
+    case srtp_profile_null_sha1_32:
+    default:
+        return 0; /* indicate error by returning a zero */
+    }
 }
 
-unsigned int
-srtp_profile_get_master_key_length(srtp_profile_t profile) {
-
-  switch(profile) {
-  case srtp_profile_aes128_cm_sha1_80:
-    return 16;
-    break;
-  case srtp_profile_aes128_cm_sha1_32:
-    return 16;
-    break;
-  case srtp_profile_null_sha1_80:
-    return 16;
-    break;
-  case srtp_profile_aes256_cm_sha1_80:
-    return 32;
-    break;
-  case srtp_profile_aes256_cm_sha1_32:
-    return 32;
-    break;
-    /* the following profiles are not (yet) supported */
-  case srtp_profile_null_sha1_32:
-  default:
-    return 0;  /* indicate error by returning a zero */
-  }
+srtp_err_status_t srtp_get_protect_trailer_length(srtp_t session,
+                                                  uint32_t use_mki,
+                                                  uint32_t mki_index,
+                                                  uint32_t *length)
+{
+    srtp_stream_ctx_t *stream;
+
+    if (session == NULL)
+        return srtp_err_status_bad_param;
+
+    *length = 0;
+
+    /* Try obtaining stream from stream_list */
+    stream = session->stream_list;
+
+    if (stream == NULL) {
+        /* Try obtaining the template stream */
+        stream = session->stream_template;
+    }
+
+    if (stream == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    if (use_mki) {
+        if (mki_index > stream->num_master_keys)
+            return srtp_err_status_bad_mki;
+
+        *length += stream->session_keys[mki_index].mki_size;
+        *length +=
+            srtp_auth_get_tag_length(stream->session_keys[mki_index].rtp_auth);
+    } else {
+        *length += srtp_auth_get_tag_length(stream->session_keys[0].rtp_auth);
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_get_protect_rtcp_trailer_length(srtp_t session,
+                                                       uint32_t use_mki,
+                                                       uint32_t mki_index,
+                                                       uint32_t *length)
+{
+    srtp_stream_ctx_t *stream;
+
+    if (session == NULL)
+        return srtp_err_status_bad_param;
+
+    *length = 0;
+
+    /* Try obtaining stream from stream_list */
+    stream = session->stream_list;
+
+    if (stream == NULL) {
+        /* Try obtaining the template stream */
+        stream = session->stream_template;
+    }
+
+    if (stream == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    if (use_mki) {
+        if (mki_index > stream->num_master_keys)
+            return srtp_err_status_bad_mki;
+
+        *length += stream->session_keys[mki_index].mki_size;
+        *length +=
+            srtp_auth_get_tag_length(stream->session_keys[mki_index].rtcp_auth);
+    } else {
+        *length += srtp_auth_get_tag_length(stream->session_keys[0].rtcp_auth);
+    }
+
+    *length += sizeof(srtcp_trailer_t);
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * SRTP debug interface
+ */
+srtp_err_status_t srtp_set_debug_module(const char *mod_name, int v)
+{
+    return srtp_crypto_kernel_set_debug_module(mod_name, v);
 }
 
-unsigned int
-srtp_profile_get_master_salt_length(srtp_profile_t profile) {
-
-  switch(profile) {
-  case srtp_profile_aes128_cm_sha1_80:
-    return 14;
-    break;
-  case srtp_profile_aes128_cm_sha1_32:
-    return 14;
-    break;
-  case srtp_profile_null_sha1_80:
-    return 14;
-    break;
-  case srtp_profile_aes256_cm_sha1_80:
-    return 14;
-    break;
-  case srtp_profile_aes256_cm_sha1_32:
-    return 14;
-    break;
-    /* the following profiles are not (yet) supported */
-  case srtp_profile_null_sha1_32:
-  default:
-    return 0;  /* indicate error by returning a zero */
-  }
+srtp_err_status_t srtp_list_debug_modules(void)
+{
+    return srtp_crypto_kernel_list_debug_modules();
+}
+
+/*
+ * srtp_log_handler is a global variable holding a pointer to the
+ * log handler function; this function is called for any log
+ * output.
+ */
+
+static srtp_log_handler_func_t *srtp_log_handler = NULL;
+static void *srtp_log_handler_data = NULL;
+
+void srtp_err_handler(srtp_err_reporting_level_t level, const char *msg)
+{
+    if (srtp_log_handler) {
+        srtp_log_level_t log_level = srtp_log_level_error;
+        switch (level) {
+        case srtp_err_level_error:
+            log_level = srtp_log_level_error;
+            break;
+        case srtp_err_level_warning:
+            log_level = srtp_log_level_warning;
+            break;
+        case srtp_err_level_info:
+            log_level = srtp_log_level_info;
+            break;
+        case srtp_err_level_debug:
+            log_level = srtp_log_level_debug;
+            break;
+        }
+
+        srtp_log_handler(log_level, msg, srtp_log_handler_data);
+    }
 }
+
+srtp_err_status_t srtp_install_log_handler(srtp_log_handler_func_t func,
+                                           void *data)
+{
+    /*
+     * note that we accept NULL arguments intentionally - calling this
+     * function with a NULL arguments removes a log handler that's
+     * been previously installed
+     */
+
+    if (srtp_log_handler) {
+        srtp_install_err_report_handler(NULL);
+    }
+    srtp_log_handler = func;
+    srtp_log_handler_data = data;
+    if (srtp_log_handler) {
+        srtp_install_err_report_handler(srtp_err_handler);
+    }
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_set_stream_roc(srtp_t session,
+                                      uint32_t ssrc,
+                                      uint32_t roc)
+{
+    srtp_stream_t stream;
+
+    stream = srtp_get_stream(session, htonl(ssrc));
+    if (stream == NULL)
+        return srtp_err_status_bad_param;
+
+    stream->pending_roc = roc;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_get_stream_roc(srtp_t session,
+                                      uint32_t ssrc,
+                                      uint32_t *roc)
+{
+    srtp_stream_t stream;
+
+    stream = srtp_get_stream(session, htonl(ssrc));
+    if (stream == NULL)
+        return srtp_err_status_bad_param;
+
+    *roc = srtp_rdbx_get_roc(&stream->rtp_rdbx);
+
+    return srtp_err_status_ok;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/cutest.h
@@ -0,0 +1,713 @@
+/*
+ * CUTest -- C/C++ Unit Test facility
+ * <http://github.com/mity/cutest>
+ *
+ * Copyright (c) 2013-2017 Martin Mitas
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef CUTEST_H__
+#define CUTEST_H__
+
+/************************
+ *** Public interface ***
+ ************************/
+
+/* By default, <cutest.h> provides the main program entry point (function
+ * main()). However, if the test suite is composed of multiple source files
+ * which include <cutest.h>, then this causes a problem of multiple main()
+ * definitions. To avoid this problem, #define macro TEST_NO_MAIN in all
+ * compilation units but one.
+ */
+
+/* Macro to specify list of unit tests in the suite.
+ * The unit test implementation MUST provide list of unit tests it implements
+ * with this macro:
+ *
+ *   TEST_LIST = {
+ *       { "test1_name", test1_func_ptr },
+ *       { "test2_name", test2_func_ptr },
+ *       ...
+ *       { 0 }
+ *   };
+ *
+ * The list specifies names of each test (must be unique) and pointer to
+ * a function implementing it. The function does not take any arguments
+ * and has no return values, i.e. every test function has tp be compatible
+ * with this prototype:
+ *
+ *   void test_func(void);
+ */
+#define TEST_LIST const struct test__ test_list__[]
+
+/* Macros for testing whether an unit test succeeds or fails. These macros
+ * can be used arbitrarily in functions implementing the unit tests.
+ *
+ * If any condition fails throughout execution of a test, the test fails.
+ *
+ * TEST_CHECK takes only one argument (the condition), TEST_CHECK_ allows
+ * also to specify an error message to print out if the condition fails.
+ * (It expects printf-like format string and its parameters). The macros
+ * return non-zero (condition passes) or 0 (condition fails).
+ *
+ * That can be useful when more conditions should be checked only if some
+ * preceding condition passes, as illustrated in this code snippet:
+ *
+ *   SomeStruct* ptr = allocate_some_struct();
+ *   if(TEST_CHECK(ptr != NULL)) {
+ *       TEST_CHECK(ptr->member1 < 100);
+ *       TEST_CHECK(ptr->member2 > 200);
+ *   }
+ */
+#define TEST_CHECK_(cond, ...)                                                 \
+    test_check__((cond), __FILE__, __LINE__, __VA_ARGS__)
+#define TEST_CHECK(cond) test_check__((cond), __FILE__, __LINE__, "%s", #cond)
+
+/**********************
+ *** Implementation ***
+ **********************/
+
+/* The unit test files should not rely on anything below. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
+#define CUTEST_UNIX__ 1
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
+#define CUTEST_WIN__ 1
+#include <windows.h>
+#include <io.h>
+#endif
+
+#ifdef __cplusplus
+#include <exception>
+#endif
+
+/* Note our global private identifiers end with '__' to mitigate risk of clash
+ * with the unit tests implementation. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct test__ {
+    const char *name;
+    void (*func)(void);
+};
+
+extern const struct test__ test_list__[];
+
+int test_check__(int cond, const char *file, int line, const char *fmt, ...);
+
+#ifndef TEST_NO_MAIN
+
+static char *test_argv0__ = NULL;
+static int test_count__ = 0;
+static int test_no_exec__ = 0;
+static int test_no_summary__ = 0;
+static int test_skip_mode__ = 0;
+
+static int test_stat_failed_units__ = 0;
+static int test_stat_run_units__ = 0;
+
+static const struct test__ *test_current_unit__ = NULL;
+static int test_current_already_logged__ = 0;
+static int test_verbose_level__ = 2;
+static int test_current_failures__ = 0;
+static int test_colorize__ = 0;
+
+#define CUTEST_COLOR_DEFAULT__ 0
+#define CUTEST_COLOR_GREEN__ 1
+#define CUTEST_COLOR_RED__ 2
+#define CUTEST_COLOR_DEFAULT_INTENSIVE__ 3
+#define CUTEST_COLOR_GREEN_INTENSIVE__ 4
+#define CUTEST_COLOR_RED_INTENSIVE__ 5
+
+static size_t test_print_in_color__(int color, const char *fmt, ...)
+{
+    va_list args;
+    char buffer[256];
+    size_t n;
+
+    va_start(args, fmt);
+    vsnprintf(buffer, sizeof(buffer), fmt, args);
+    va_end(args);
+    buffer[sizeof(buffer) - 1] = '\0';
+
+    if (!test_colorize__) {
+        return printf("%s", buffer);
+    }
+
+#if defined CUTEST_UNIX__
+    {
+        const char *col_str;
+        switch (color) {
+        case CUTEST_COLOR_GREEN__:
+            col_str = "\033[0;32m";
+            break;
+        case CUTEST_COLOR_RED__:
+            col_str = "\033[0;31m";
+            break;
+        case CUTEST_COLOR_GREEN_INTENSIVE__:
+            col_str = "\033[1;32m";
+            break;
+        case CUTEST_COLOR_RED_INTENSIVE__:
+            col_str = "\033[1;30m";
+            break;
+        case CUTEST_COLOR_DEFAULT_INTENSIVE__:
+            col_str = "\033[1m";
+            break;
+        default:
+            col_str = "\033[0m";
+            break;
+        }
+        printf("%s", col_str);
+        n = printf("%s", buffer);
+        printf("\033[0m");
+        return n;
+    }
+#elif defined CUTEST_WIN__
+    {
+        HANDLE h;
+        CONSOLE_SCREEN_BUFFER_INFO info;
+        WORD attr;
+
+        h = GetStdHandle(STD_OUTPUT_HANDLE);
+        GetConsoleScreenBufferInfo(h, &info);
+
+        switch (color) {
+        case CUTEST_COLOR_GREEN__:
+            attr = FOREGROUND_GREEN;
+            break;
+        case CUTEST_COLOR_RED__:
+            attr = FOREGROUND_RED;
+            break;
+        case CUTEST_COLOR_GREEN_INTENSIVE__:
+            attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+            break;
+        case CUTEST_COLOR_RED_INTENSIVE__:
+            attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
+            break;
+        case CUTEST_COLOR_DEFAULT_INTENSIVE__:
+            attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED |
+                   FOREGROUND_INTENSITY;
+            break;
+        default:
+            attr = 0;
+            break;
+        }
+        if (attr != 0)
+            SetConsoleTextAttribute(h, attr);
+        n = printf("%s", buffer);
+        SetConsoleTextAttribute(h, info.wAttributes);
+        return n;
+    }
+#else
+    n = printf("%s", buffer);
+    return n;
+#endif
+}
+
+int test_check__(int cond, const char *file, int line, const char *fmt, ...)
+{
+    const char *result_str;
+    int result_color;
+    int verbose_level;
+
+    if (cond) {
+        result_str = "ok";
+        result_color = CUTEST_COLOR_GREEN__;
+        verbose_level = 3;
+    } else {
+        if (!test_current_already_logged__ && test_current_unit__ != NULL) {
+            printf("[ ");
+            test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
+            printf(" ]\n");
+        }
+        result_str = "failed";
+        result_color = CUTEST_COLOR_RED__;
+        verbose_level = 2;
+        test_current_failures__++;
+        test_current_already_logged__++;
+    }
+
+    if (test_verbose_level__ >= verbose_level) {
+        size_t n = 0;
+        va_list args;
+
+        printf("  ");
+
+        if (file != NULL)
+            n += printf("%s:%d: Check ", file, line);
+
+        va_start(args, fmt);
+        n += vprintf(fmt, args);
+        va_end(args);
+
+        printf("... ");
+        test_print_in_color__(result_color, result_str);
+        printf("\n");
+        test_current_already_logged__++;
+    }
+
+    return (cond != 0);
+}
+
+static void test_list_names__(void)
+{
+    const struct test__ *test;
+
+    printf("Unit tests:\n");
+    for (test = &test_list__[0]; test->func != NULL; test++)
+        printf("  %s\n", test->name);
+}
+
+static const struct test__ *test_by_name__(const char *name)
+{
+    const struct test__ *test;
+
+    for (test = &test_list__[0]; test->func != NULL; test++) {
+        if (strcmp(test->name, name) == 0)
+            return test;
+    }
+
+    return NULL;
+}
+
+/* Call directly the given test unit function. */
+static int test_do_run__(const struct test__ *test)
+{
+    test_current_unit__ = test;
+    test_current_failures__ = 0;
+    test_current_already_logged__ = 0;
+
+    if (test_verbose_level__ >= 3) {
+        test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "Test %s:\n",
+                              test->name);
+        test_current_already_logged__++;
+    } else if (test_verbose_level__ >= 1) {
+        size_t n;
+        char spaces[32];
+
+        n = test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__,
+                                  "Test %s... ", test->name);
+        memset(spaces, ' ', sizeof(spaces));
+        if (n < sizeof(spaces))
+            printf("%.*s", (int)(sizeof(spaces) - n), spaces);
+    } else {
+        test_current_already_logged__ = 1;
+    }
+
+#ifdef __cplusplus
+    try {
+#endif
+
+        /* This is good to do for case the test unit e.g. crashes. */
+        fflush(stdout);
+        fflush(stderr);
+
+        test->func();
+
+#ifdef __cplusplus
+    } catch (std::exception &e) {
+        const char *what = e.what();
+        if (what != NULL)
+            test_check__(0, NULL, 0, "Threw std::exception: %s", what);
+        else
+            test_check__(0, NULL, 0, "Threw std::exception");
+    } catch (...) {
+        test_check__(0, NULL, 0, "Threw an exception");
+    }
+#endif
+
+    if (test_verbose_level__ >= 3) {
+        switch (test_current_failures__) {
+        case 0:
+            test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
+                                  "  All conditions have passed.\n\n");
+            break;
+        case 1:
+            test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
+                                  "  One condition has FAILED.\n\n");
+            break;
+        default:
+            test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__,
+                                  "  %d conditions have FAILED.\n\n",
+                                  test_current_failures__);
+            break;
+        }
+    } else if (test_verbose_level__ >= 1 && test_current_failures__ == 0) {
+        printf("[   ");
+        test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__, "OK");
+        printf("   ]\n");
+    }
+
+    test_current_unit__ = NULL;
+    return (test_current_failures__ == 0) ? 0 : -1;
+}
+
+#if defined(CUTEST_UNIX__) || defined(CUTEST_WIN__)
+/* Called if anything goes bad in cutest, or if the unit test ends in other
+ * way then by normal returning from its function (e.g. exception or some
+ * abnormal child process termination). */
+static void test_error__(const char *fmt, ...)
+{
+    va_list args;
+
+    if (test_verbose_level__ == 0)
+        return;
+
+    if (test_verbose_level__ <= 2 && !test_current_already_logged__ &&
+        test_current_unit__ != NULL) {
+        printf("[ ");
+        test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "FAILED");
+        printf(" ]\n");
+    }
+
+    if (test_verbose_level__ >= 2) {
+        test_print_in_color__(CUTEST_COLOR_RED_INTENSIVE__, "  Error: ");
+        va_start(args, fmt);
+        vprintf(fmt, args);
+        va_end(args);
+        printf("\n");
+    }
+}
+#endif
+
+/* Trigger the unit test. If possible (and not suppressed) it starts a child
+ * process who calls test_do_run__(), otherwise it calls test_do_run__()
+ * directly. */
+static void test_run__(const struct test__ *test)
+{
+    int failed = 1;
+
+    test_current_unit__ = test;
+    test_current_already_logged__ = 0;
+
+    if (!test_no_exec__) {
+#if defined(CUTEST_UNIX__)
+
+        pid_t pid;
+        int exit_code;
+
+        pid = fork();
+        if (pid == (pid_t)-1) {
+            test_error__("Cannot fork. %s [%d]", strerror(errno), errno);
+            failed = 1;
+        } else if (pid == 0) {
+            /* Child: Do the test. */
+            failed = (test_do_run__(test) != 0);
+            exit(failed ? 1 : 0);
+        } else {
+            /* Parent: Wait until child terminates and analyze its exit code. */
+            waitpid(pid, &exit_code, 0);
+            if (WIFEXITED(exit_code)) {
+                switch (WEXITSTATUS(exit_code)) {
+                case 0:
+                    failed = 0;
+                    break; /* test has passed. */
+                case 1:    /* noop */
+                    break; /* "normal" failure. */
+                default:
+                    test_error__("Unexpected exit code [%d]",
+                                 WEXITSTATUS(exit_code));
+                }
+            } else if (WIFSIGNALED(exit_code)) {
+                char tmp[32];
+                const char *signame;
+                switch (WTERMSIG(exit_code)) {
+                case SIGINT:
+                    signame = "SIGINT";
+                    break;
+                case SIGHUP:
+                    signame = "SIGHUP";
+                    break;
+                case SIGQUIT:
+                    signame = "SIGQUIT";
+                    break;
+                case SIGABRT:
+                    signame = "SIGABRT";
+                    break;
+                case SIGKILL:
+                    signame = "SIGKILL";
+                    break;
+                case SIGSEGV:
+                    signame = "SIGSEGV";
+                    break;
+                case SIGILL:
+                    signame = "SIGILL";
+                    break;
+                case SIGTERM:
+                    signame = "SIGTERM";
+                    break;
+                default:
+                    sprintf(tmp, "signal %d", WTERMSIG(exit_code));
+                    signame = tmp;
+                    break;
+                }
+                test_error__("Test interrupted by %s", signame);
+            } else {
+                test_error__("Test ended in an unexpected way [%d]", exit_code);
+            }
+        }
+
+#elif defined(CUTEST_WIN__)
+
+        char buffer[512] = { 0 };
+        STARTUPINFOA startupInfo = { 0 };
+        PROCESS_INFORMATION processInfo;
+        DWORD exitCode;
+
+        /* Windows has no fork(). So we propagate all info into the child
+         * through a command line arguments. */
+        _snprintf(buffer, sizeof(buffer) - 1,
+                  "%s --no-exec --no-summary --verbose=%d --color=%s -- \"%s\"",
+                  test_argv0__, test_verbose_level__,
+                  test_colorize__ ? "always" : "never", test->name);
+        startupInfo.cb = sizeof(STARTUPINFO);
+        if (CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL,
+                           &startupInfo, &processInfo)) {
+            WaitForSingleObject(processInfo.hProcess, INFINITE);
+            GetExitCodeProcess(processInfo.hProcess, &exitCode);
+            CloseHandle(processInfo.hThread);
+            CloseHandle(processInfo.hProcess);
+            failed = (exitCode != 0);
+        } else {
+            test_error__("Cannot create unit test subprocess [%ld].",
+                         GetLastError());
+            failed = 1;
+        }
+
+#else
+
+        /* A platform where we don't know how to run child process. */
+        failed = (test_do_run__(test) != 0);
+
+#endif
+
+    } else {
+        /* Child processes suppressed through --no-exec. */
+        failed = (test_do_run__(test) != 0);
+    }
+
+    test_current_unit__ = NULL;
+
+    test_stat_run_units__++;
+    if (failed)
+        test_stat_failed_units__++;
+}
+
+#if defined(CUTEST_WIN__)
+/* Callback for SEH events. */
+static LONG CALLBACK test_exception_filter__(EXCEPTION_POINTERS *ptrs)
+{
+    test_error__("Unhandled SEH exception %08lx at %p.",
+                 ptrs->ExceptionRecord->ExceptionCode,
+                 ptrs->ExceptionRecord->ExceptionAddress);
+    fflush(stdout);
+    fflush(stderr);
+    return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+static void test_help__(void)
+{
+    printf("Usage: %s [options] [test...]\n", test_argv0__);
+    printf("Run the specified unit tests; or if the option '--skip' is used, "
+           "run all\n");
+    printf("tests in the suite but those listed.  By default, if no tests are "
+           "specified\n");
+    printf("on the command line, all unit tests in the suite are run.\n");
+    printf("\n");
+    printf("Options:\n");
+    printf(
+        "  -s, --skip            Execute all unit tests but the listed ones\n");
+    printf("      --no-exec         Do not execute unit tests as child "
+           "processes\n");
+    printf(
+        "      --no-summary      Suppress printing of test results summary\n");
+    printf("  -l, --list            List unit tests in the suite and exit\n");
+    printf("  -v, --verbose         Enable more verbose output\n");
+    printf("      --verbose=LEVEL   Set verbose level to LEVEL:\n");
+    printf("                          0 ... Be silent\n");
+    printf("                          1 ... Output one line per test (and "
+           "summary)\n");
+    printf("                          2 ... As 1 and failed conditions (this "
+           "is default)\n");
+    printf("                          3 ... As 1 and all conditions (and "
+           "extended summary)\n");
+    printf("      --color=WHEN      Enable colorized output (WHEN is one of "
+           "'auto', 'always', 'never')\n");
+    printf("  -h, --help            Display this help and exit\n");
+    printf("\n");
+    test_list_names__();
+}
+
+int main(int argc, char **argv)
+{
+    const struct test__ **tests = NULL;
+    int i, j, n = 0;
+    int seen_double_dash = 0;
+
+    test_argv0__ = argv[0];
+
+#if defined CUTEST_UNIX__
+    test_colorize__ = isatty(STDOUT_FILENO);
+#elif defined CUTEST_WIN__
+    test_colorize__ = _isatty(_fileno(stdout));
+#else
+    test_colorize__ = 0;
+#endif
+
+    /* Parse options */
+    for (i = 1; i < argc; i++) {
+        if (seen_double_dash || argv[i][0] != '-') {
+            tests = (const struct test__ **)realloc(
+                (void *)tests, (n + 1) * sizeof(const struct test__ *));
+            if (tests == NULL) {
+                fprintf(stderr, "Out of memory.\n");
+                exit(2);
+            }
+            tests[n] = test_by_name__(argv[i]);
+            if (tests[n] == NULL) {
+                fprintf(stderr, "%s: Unrecognized unit test '%s'\n", argv[0],
+                        argv[i]);
+                fprintf(stderr, "Try '%s --list' for list of unit tests.\n",
+                        argv[0]);
+                exit(2);
+            }
+            n++;
+        } else if (strcmp(argv[i], "--") == 0) {
+            seen_double_dash = 1;
+        } else if (strcmp(argv[i], "--help") == 0 ||
+                   strcmp(argv[i], "-h") == 0) {
+            test_help__();
+            exit(0);
+        } else if (strcmp(argv[i], "--verbose") == 0 ||
+                   strcmp(argv[i], "-v") == 0) {
+            test_verbose_level__++;
+        } else if (strncmp(argv[i], "--verbose=", 10) == 0) {
+            test_verbose_level__ = atoi(argv[i] + 10);
+        } else if (strcmp(argv[i], "--color=auto") == 0) {
+            /* noop (set from above) */
+        } else if (strcmp(argv[i], "--color=always") == 0 ||
+                   strcmp(argv[i], "--color") == 0) {
+            test_colorize__ = 1;
+        } else if (strcmp(argv[i], "--color=never") == 0) {
+            test_colorize__ = 0;
+        } else if (strcmp(argv[i], "--skip") == 0 ||
+                   strcmp(argv[i], "-s") == 0) {
+            test_skip_mode__ = 1;
+        } else if (strcmp(argv[i], "--no-exec") == 0) {
+            test_no_exec__ = 1;
+        } else if (strcmp(argv[i], "--no-summary") == 0) {
+            test_no_summary__ = 1;
+        } else if (strcmp(argv[i], "--list") == 0 ||
+                   strcmp(argv[i], "-l") == 0) {
+            test_list_names__();
+            exit(0);
+        } else {
+            fprintf(stderr, "%s: Unrecognized option '%s'\n", argv[0], argv[i]);
+            fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
+            exit(2);
+        }
+    }
+
+#if defined(CUTEST_WIN__)
+    SetUnhandledExceptionFilter(test_exception_filter__);
+#endif
+
+    /* Count all test units */
+    test_count__ = 0;
+    for (i = 0; test_list__[i].func != NULL; i++)
+        test_count__++;
+
+    /* Run the tests */
+    if (n == 0) {
+        /* Run all tests */
+        for (i = 0; test_list__[i].func != NULL; i++)
+            test_run__(&test_list__[i]);
+    } else if (!test_skip_mode__) {
+        /* Run the listed tests */
+        for (i = 0; i < n; i++)
+            test_run__(tests[i]);
+    } else {
+        /* Run all tests except those listed */
+        for (i = 0; test_list__[i].func != NULL; i++) {
+            int want_skip = 0;
+            for (j = 0; j < n; j++) {
+                if (tests[j] == &test_list__[i]) {
+                    want_skip = 1;
+                    break;
+                }
+            }
+            if (!want_skip)
+                test_run__(&test_list__[i]);
+        }
+    }
+
+    /* Write a summary */
+    if (!test_no_summary__ && test_verbose_level__ >= 1) {
+        test_print_in_color__(CUTEST_COLOR_DEFAULT_INTENSIVE__, "\nSummary:\n");
+
+        if (test_verbose_level__ >= 3) {
+            printf("  Count of all unit tests:     %4d\n", test_count__);
+            printf("  Count of run unit tests:     %4d\n",
+                   test_stat_run_units__);
+            printf("  Count of failed unit tests:  %4d\n",
+                   test_stat_failed_units__);
+            printf("  Count of skipped unit tests: %4d\n",
+                   test_count__ - test_stat_run_units__);
+        }
+
+        if (test_stat_failed_units__ == 0) {
+            test_print_in_color__(CUTEST_COLOR_GREEN_INTENSIVE__,
+                                  "  SUCCESS: All unit tests have passed.\n");
+        } else {
+            test_print_in_color__(
+                CUTEST_COLOR_RED_INTENSIVE__,
+                "  FAILED: %d of %d unit tests have failed.\n",
+                test_stat_failed_units__, test_stat_run_units__);
+        }
+    }
+
+    if (tests != NULL)
+        free((void *)tests);
+
+    return (test_stat_failed_units__ == 0) ? 0 : 1;
+}
+
+#endif /* #ifndef TEST_NO_MAIN */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef CUTEST_H__ */
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/dtls_srtp_driver.c
@@ -0,0 +1,261 @@
+/*
+ * dtls_srtp_driver.c
+ *
+ * test driver for DTLS-SRTP functions
+ *
+ * David McGrew
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 "getopt_s.h" /* for local getopt()    */
+#include "srtp_priv.h"
+
+srtp_err_status_t test_dtls_srtp(void);
+
+srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
+
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
+           "  -d <mod>   turn on debugging module <mod>\n"
+           "  -l         list debugging modules\n",
+           prog_name);
+    exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+    unsigned do_list_mods = 0;
+    int q;
+    srtp_err_status_t err;
+
+    printf("dtls_srtp_driver\n");
+
+    /* initialize srtp library */
+    err = srtp_init();
+    if (err) {
+        printf("error: srtp init failed with error code %d\n", err);
+        exit(1);
+    }
+
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "ld:");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 'l':
+            do_list_mods = 1;
+            break;
+        case 'd':
+            err = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
+            if (err) {
+                printf("error: set debug module (%s) failed\n", optarg_s);
+                exit(1);
+            }
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (do_list_mods) {
+        err = srtp_crypto_kernel_list_debug_modules();
+        if (err) {
+            printf("error: list of debug modules failed\n");
+            exit(1);
+        }
+    }
+
+    printf("testing dtls_srtp...");
+    err = test_dtls_srtp();
+    if (err) {
+        printf("\nerror (code %d)\n", err);
+        exit(1);
+    }
+    printf("passed\n");
+
+    /* shut down srtp library */
+    err = srtp_shutdown();
+    if (err) {
+        printf("error: srtp shutdown failed with error code %d\n", err);
+        exit(1);
+    }
+
+    return 0;
+}
+
+srtp_err_status_t test_dtls_srtp(void)
+{
+    srtp_hdr_t *test_packet;
+    int test_packet_len = 80;
+    srtp_t s;
+    srtp_policy_t policy;
+    uint8_t key[SRTP_MAX_KEY_LEN];
+    uint8_t salt[SRTP_MAX_KEY_LEN];
+    unsigned int key_len, salt_len;
+    srtp_profile_t profile;
+    srtp_err_status_t err;
+
+    memset(&policy, 0x0, sizeof(srtp_policy_t));
+
+    /* create a 'null' SRTP session */
+    err = srtp_create(&s, NULL);
+    if (err)
+        return err;
+
+    /*
+     * verify that packet-processing functions behave properly - we
+     * expect that these functions will return srtp_err_status_no_ctx
+     */
+    test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
+    if (test_packet == NULL)
+        return srtp_err_status_alloc_fail;
+
+    err = srtp_protect(s, test_packet, &test_packet_len);
+    if (err != srtp_err_status_no_ctx) {
+        printf("wrong return value from srtp_protect() (got code %d)\n", err);
+        return srtp_err_status_fail;
+    }
+
+    err = srtp_unprotect(s, test_packet, &test_packet_len);
+    if (err != srtp_err_status_no_ctx) {
+        printf("wrong return value from srtp_unprotect() (got code %d)\n", err);
+        return srtp_err_status_fail;
+    }
+
+    err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
+    if (err != srtp_err_status_no_ctx) {
+        printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
+               err);
+        return srtp_err_status_fail;
+    }
+
+    err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
+    if (err != srtp_err_status_no_ctx) {
+        printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
+               err);
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * set keys to known values for testing
+     */
+    profile = srtp_profile_aes128_cm_sha1_80;
+    key_len = srtp_profile_get_master_key_length(profile);
+    salt_len = srtp_profile_get_master_salt_length(profile);
+    memset(key, 0xff, key_len);
+    memset(salt, 0xee, salt_len);
+    srtp_append_salt_to_key(key, key_len, salt, salt_len);
+    policy.key = key;
+
+    /* initialize SRTP policy from profile  */
+    err = srtp_crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
+    if (err)
+        return err;
+    err = srtp_crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
+    if (err)
+        return err;
+    policy.ssrc.type = ssrc_any_inbound;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    err = srtp_add_stream(s, &policy);
+    if (err)
+        return err;
+
+    err = srtp_dealloc(s);
+    if (err)
+        return err;
+
+    free(test_packet);
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * srtp_create_test_packet(len, ssrc) returns a pointer to a
+ * (malloced) example RTP packet whose data field has the length given
+ * by pkt_octet_len and the SSRC value ssrc.  The total length of the
+ * packet is twelve octets longer, since the header is at the
+ * beginning.  There is room at the end of the packet for a trailer,
+ * and the four octets following the packet are filled with 0xff
+ * values to enable testing for overwrites.
+ *
+ * note that the location of the test packet can (and should) be
+ * deallocated with the free() call once it is no longer needed.
+ */
+
+srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc)
+{
+    int i;
+    uint8_t *buffer;
+    srtp_hdr_t *hdr;
+    int bytes_in_hdr = 12;
+
+    /* allocate memory for test packet */
+    hdr = malloc(pkt_octet_len + bytes_in_hdr + SRTP_MAX_TRAILER_LEN + 4);
+    if (!hdr)
+        return NULL;
+
+    hdr->version = 2;            /* RTP version two     */
+    hdr->p = 0;                  /* no padding needed   */
+    hdr->x = 0;                  /* no header extension */
+    hdr->cc = 0;                 /* no CSRCs            */
+    hdr->m = 0;                  /* marker bit          */
+    hdr->pt = 0xf;               /* payload type        */
+    hdr->seq = htons(0x1234);    /* sequence number     */
+    hdr->ts = htonl(0xdecafbad); /* timestamp           */
+    hdr->ssrc = htonl(ssrc);     /* synch. source       */
+
+    buffer = (uint8_t *)hdr;
+    buffer += bytes_in_hdr;
+
+    /* set RTP data to 0xab */
+    for (i = 0; i < pkt_octet_len; i++)
+        *buffer++ = 0xab;
+
+    /* set post-data value to 0xffff to enable overrun checking */
+    for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++)
+        *buffer++ = 0xff;
+
+    return hdr;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/getopt_s.c
@@ -0,0 +1,108 @@
+/*
+ * getopt.c
+ *
+ * a minimal implementation of the getopt() function, written so that
+ * test applications that use that function can run on non-POSIX
+ * platforms
+ *
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 <stdlib.h> /* for NULL */
+
+int optind_s = 0;
+
+char *optarg_s;
+
+#define GETOPT_FOUND_WITHOUT_ARGUMENT 2
+#define GETOPT_FOUND_WITH_ARGUMENT 1
+#define GETOPT_NOT_FOUND 0
+
+static int getopt_check_character(char c, const char *string)
+{
+    unsigned int max_string_len = 128;
+
+    while (*string != 0) {
+        if (max_string_len == 0) {
+            return '?';
+        }
+        if (*string++ == c) {
+            if (*string == ':') {
+                return GETOPT_FOUND_WITH_ARGUMENT;
+            } else {
+                return GETOPT_FOUND_WITHOUT_ARGUMENT;
+            }
+        }
+    }
+    return GETOPT_NOT_FOUND;
+}
+
+int getopt_s(int argc, char *const argv[], const char *optstring)
+{
+    while (optind_s + 1 < argc) {
+        char *string;
+
+        /* move 'string' on to next argument */
+        optind_s++;
+        string = argv[optind_s];
+
+        if (string == NULL)
+            return '?'; /* NULL argument string */
+
+        if (string[0] != '-')
+            return -1; /* found an unexpected character */
+
+        switch (getopt_check_character(string[1], optstring)) {
+        case GETOPT_FOUND_WITH_ARGUMENT:
+            if (optind_s + 1 < argc) {
+                optind_s++;
+                optarg_s = argv[optind_s];
+                return string[1];
+            } else {
+                return '?'; /* argument missing */
+            }
+        case GETOPT_FOUND_WITHOUT_ARGUMENT:
+            return string[1];
+        case GETOPT_NOT_FOUND:
+        default:
+            return '?'; /* didn't find expected character */
+            break;
+        }
+    }
+
+    return -1;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rdbx_driver.c
@@ -0,0 +1,357 @@
+/*
+ * rdbx_driver.c
+ *
+ * driver for the rdbx implementation (replay database with extended range)
+ *
+ * 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 <stdio.h>    /* for printf()          */
+#include "getopt_s.h" /* for local getopt()    */
+
+#include "rdbx.h"
+
+#ifdef ROC_TEST
+#error "srtp_rdbx_t won't work with ROC_TEST - bitmask same size as seq_median"
+#endif
+
+#include "ut_sim.h"
+
+srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws);
+
+double rdbx_check_adds_per_second(int num_trials, unsigned long ws);
+
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -t | -v ]\n", prog_name);
+    exit(255);
+}
+
+int main(int argc, char *argv[])
+{
+    double rate;
+    srtp_err_status_t status;
+    int q;
+    unsigned do_timing_test = 0;
+    unsigned do_validation = 0;
+
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "tv");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 't':
+            do_timing_test = 1;
+            break;
+        case 'v':
+            do_validation = 1;
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    printf("rdbx (replay database w/ extended range) test driver\n"
+           "David A. McGrew\n"
+           "Cisco Systems, Inc.\n");
+
+    if (!do_validation && !do_timing_test)
+        usage(argv[0]);
+
+    if (do_validation) {
+        printf("testing srtp_rdbx_t (ws=128)...\n");
+
+        status = test_replay_dbx(1 << 12, 128);
+        if (status) {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("passed\n");
+
+        printf("testing srtp_rdbx_t (ws=1024)...\n");
+
+        status = test_replay_dbx(1 << 12, 1024);
+        if (status) {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("passed\n");
+    }
+
+    if (do_timing_test) {
+        rate = rdbx_check_adds_per_second(1 << 18, 128);
+        printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
+        rate = rdbx_check_adds_per_second(1 << 18, 1024);
+        printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
+    }
+
+    return 0;
+}
+
+void print_rdbx(srtp_rdbx_t *rdbx)
+{
+    char buf[2048];
+    printf("rdbx: {%llu, %s}\n", (unsigned long long)(rdbx->index),
+           bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf)));
+}
+
+/*
+ * rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against
+ * rdbx, then adds it.  if a failure is detected (i.e., the check
+ * indicates that the value is already in rdbx) then
+ * srtp_err_status_algo_fail is returned.
+ *
+ */
+
+srtp_err_status_t rdbx_check_add(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
+
+    delta = srtp_index_guess(&rdbx->index, &est, idx);
+
+    if (srtp_rdbx_check(rdbx, delta) != srtp_err_status_ok) {
+        printf("replay_check failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    /*
+     * in practice, we'd authenticate the packet containing idx, using
+     * the estimated value est, at this point
+     */
+
+    if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
+        printf("rdbx_add_index failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
+ *
+ * checks that a sequence number idx is in the replay database
+ * and thus will be rejected
+ */
+
+srtp_err_status_t rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
+    srtp_err_status_t status;
+
+    delta = srtp_index_guess(&rdbx->index, &est, idx);
+
+    status = srtp_rdbx_check(rdbx, delta);
+    if (status == srtp_err_status_ok) {
+        printf("delta: %d ", delta);
+        printf("replay_check failed at index %u (false positive)\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t rdbx_check_add_unordered(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
+    srtp_err_status_t rstat;
+
+    delta = srtp_index_guess(&rdbx->index, &est, idx);
+
+    rstat = srtp_rdbx_check(rdbx, delta);
+    if ((rstat != srtp_err_status_ok) &&
+        (rstat != srtp_err_status_replay_old)) {
+        printf("replay_check_add_unordered failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+    if (rstat == srtp_err_status_replay_old) {
+        return srtp_err_status_ok;
+    }
+    if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
+        printf("rdbx_add_index failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws)
+{
+    srtp_rdbx_t rdbx;
+    uint32_t idx, ircvd;
+    ut_connection utc;
+    srtp_err_status_t status;
+    int num_fp_trials;
+
+    status = srtp_rdbx_init(&rdbx, ws);
+    if (status) {
+        printf("replay_init failed with error code %d\n", status);
+        exit(1);
+    }
+
+    /*
+     *  test sequential insertion
+     */
+    printf("\ttesting sequential insertion...");
+    for (idx = 0; (int)idx < num_trials; idx++) {
+        status = rdbx_check_add(&rdbx, idx);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
+
+    /*
+     *  test for false positives by checking all of the index
+     *  values which we've just added
+     *
+     * note that we limit the number of trials here, since allowing the
+     * rollover counter to roll over would defeat this test
+     */
+    num_fp_trials = num_trials % 0x10000;
+    if (num_fp_trials == 0) {
+        printf("warning: no false positive tests performed\n");
+    }
+    printf("\ttesting for false positives...");
+    for (idx = 0; (int)idx < num_fp_trials; idx++) {
+        status = rdbx_check_expect_failure(&rdbx, idx);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
+
+    /* re-initialize */
+    srtp_rdbx_dealloc(&rdbx);
+
+    if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
+        printf("replay_init failed\n");
+        return srtp_err_status_init_fail;
+    }
+
+    /*
+     * test non-sequential insertion
+     *
+     * this test covers only fase negatives, since the values returned
+     * by ut_next_index(...) are distinct
+     */
+    ut_init(&utc);
+
+    printf("\ttesting non-sequential insertion...");
+    for (idx = 0; (int)idx < num_trials; idx++) {
+        ircvd = ut_next_index(&utc);
+        status = rdbx_check_add_unordered(&rdbx, ircvd);
+        if (status)
+            return status;
+        status = rdbx_check_expect_failure(&rdbx, ircvd);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
+
+    /* re-initialize */
+    srtp_rdbx_dealloc(&rdbx);
+
+    if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
+        printf("replay_init failed\n");
+        return srtp_err_status_init_fail;
+    }
+
+    /*
+     * test insertion with large gaps.
+     * check for false positives for each insertion.
+     */
+    printf("\ttesting insertion with large gaps...");
+    for (idx = 0, ircvd = 0; (int)idx < num_trials;
+         idx++, ircvd += (1 << (rand() % 12))) {
+        status = rdbx_check_add(&rdbx, ircvd);
+        if (status)
+            return status;
+        status = rdbx_check_expect_failure(&rdbx, ircvd);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
+
+    srtp_rdbx_dealloc(&rdbx);
+
+    return srtp_err_status_ok;
+}
+
+#include <time.h>   /* for clock()  */
+#include <stdlib.h> /* for random() */
+
+double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
+{
+    uint32_t i;
+    int delta;
+    srtp_rdbx_t rdbx;
+    srtp_xtd_seq_num_t est;
+    clock_t timer;
+    int failures; /* count number of failures */
+
+    if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
+        printf("replay_init failed\n");
+        exit(1);
+    }
+
+    failures = 0;
+    timer = clock();
+    for (i = 0; (int)i < num_trials; i++) {
+        delta = srtp_index_guess(&rdbx.index, &est, i);
+
+        if (srtp_rdbx_check(&rdbx, delta) != srtp_err_status_ok)
+            ++failures;
+        else if (srtp_rdbx_add_index(&rdbx, delta) != srtp_err_status_ok)
+            ++failures;
+    }
+    timer = clock() - timer;
+
+    printf("number of failures: %d \n", failures);
+
+    srtp_rdbx_dealloc(&rdbx);
+
+    return (double)CLOCKS_PER_SEC * num_trials / timer;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/replay_driver.c
@@ -0,0 +1,283 @@
+/*
+ * replay_driver.c
+ *
+ * A driver for the replay_database implementation
+ *
+ * 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 <stdio.h>
+
+#include "rdb.h"
+#include "ut_sim.h"
+
+/*
+ * num_trials defines the number of trials that are used in the
+ * validation functions below
+ */
+
+unsigned num_trials = 1 << 16;
+
+srtp_err_status_t test_rdb_db(void);
+
+double rdb_check_adds_per_second(void);
+
+int main(void)
+{
+    srtp_err_status_t err;
+
+    printf("testing anti-replay database (srtp_rdb_t)...\n");
+    err = test_rdb_db();
+    if (err) {
+        printf("failed\n");
+        exit(1);
+    }
+    printf("done\n");
+
+    printf("rdb_check/rdb_adds per second: %e\n", rdb_check_adds_per_second());
+
+    return 0;
+}
+
+void print_rdb(srtp_rdb_t *rdb)
+{
+    printf("rdb: {%u, %s}\n", rdb->window_start,
+           v128_bit_string(&rdb->bitmask));
+}
+
+srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx)
+{
+    if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
+        printf("rdb_check failed at index %u\n", idx);
+        return srtp_err_status_fail;
+    }
+    if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
+        printf("rdb_add_index failed at index %u\n", idx);
+        return srtp_err_status_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx)
+{
+    srtp_err_status_t err;
+
+    err = srtp_rdb_check(rdb, idx);
+    if ((err != srtp_err_status_replay_old) &&
+        (err != srtp_err_status_replay_fail)) {
+        printf("rdb_check failed at index %u (false positive)\n", idx);
+        return srtp_err_status_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx)
+{
+    srtp_err_status_t rstat;
+
+    /* printf("index: %u\n", idx); */
+    rstat = srtp_rdb_check(rdb, idx);
+    if ((rstat != srtp_err_status_ok) &&
+        (rstat != srtp_err_status_replay_old)) {
+        printf("rdb_check_add_unordered failed at index %u\n", idx);
+        return rstat;
+    }
+    if (rstat == srtp_err_status_replay_old) {
+        return srtp_err_status_ok;
+    }
+    if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
+        printf("rdb_add_index failed at index %u\n", idx);
+        return srtp_err_status_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t test_rdb_db()
+{
+    srtp_rdb_t rdb;
+    uint32_t idx, ircvd;
+    ut_connection utc;
+    srtp_err_status_t err;
+
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_init_fail;
+    }
+
+    /* test sequential insertion */
+    for (idx = 0; idx < num_trials; idx++) {
+        err = rdb_check_add(&rdb, idx);
+        if (err)
+            return err;
+    }
+
+    /* test for false positives */
+    for (idx = 0; idx < num_trials; idx++) {
+        err = rdb_check_expect_failure(&rdb, idx);
+        if (err)
+            return err;
+    }
+
+    /* re-initialize */
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_fail;
+    }
+
+    /* test non-sequential insertion */
+    ut_init(&utc);
+
+    for (idx = 0; idx < num_trials; idx++) {
+        ircvd = ut_next_index(&utc);
+        err = rdb_check_add_unordered(&rdb, ircvd);
+        if (err)
+            return err;
+        err = rdb_check_expect_failure(&rdb, ircvd);
+        if (err)
+            return err;
+    }
+
+    /* re-initialize */
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_fail;
+    }
+
+    /* test insertion with large gaps */
+    for (idx = 0, ircvd = 0; idx < num_trials;
+         idx++, ircvd += (1 << (rand() % 10))) {
+        err = rdb_check_add(&rdb, ircvd);
+        if (err)
+            return err;
+        err = rdb_check_expect_failure(&rdb, ircvd);
+        if (err)
+            return err;
+    }
+
+    /* re-initialize */
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_fail;
+    }
+
+    /* test loss of first 513 packets */
+    for (idx = 0; idx < num_trials; idx++) {
+        err = rdb_check_add(&rdb, idx + 513);
+        if (err)
+            return err;
+    }
+
+    /* test for false positives */
+    for (idx = 0; idx < num_trials + 513; idx++) {
+        err = rdb_check_expect_failure(&rdb, idx);
+        if (err)
+            return err;
+    }
+
+    /* test for key expired */
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_fail;
+    }
+    rdb.window_start = 0x7ffffffe;
+    if (srtp_rdb_increment(&rdb) != srtp_err_status_ok) {
+        printf("srtp_rdb_increment of 0x7ffffffe failed\n");
+        return srtp_err_status_fail;
+    }
+    if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
+        printf("rdb valiue was not 0x7fffffff\n");
+        return srtp_err_status_fail;
+    }
+    if (srtp_rdb_increment(&rdb) != srtp_err_status_key_expired) {
+        printf("srtp_rdb_increment of 0x7fffffff did not return "
+               "srtp_err_status_key_expired\n");
+        return srtp_err_status_fail;
+    }
+    if (srtp_rdb_get_value(&rdb) != 0x7fffffff) {
+        printf("rdb valiue was not 0x7fffffff\n");
+        return srtp_err_status_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+#include <time.h>   /* for clock()  */
+#include <stdlib.h> /* for random() */
+
+#define REPLAY_NUM_TRIALS 10000000
+
+double rdb_check_adds_per_second(void)
+{
+    uint32_t i;
+    srtp_rdb_t rdb;
+    clock_t timer;
+    int failures = 0; /* count number of failures        */
+
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        exit(1);
+    }
+
+    timer = clock();
+    for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) {
+        if (srtp_rdb_check(&rdb, i + 2) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i + 2) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_check(&rdb, i + 1) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i + 1) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
+            ++failures;
+    }
+    timer = clock() - timer;
+
+    return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/roc_driver.c
@@ -0,0 +1,170 @@
+/*
+ * roc_driver.c
+ *
+ * test driver for rollover counter replay implementation
+ *
+ * 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 <stdio.h>
+
+/*
+ * defining ROC_TEST causes small datatypes to be used in
+ * srtp_xtd_seq_num_t - this allows the functions to be exhaustively tested.
+ */
+#if ROC_NEEDS_TO_BE_TESTED
+#define ROC_TEST
+#endif
+
+#include "rdbx.h"
+#include "ut_sim.h"
+
+srtp_err_status_t roc_test(int num_trials);
+
+int main(void)
+{
+    srtp_err_status_t status;
+
+    printf("rollover counter test driver\n"
+           "David A. McGrew\n"
+           "Cisco Systems, Inc.\n");
+
+    printf("testing index functions...");
+    status = roc_test(1 << 18);
+    if (status) {
+        printf("failed\n");
+        exit(status);
+    }
+    printf("passed\n");
+    return 0;
+}
+
+#define ROC_VERBOSE 0
+
+srtp_err_status_t roc_test(int num_trials)
+{
+    srtp_xtd_seq_num_t local, est, ref;
+    ut_connection utc;
+    int i, num_bad_est = 0;
+    int delta;
+    uint32_t ircvd;
+    double failure_rate;
+
+    srtp_index_init(&local);
+    srtp_index_init(&ref);
+    srtp_index_init(&est);
+
+    printf("\n\ttesting sequential insertion...");
+    for (i = 0; i < 2048; i++) {
+        delta = srtp_index_guess(&local, &est, (uint16_t)ref);
+#if ROC_VERBOSE
+        printf("%lld, %lld, %d\n", ref, est, i);
+#endif
+        if (ref != est) {
+#if ROC_VERBOSE
+            printf(" *bad estimate*\n");
+#endif
+            ++num_bad_est;
+        }
+        srtp_index_advance(&ref, 1);
+    }
+    failure_rate = (double)num_bad_est / num_trials;
+    if (failure_rate > 0.01) {
+        printf("error: failure rate too high (%d bad estimates in %d trials)\n",
+               num_bad_est, num_trials);
+        return srtp_err_status_algo_fail;
+    }
+    printf("done\n");
+
+    printf("\ttesting non-sequential insertion...");
+    srtp_index_init(&local);
+    srtp_index_init(&ref);
+    srtp_index_init(&est);
+    ut_init(&utc);
+
+    for (i = 0; i < num_trials; i++) {
+        /* get next seq num from unreliable transport simulator */
+        ircvd = ut_next_index(&utc);
+
+        /* set ref to value of ircvd */
+        ref = ircvd;
+
+        /* estimate index based on low bits of ircvd */
+        delta = srtp_index_guess(&local, &est, (uint16_t)ref);
+#if ROC_VERBOSE
+        printf("ref: %lld, local: %lld, est: %lld, ircvd: %d, delta: %d\n", ref,
+               local, est, ircvd, delta);
+#endif
+
+        if (local + delta != est) {
+            printf(" *bad delta*: local %llu + delta %d != est %llu\n",
+                   (unsigned long long)local, delta, (unsigned long long)est);
+            return srtp_err_status_algo_fail;
+        }
+
+        /* now update local srtp_xtd_seq_num_t as necessary */
+        if (delta > 0)
+            srtp_index_advance(&local, delta);
+
+        if (ref != est) {
+#if ROC_VERBOSE
+            printf(" *bad estimate*\n");
+#endif
+            /* record failure event */
+            ++num_bad_est;
+
+            /* reset local value to correct value */
+            local = ref;
+        }
+    }
+    failure_rate = (double)num_bad_est / num_trials;
+    if (failure_rate > 0.01) {
+        printf("error: failure rate too high (%d bad estimates in %d trials)\n",
+               num_bad_est, num_trials);
+        return srtp_err_status_algo_fail;
+    }
+    printf("done\n");
+
+    return srtp_err_status_ok;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rtp.c
@@ -0,0 +1,227 @@
+/*
+ * rtp.c
+ *
+ * library functions for the real-time transport protocol
+ *
+ * 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.
+ *
+ */
+
+#include "rtp.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#define PRINT_DEBUG 0   /* set to 1 to print out debugging data */
+#define VERBOSE_DEBUG 0 /* set to 1 to print out more data      */
+
+int rtp_sendto(rtp_sender_t sender, const void *msg, int len)
+{
+    int octets_sent;
+    srtp_err_status_t stat;
+    int pkt_len = len + RTP_HEADER_LEN;
+
+    /* marshal data */
+    strncpy(sender->message.body, msg, len);
+
+    /* update header */
+    sender->message.header.seq = ntohs(sender->message.header.seq) + 1;
+    sender->message.header.seq = htons(sender->message.header.seq);
+    sender->message.header.ts = ntohl(sender->message.header.ts) + 1;
+    sender->message.header.ts = htonl(sender->message.header.ts);
+
+    /* apply srtp */
+    stat = srtp_protect(sender->srtp_ctx, &sender->message.header, &pkt_len);
+    if (stat) {
+#if PRINT_DEBUG
+        fprintf(stderr, "error: srtp protection failed with code %d\n", stat);
+#endif
+        return -1;
+    }
+#if VERBOSE_DEBUG
+    srtp_print_packet(&sender->message.header, pkt_len);
+#endif
+    octets_sent =
+        sendto(sender->socket, (void *)&sender->message, pkt_len, 0,
+               (struct sockaddr *)&sender->addr, sizeof(struct sockaddr_in));
+
+    if (octets_sent != pkt_len) {
+#if PRINT_DEBUG
+        fprintf(stderr, "error: couldn't send message %s", (char *)msg);
+        perror("");
+#endif
+    }
+
+    return octets_sent;
+}
+
+int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len)
+{
+    int octets_recvd;
+    srtp_err_status_t stat;
+
+    octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message, *len,
+                            0, (struct sockaddr *)NULL, 0);
+
+    if (octets_recvd == -1) {
+        *len = 0;
+        return -1;
+    }
+
+    /* verify rtp header */
+    if (receiver->message.header.version != 2) {
+        *len = 0;
+        return -1;
+    }
+
+#if PRINT_DEBUG
+    fprintf(stderr, "%d octets received from SSRC %u\n", octets_recvd,
+            receiver->message.header.ssrc);
+#endif
+#if VERBOSE_DEBUG
+    srtp_print_packet(&receiver->message.header, octets_recvd);
+#endif
+
+    /* apply srtp */
+    stat = srtp_unprotect(receiver->srtp_ctx, &receiver->message.header,
+                          &octets_recvd);
+    if (stat) {
+        fprintf(stderr, "error: srtp unprotection failed with code %d%s\n",
+                stat,
+                stat == srtp_err_status_replay_fail
+                    ? " (replay check failed)"
+                    : stat == srtp_err_status_auth_fail ? " (auth check failed)"
+                                                        : "");
+        return -1;
+    }
+    strncpy(msg, receiver->message.body, octets_recvd);
+
+    return octets_recvd;
+}
+
+int rtp_sender_init(rtp_sender_t sender,
+                    int sock,
+                    struct sockaddr_in addr,
+                    unsigned int ssrc)
+{
+    /* set header values */
+    sender->message.header.ssrc = htonl(ssrc);
+    sender->message.header.ts = 0;
+    sender->message.header.seq = (uint16_t)rand();
+    sender->message.header.m = 0;
+    sender->message.header.pt = 0x1;
+    sender->message.header.version = 2;
+    sender->message.header.p = 0;
+    sender->message.header.x = 0;
+    sender->message.header.cc = 0;
+
+    /* set other stuff */
+    sender->socket = sock;
+    sender->addr = addr;
+
+    return 0;
+}
+
+int rtp_receiver_init(rtp_receiver_t rcvr,
+                      int sock,
+                      struct sockaddr_in addr,
+                      unsigned int ssrc)
+{
+    /* set header values */
+    rcvr->message.header.ssrc = htonl(ssrc);
+    rcvr->message.header.ts = 0;
+    rcvr->message.header.seq = 0;
+    rcvr->message.header.m = 0;
+    rcvr->message.header.pt = 0x1;
+    rcvr->message.header.version = 2;
+    rcvr->message.header.p = 0;
+    rcvr->message.header.x = 0;
+    rcvr->message.header.cc = 0;
+
+    /* set other stuff */
+    rcvr->socket = sock;
+    rcvr->addr = addr;
+
+    return 0;
+}
+
+int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy)
+{
+    return srtp_create(&sender->srtp_ctx, policy);
+}
+
+int rtp_sender_deinit_srtp(rtp_sender_t sender)
+{
+    return srtp_dealloc(sender->srtp_ctx);
+}
+
+int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy)
+{
+    return srtp_create(&sender->srtp_ctx, policy);
+}
+
+int rtp_receiver_deinit_srtp(rtp_receiver_t sender)
+{
+    return srtp_dealloc(sender->srtp_ctx);
+}
+
+rtp_sender_t rtp_sender_alloc(void)
+{
+    return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
+}
+
+void rtp_sender_dealloc(rtp_sender_t rtp_ctx)
+{
+    free(rtp_ctx);
+}
+
+rtp_receiver_t rtp_receiver_alloc(void)
+{
+    return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
+}
+
+void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx)
+{
+    free(rtp_ctx);
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rtp.h
@@ -0,0 +1,155 @@
+/*
+ * rtp.h
+ *
+ * rtp interface for srtp reference implementation
+ *
+ * David A. McGrew
+ * Cisco Systems, Inc.
+ *
+ * data types:
+ *
+ * rtp_msg_t       an rtp message (the data that goes on the wire)
+ * rtp_sender_t    sender side socket and rtp info
+ * rtp_receiver_t  receiver side socket and rtp info
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2001-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef SRTP_RTP_H
+#define SRTP_RTP_H
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+#include "srtp_priv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * RTP_HEADER_LEN indicates the size of an RTP header
+ */
+#define RTP_HEADER_LEN 12
+
+/*
+ * RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
+ */
+#define RTP_MAX_BUF_LEN 16384
+
+typedef srtp_hdr_t rtp_hdr_t;
+
+typedef struct {
+    srtp_hdr_t header;
+    char body[RTP_MAX_BUF_LEN];
+} rtp_msg_t;
+
+typedef struct rtp_sender_ctx_t {
+    rtp_msg_t message;
+    int socket;
+    srtp_ctx_t *srtp_ctx;
+    struct sockaddr_in addr; /* reciever's address */
+} rtp_sender_ctx_t;
+
+typedef struct rtp_receiver_ctx_t {
+    rtp_msg_t message;
+    int socket;
+    srtp_ctx_t *srtp_ctx;
+    struct sockaddr_in addr; /* receiver's address */
+} rtp_receiver_ctx_t;
+
+typedef struct rtp_sender_ctx_t *rtp_sender_t;
+
+typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
+
+int rtp_sendto(rtp_sender_t sender, const void *msg, int len);
+
+int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
+
+int rtp_receiver_init(rtp_receiver_t rcvr,
+                      int sock,
+                      struct sockaddr_in addr,
+                      unsigned int ssrc);
+
+int rtp_sender_init(rtp_sender_t sender,
+                    int sock,
+                    struct sockaddr_in addr,
+                    unsigned int ssrc);
+
+/*
+ * srtp_sender_init(...) initializes an rtp_sender_t
+ */
+
+int srtp_sender_init(
+    rtp_sender_t rtp_ctx,              /* structure to be init'ed */
+    struct sockaddr_in name,           /* socket name             */
+    srtp_sec_serv_t security_services, /* sec. servs. to be used  */
+    unsigned char *input_key           /* master key/salt in hex  */
+    );
+
+int srtp_receiver_init(
+    rtp_receiver_t rtp_ctx,            /* structure to be init'ed */
+    struct sockaddr_in name,           /* socket name             */
+    srtp_sec_serv_t security_services, /* sec. servs. to be used  */
+    unsigned char *input_key           /* master key/salt in hex  */
+    );
+
+int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
+
+int rtp_sender_deinit_srtp(rtp_sender_t sender);
+
+int rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
+
+int rtp_receiver_deinit_srtp(rtp_receiver_t sender);
+
+rtp_sender_t rtp_sender_alloc(void);
+
+void rtp_sender_dealloc(rtp_sender_t rtp_ctx);
+
+rtp_receiver_t rtp_receiver_alloc(void);
+
+void rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_RTP_H */
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rtp_decoder.c
@@ -0,0 +1,574 @@
+/*
+ * rtp_decoder.c
+ *
+ * decoder structures and functions for SRTP pcap decoder
+ *
+ * Example:
+ * $ wget --no-check-certificate \
+ *     https://raw.githubusercontent.com/gteissier/srtp-decrypt/master/marseillaise-srtp.pcap
+ * $ ./test/rtp_decoder -a -t 10 -e 128 -b \
+ *     aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz \
+ *         < ~/marseillaise-srtp.pcap \
+ *         | text2pcap -t "%M:%S." -u 10000,10000 - - \
+ *         > ./marseillaise-rtp.pcap
+ *
+ * There is also a different way of setting up key size and tag size
+ * based upon RFC 4568 crypto suite specification, i.e.:
+ *
+ * $ ./test/rtp_decoder -s AES_CM_128_HMAC_SHA1_80 -b \
+ *     aSBrbm93IGFsbCB5b3VyIGxpdHRsZSBzZWNyZXRz ...
+ *
+ * Audio can be extracted using extractaudio utility from the RTPproxy
+ * package:
+ *
+ * $ extractaudio -A ./marseillaise-rtp.pcap ./marseillaise-out.wav
+ *
+ * Bernardo Torres <bernardo@torresautomacao.com.br>
+ *
+ * Some structure and code from https://github.com/gteissier/srtp-decrypt
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 "getopt_s.h" /* for local getopt()  */
+#include <assert.h>   /* for assert()  */
+
+#include <pcap.h>
+#include "rtp_decoder.h"
+#include "util.h"
+
+#ifndef timersub
+#define timersub(a, b, result)                                                 \
+    do {                                                                       \
+        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                          \
+        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                       \
+        if ((result)->tv_usec < 0) {                                           \
+            --(result)->tv_sec;                                                \
+            (result)->tv_usec += 1000000;                                      \
+        }                                                                      \
+    } while (0)
+#endif
+
+#define MAX_KEY_LEN 96
+#define MAX_FILTER 256
+
+struct srtp_crypto_suite {
+    const char *can_name;
+    int key_size;
+    int tag_size;
+};
+
+static struct srtp_crypto_suite srtp_crypto_suites[] = {
+    {.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
+#if 0
+  {.can_name = "F8_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4},
+#endif
+    {.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
+    {.can_name = "AES_CM_128_HMAC_SHA1_80", .key_size = 128, .tag_size = 10 },
+    {.can_name = NULL }
+};
+
+int main(int argc, char *argv[])
+{
+    char errbuf[PCAP_ERRBUF_SIZE];
+    bpf_u_int32 pcap_net = 0;
+    pcap_t *pcap_handle;
+#if BEW
+    struct sockaddr_in local;
+#endif
+    srtp_sec_serv_t sec_servs = sec_serv_none;
+    int c;
+    struct srtp_crypto_suite scs, *i_scsp;
+    scs.key_size = 128;
+    scs.tag_size = 8;
+    int gcm_on = 0;
+    char *input_key = NULL;
+    int b64_input = 0;
+    char key[MAX_KEY_LEN];
+    struct bpf_program fp;
+    char filter_exp[MAX_FILTER] = "";
+    rtp_decoder_t dec;
+    srtp_policy_t policy;
+    srtp_err_status_t status;
+    int len;
+    int expected_len;
+    int do_list_mods = 0;
+
+    fprintf(stderr, "Using %s [0x%x]\n", srtp_get_version_string(),
+            srtp_get_version());
+
+    /* initialize srtp library */
+    status = srtp_init();
+    if (status) {
+        fprintf(stderr,
+                "error: srtp initialization failed with error code %d\n",
+                status);
+        exit(1);
+    }
+
+    /* check args */
+    while (1) {
+        c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:");
+        if (c == -1) {
+            break;
+        }
+        switch (c) {
+        case 'b':
+            b64_input = 1;
+        /* fall thru */
+        case 'k':
+            input_key = optarg_s;
+            break;
+        case 'e':
+            scs.key_size = atoi(optarg_s);
+            if (scs.key_size != 128 && scs.key_size != 256) {
+                fprintf(stderr,
+                        "error: encryption key size must be 128 or 256 (%d)\n",
+                        scs.key_size);
+                exit(1);
+            }
+            input_key = malloc(scs.key_size);
+            sec_servs |= sec_serv_conf;
+            break;
+        case 't':
+            scs.tag_size = atoi(optarg_s);
+            break;
+        case 'a':
+            sec_servs |= sec_serv_auth;
+            break;
+        case 'g':
+            gcm_on = 1;
+            sec_servs |= sec_serv_auth;
+            break;
+        case 'd':
+            status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
+            if (status) {
+                fprintf(stderr, "error: set debug module (%s) failed\n",
+                        optarg_s);
+                exit(1);
+            }
+            break;
+        case 'f':
+            if (strlen(optarg_s) > MAX_FILTER) {
+                fprintf(stderr, "error: filter bigger than %d characters\n",
+                        MAX_FILTER);
+                exit(1);
+            }
+            fprintf(stderr, "Setting filter as %s\n", optarg_s);
+            strcpy(filter_exp, optarg_s);
+            break;
+        case 'l':
+            do_list_mods = 1;
+            break;
+        case 's':
+            for (i_scsp = &srtp_crypto_suites[0]; i_scsp->can_name != NULL;
+                 i_scsp++) {
+                if (strcasecmp(i_scsp->can_name, optarg_s) == 0) {
+                    break;
+                }
+            }
+            if (i_scsp->can_name == NULL) {
+                fprintf(stderr, "Unknown/unsupported crypto suite name %s\n",
+                        optarg_s);
+                exit(1);
+            }
+            scs = *i_scsp;
+            input_key = malloc(scs.key_size);
+            sec_servs |= sec_serv_conf | sec_serv_auth;
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
+        fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
+                scs.tag_size);
+        // exit(1);
+    }
+
+    if (do_list_mods) {
+        status = srtp_crypto_kernel_list_debug_modules();
+        if (status) {
+            fprintf(stderr, "error: list of debug modules failed\n");
+            exit(1);
+        }
+        return 0;
+    }
+
+    if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
+        /*
+         * a key must be provided if and only if security services have
+         * been requested
+         */
+        if (input_key == NULL) {
+            fprintf(stderr, "key not provided\n");
+        }
+        if (!sec_servs) {
+            fprintf(stderr, "no secservs\n");
+        }
+        fprintf(stderr, "provided\n");
+        usage(argv[0]);
+    }
+
+    /* report security services selected on the command line */
+    fprintf(stderr, "security services: ");
+    if (sec_servs & sec_serv_conf)
+        fprintf(stderr, "confidentiality ");
+    if (sec_servs & sec_serv_auth)
+        fprintf(stderr, "message authentication");
+    if (sec_servs == sec_serv_none)
+        fprintf(stderr, "none");
+    fprintf(stderr, "\n");
+
+    /* set up the srtp policy and master key */
+    if (sec_servs) {
+        /*
+         * create policy structure, using the default mechanisms but
+         * with only the security services requested on the command line,
+         * using the right SSRC value
+         */
+        switch (sec_servs) {
+        case sec_serv_conf_and_auth:
+            if (gcm_on) {
+#ifdef OPENSSL
+                switch (scs.key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
+                    break;
+                }
+#else
+                fprintf(stderr, "error: GCM mode only supported when using the "
+                                "OpenSSL crypto engine.\n");
+                return 0;
+#endif
+            } else {
+                switch (scs.key_size) {
+                case 128:
+                    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                }
+            }
+            break;
+        case sec_serv_conf:
+            if (gcm_on) {
+                fprintf(
+                    stderr,
+                    "error: GCM mode must always be used with auth enabled\n");
+                return -1;
+            } else {
+                switch (scs.key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                }
+            }
+            break;
+        case sec_serv_auth:
+            if (gcm_on) {
+#ifdef OPENSSL
+                switch (scs.key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
+                        &policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
+                        &policy.rtcp);
+                    break;
+                }
+#else
+                printf("error: GCM mode only supported when using the OpenSSL "
+                       "crypto engine.\n");
+                return 0;
+#endif
+            } else {
+                srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
+                srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+            }
+            break;
+        default:
+            fprintf(stderr, "error: unknown security service requested\n");
+            return -1;
+        }
+
+        policy.key = (uint8_t *)key;
+        policy.ekt = NULL;
+        policy.next = NULL;
+        policy.window_size = 128;
+        policy.allow_repeat_tx = 0;
+        policy.rtp.sec_serv = sec_servs;
+        policy.rtcp.sec_serv =
+            sec_servs; // sec_serv_none;  /* we don't do RTCP anyway */
+        fprintf(stderr, "setting tag len %d\n", scs.tag_size);
+        policy.rtp.auth_tag_len = scs.tag_size;
+
+        if (gcm_on && scs.tag_size != 8) {
+            fprintf(stderr, "setted tag len %d\n", scs.tag_size);
+            policy.rtp.auth_tag_len = scs.tag_size;
+        }
+
+        /*
+         * read key from hexadecimal or base64 on command line into an octet
+         * string
+         */
+        if (b64_input) {
+            int pad;
+            expected_len = policy.rtp.cipher_key_len * 4 / 3;
+            len = base64_string_to_octet_string(key, &pad, input_key,
+                                                expected_len);
+            if (pad != 0) {
+                fprintf(stderr, "error: padding in base64 unexpected\n");
+                exit(1);
+            }
+        } else {
+            expected_len = policy.rtp.cipher_key_len * 2;
+            len = hex_string_to_octet_string(key, input_key, expected_len);
+        }
+        /* check that hex string is the right length */
+        if (len < expected_len) {
+            fprintf(stderr, "error: too few digits in key/salt "
+                            "(should be %d digits, found %d)\n",
+                    expected_len, len);
+            exit(1);
+        }
+        if (strlen(input_key) > policy.rtp.cipher_key_len * 2) {
+            fprintf(stderr, "error: too many digits in key/salt "
+                            "(should be %d hexadecimal digits, found %u)\n",
+                    policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
+            exit(1);
+        }
+
+        fprintf(stderr, "set master key/salt to %s/",
+                octet_string_hex_string(key, 16));
+        fprintf(stderr, "%s\n", octet_string_hex_string(key + 16, 14));
+
+    } else {
+        fprintf(stderr,
+                "error: neither encryption or authentication were selected");
+        exit(1);
+    }
+
+    pcap_handle = pcap_open_offline("-", errbuf);
+
+    if (!pcap_handle) {
+        fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
+        exit(1);
+    }
+    assert(pcap_handle != NULL);
+    if ((pcap_compile(pcap_handle, &fp, filter_exp, 1, pcap_net)) == -1) {
+        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp,
+                pcap_geterr(pcap_handle));
+        return (2);
+    }
+    if (pcap_setfilter(pcap_handle, &fp) == -1) {
+        fprintf(stderr, "couldn't install filter %s: %s\n", filter_exp,
+                pcap_geterr(pcap_handle));
+        return (2);
+    }
+    dec = rtp_decoder_alloc();
+    if (dec == NULL) {
+        fprintf(stderr, "error: malloc() failed\n");
+        exit(1);
+    }
+    fprintf(stderr, "Starting decoder\n");
+    rtp_decoder_init(dec, policy);
+
+    pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
+
+    rtp_decoder_deinit_srtp(dec);
+    rtp_decoder_dealloc(dec);
+
+    status = srtp_shutdown();
+    if (status) {
+        fprintf(stderr, "error: srtp shutdown failed with error code %d\n",
+                status);
+        exit(1);
+    }
+
+    return 0;
+}
+
+void usage(char *string)
+{
+    fprintf(
+        stderr,
+        "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
+        "or     %s -l\n"
+        "where  -a use message authentication\n"
+        "       -e <key size> use encryption (use 128 or 256 for key size)\n"
+        "       -g Use AES-GCM mode (must be used with -e)\n"
+        "       -t <tag size> Tag size to use (in GCM mode use 8 or 16)\n"
+        "       -k <key>  sets the srtp master key given in hexadecimal\n"
+        "       -b <key>  sets the srtp master key given in base64\n"
+        "       -l list debug modules\n"
+        "       -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
+        "       -d <debug> turn on debugging for module <debug>\n"
+        "       -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
+        "          on RFC4568-style crypto suite specification\n",
+        string, string);
+    exit(1);
+}
+
+rtp_decoder_t rtp_decoder_alloc(void)
+{
+    return (rtp_decoder_t)malloc(sizeof(rtp_decoder_ctx_t));
+}
+
+void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
+{
+    free(rtp_ctx);
+}
+
+srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
+                                        unsigned int ssrc)
+{
+    decoder->policy.ssrc.value = htonl(ssrc);
+    return srtp_create(&decoder->srtp_ctx, &decoder->policy);
+}
+
+int rtp_decoder_deinit_srtp(rtp_decoder_t decoder)
+{
+    return srtp_dealloc(decoder->srtp_ctx);
+}
+
+int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy)
+{
+    dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
+    dcdr->srtp_ctx = NULL;
+    dcdr->start_tv.tv_usec = 0;
+    dcdr->start_tv.tv_sec = 0;
+    dcdr->frame_nr = -1;
+    dcdr->policy = policy;
+    dcdr->policy.ssrc.type = ssrc_specific;
+    return 0;
+}
+
+/*
+ * decodes key as base64
+ */
+
+void hexdump(const void *ptr, size_t size)
+{
+    int i, j;
+    const unsigned char *cptr = ptr;
+
+    for (i = 0; i < size; i += 16) {
+        fprintf(stdout, "%04x ", i);
+        for (j = 0; j < 16 && i + j < size; j++) {
+            fprintf(stdout, "%02x ", cptr[i + j]);
+        }
+        fprintf(stdout, "\n");
+    }
+}
+
+void rtp_decoder_handle_pkt(u_char *arg,
+                            const struct pcap_pkthdr *hdr,
+                            const u_char *bytes)
+{
+    rtp_decoder_t dcdr = (rtp_decoder_t)arg;
+    int pktsize;
+    struct timeval delta;
+    int octets_recvd;
+    srtp_err_status_t status;
+    dcdr->frame_nr++;
+
+    if ((dcdr->start_tv.tv_sec == 0) && (dcdr->start_tv.tv_usec == 0)) {
+        dcdr->start_tv = hdr->ts;
+    }
+
+    if (hdr->caplen < dcdr->rtp_offset) {
+        return;
+    }
+    const void *rtp_packet = bytes + dcdr->rtp_offset;
+
+    memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
+    pktsize = hdr->caplen - dcdr->rtp_offset;
+    octets_recvd = pktsize;
+
+    if (octets_recvd == -1) {
+        return;
+    }
+
+    /* verify rtp header */
+    if (dcdr->message.header.version != 2) {
+        return;
+    }
+    if (dcdr->srtp_ctx == NULL) {
+        status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
+        if (status) {
+            exit(1);
+        }
+    }
+    status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
+    if (status) {
+        return;
+    }
+    timersub(&hdr->ts, &dcdr->start_tv, &delta);
+    fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
+            (long)delta.tv_usec);
+    hexdump(&dcdr->message, octets_recvd);
+}
+
+void rtp_print_error(srtp_err_status_t status, char *message)
+{
+    // clang-format off
+    fprintf(stderr,
+            "error: %s %d%s\n", message, status,
+            status == srtp_err_status_replay_fail ? " (replay check failed)" :
+            status == srtp_err_status_bad_param ? " (bad param)" :
+            status == srtp_err_status_no_ctx ? " (no context)" :
+            status == srtp_err_status_cipher_fail ? " (cipher failed)" :
+            status == srtp_err_status_key_expired ? " (key expired)" :
+            status == srtp_err_status_auth_fail ? " (auth check failed)" : "");
+    // clang-format on
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rtp_decoder.h
@@ -0,0 +1,105 @@
+/*
+ * rtp_decoder.h
+ *
+ * decoder structures and functions for SRTP pcap decoder
+ *
+ * Bernardo Torres <bernardo@torresautomacao.com.br>
+ *
+ * Some structure and code from https://github.com/gteissier/srtp-decrypt
+ *
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef RTP_DECODER_H
+#define RTP_DECODER_H
+
+#include "srtp_priv.h"
+#include "rtp.h"
+
+#define DEFAULT_RTP_OFFSET 42
+
+typedef struct rtp_decoder_ctx_t {
+    srtp_policy_t policy;
+    srtp_ctx_t *srtp_ctx;
+    int rtp_offset;
+    struct timeval start_tv;
+    int frame_nr;
+    rtp_msg_t message;
+} rtp_decoder_ctx_t;
+
+typedef struct rtp_decoder_ctx_t *rtp_decoder_t;
+
+/*
+ * error to string
+ */
+void rtp_print_error(srtp_err_status_t status, char *message);
+
+/*
+ * prints the output of a random buffer in hexadecimal
+ */
+void hexdump(const void *ptr, size_t size);
+
+/*
+ * the function usage() prints an error message describing how this
+ * program should be called, then calls exit()
+ */
+void usage(char *prog_name);
+
+/*
+ * transforms base64 key into octet
+ */
+char *decode_sdes(char *in, char *out);
+
+/*
+ * pcap handling
+ */
+void rtp_decoder_handle_pkt(u_char *arg,
+                            const struct pcap_pkthdr *hdr,
+                            const u_char *bytes);
+
+rtp_decoder_t rtp_decoder_alloc(void);
+
+void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx);
+
+int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy);
+
+srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
+                                        unsigned int ssrc);
+
+int rtp_decoder_deinit_srtp(rtp_decoder_t decoder);
+
+#endif /* RTP_DECODER_H */
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/rtpw.c
@@ -0,0 +1,700 @@
+/*
+ * rtpw.c
+ *
+ * rtp word sender/receiver
+ *
+ * David A. McGrew
+ * Cisco Systems, Inc.
+ *
+ * This app is a simple RTP application intended only for testing
+ * libsrtp.  It reads one word at a time from words.txt (or
+ * whatever file is specified as DICT_FILE or with -w), and sends one word out
+ * each USEC_RATE microseconds.  Secure RTP protections can be
+ * applied.  See the usage() function for more details.
+ *
+ */
+
+/*
+ *
+ * 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 "getopt_s.h" /* for local getopt()  */
+
+#include <stdio.h>  /* for printf, fprintf */
+#include <stdlib.h> /* for atoi()          */
+#include <errno.h>
+#include <signal.h> /* for signal()        */
+
+#include <string.h> /* for strncpy()       */
+#include <time.h>   /* for usleep()        */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* for close()         */
+#elif defined(_MSC_VER)
+#include <io.h> /* for _close()        */
+#define close _close
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined HAVE_WINSOCK2_H
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define RTPW_USE_WINSOCK2 1
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "srtp.h"
+#include "rtp.h"
+#include "util.h"
+
+#define DICT_FILE "words.txt"
+#define USEC_RATE (5e5)
+#define MAX_WORD_LEN 128
+#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a))
+#define MAX_KEY_LEN 96
+
+#ifndef HAVE_USLEEP
+#ifdef HAVE_WINDOWS_H
+#define usleep(us) Sleep((us) / 1000)
+#else
+#define usleep(us) sleep((us) / 1000000)
+#endif
+#endif
+
+/*
+ * the function usage() prints an error message describing how this
+ * program should be called, then calls exit()
+ */
+
+void usage(char *prog_name);
+
+/*
+ * leave_group(...) de-registers from a multicast group
+ */
+
+void leave_group(int sock, struct ip_mreq mreq, char *name);
+
+/*
+ * setup_signal_handler() sets up a signal handler to trigger
+ * cleanups after an interrupt
+ */
+int setup_signal_handler(char *name);
+
+/*
+ * handle_signal(...) handles interrupt signal to trigger cleanups
+ */
+
+volatile int interrupted = 0;
+
+/*
+ * program_type distinguishes the [s]rtp sender and receiver cases
+ */
+
+typedef enum { sender, receiver, unknown } program_type;
+
+int main(int argc, char *argv[])
+{
+    char *dictfile = DICT_FILE;
+    FILE *dict;
+    char word[MAX_WORD_LEN];
+    int sock, ret;
+    struct in_addr rcvr_addr;
+    struct sockaddr_in name;
+    struct ip_mreq mreq;
+#if BEW
+    struct sockaddr_in local;
+#endif
+    program_type prog_type = unknown;
+    srtp_sec_serv_t sec_servs = sec_serv_none;
+    unsigned char ttl = 5;
+    int c;
+    int key_size = 128;
+    int tag_size = 8;
+    int gcm_on = 0;
+    char *input_key = NULL;
+    int b64_input = 0;
+    char *address = NULL;
+    char key[MAX_KEY_LEN];
+    unsigned short port = 0;
+    rtp_sender_t snd;
+    srtp_policy_t policy;
+    srtp_err_status_t status;
+    int len;
+    int expected_len;
+    int do_list_mods = 0;
+    uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
+#ifdef RTPW_USE_WINSOCK2
+    WORD wVersionRequested = MAKEWORD(2, 0);
+    WSADATA wsaData;
+
+    ret = WSAStartup(wVersionRequested, &wsaData);
+    if (ret != 0) {
+        fprintf(stderr, "error: WSAStartup() failed: %d\n", ret);
+        exit(1);
+    }
+#endif
+
+    memset(&policy, 0x0, sizeof(srtp_policy_t));
+
+    printf("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
+
+    if (setup_signal_handler(argv[0]) != 0) {
+        exit(1);
+    }
+
+    /* initialize srtp library */
+    status = srtp_init();
+    if (status) {
+        printf("error: srtp initialization failed with error code %d\n",
+               status);
+        exit(1);
+    }
+
+    /* check args */
+    while (1) {
+        c = getopt_s(argc, argv, "b:k:rsgt:ae:ld:w:");
+        if (c == -1) {
+            break;
+        }
+        switch (c) {
+        case 'b':
+            b64_input = 1;
+        /* fall thru */
+        case 'k':
+            input_key = optarg_s;
+            break;
+        case 'e':
+            key_size = atoi(optarg_s);
+            if (key_size != 128 && key_size != 256) {
+                printf("error: encryption key size must be 128 or 256 (%d)\n",
+                       key_size);
+                exit(1);
+            }
+            sec_servs |= sec_serv_conf;
+            break;
+        case 't':
+            tag_size = atoi(optarg_s);
+            if (tag_size != 8 && tag_size != 16) {
+                printf("error: GCM tag size must be 8 or 16 (%d)\n", tag_size);
+                exit(1);
+            }
+            break;
+        case 'a':
+            sec_servs |= sec_serv_auth;
+            break;
+        case 'g':
+            gcm_on = 1;
+            sec_servs |= sec_serv_auth;
+            break;
+        case 'r':
+            prog_type = receiver;
+            break;
+        case 's':
+            prog_type = sender;
+            break;
+        case 'd':
+            status = srtp_set_debug_module(optarg_s, 1);
+            if (status) {
+                printf("error: set debug module (%s) failed\n", optarg_s);
+                exit(1);
+            }
+            break;
+        case 'l':
+            do_list_mods = 1;
+            break;
+        case 'w':
+            dictfile = optarg_s;
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (prog_type == unknown) {
+        if (do_list_mods) {
+            status = srtp_list_debug_modules();
+            if (status) {
+                printf("error: list of debug modules failed\n");
+                exit(1);
+            }
+            return 0;
+        } else {
+            printf("error: neither sender [-s] nor receiver [-r] specified\n");
+            usage(argv[0]);
+        }
+    }
+
+    if ((sec_servs && !input_key) || (!sec_servs && input_key)) {
+        /*
+         * a key must be provided if and only if security services have
+         * been requested
+         */
+        usage(argv[0]);
+    }
+
+    if (argc != optind_s + 2) {
+        /* wrong number of arguments */
+        usage(argv[0]);
+    }
+
+    /* get address from arg */
+    address = argv[optind_s++];
+
+    /* get port from arg */
+    port = atoi(argv[optind_s++]);
+
+/* set address */
+#ifdef HAVE_INET_ATON
+    if (0 == inet_aton(address, &rcvr_addr)) {
+        fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0],
+                address);
+        exit(1);
+    }
+    if (rcvr_addr.s_addr == INADDR_NONE) {
+        fprintf(stderr, "%s: address error", argv[0]);
+        exit(1);
+    }
+#else
+    rcvr_addr.s_addr = inet_addr(address);
+    if (0xffffffff == rcvr_addr.s_addr) {
+        fprintf(stderr, "%s: cannot parse IP v4 address %s\n", argv[0],
+                address);
+        exit(1);
+    }
+#endif
+
+    /* open socket */
+    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    if (sock < 0) {
+        int err;
+#ifdef RTPW_USE_WINSOCK2
+        err = WSAGetLastError();
+#else
+        err = errno;
+#endif
+        fprintf(stderr, "%s: couldn't open socket: %d\n", argv[0], err);
+        exit(1);
+    }
+
+    name.sin_addr = rcvr_addr;
+    name.sin_family = PF_INET;
+    name.sin_port = htons(port);
+
+    if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+        if (prog_type == sender) {
+            ret = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
+                             sizeof(ttl));
+            if (ret < 0) {
+                fprintf(stderr, "%s: Failed to set TTL for multicast group",
+                        argv[0]);
+                perror("");
+                exit(1);
+            }
+        }
+
+        mreq.imr_multiaddr.s_addr = rcvr_addr.s_addr;
+        mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+        ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq,
+                         sizeof(mreq));
+        if (ret < 0) {
+            fprintf(stderr, "%s: Failed to join multicast group", argv[0]);
+            perror("");
+            exit(1);
+        }
+    }
+
+    /* report security services selected on the command line */
+    printf("security services: ");
+    if (sec_servs & sec_serv_conf)
+        printf("confidentiality ");
+    if (sec_servs & sec_serv_auth)
+        printf("message authentication");
+    if (sec_servs == sec_serv_none)
+        printf("none");
+    printf("\n");
+
+    /* set up the srtp policy and master key */
+    if (sec_servs) {
+        /*
+         * create policy structure, using the default mechanisms but
+         * with only the security services requested on the command line,
+         * using the right SSRC value
+         */
+        switch (sec_servs) {
+        case sec_serv_conf_and_auth:
+            if (gcm_on) {
+#ifdef OPENSSL
+                switch (key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
+                    break;
+                }
+#else
+                printf("error: GCM mode only supported when using the OpenSSL "
+                       "crypto engine.\n");
+                return 0;
+#endif
+            } else {
+                switch (key_size) {
+                case 128:
+                    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                }
+            }
+            break;
+        case sec_serv_conf:
+            if (gcm_on) {
+                printf(
+                    "error: GCM mode must always be used with auth enabled\n");
+                return -1;
+            } else {
+                switch (key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+                    break;
+                }
+            }
+            break;
+        case sec_serv_auth:
+            if (gcm_on) {
+#ifdef OPENSSL
+                switch (key_size) {
+                case 128:
+                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_128_8_only_auth(
+                        &policy.rtcp);
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_gcm_256_8_only_auth(
+                        &policy.rtcp);
+                    break;
+                }
+#else
+                printf("error: GCM mode only supported when using the OpenSSL "
+                       "crypto engine.\n");
+                return 0;
+#endif
+            } else {
+                srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
+                srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+            }
+            break;
+        default:
+            printf("error: unknown security service requested\n");
+            return -1;
+        }
+        policy.ssrc.type = ssrc_specific;
+        policy.ssrc.value = ssrc;
+        policy.key = (uint8_t *)key;
+        policy.ekt = NULL;
+        policy.next = NULL;
+        policy.window_size = 128;
+        policy.allow_repeat_tx = 0;
+        policy.rtp.sec_serv = sec_servs;
+        policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
+
+        if (gcm_on && tag_size != 8) {
+            policy.rtp.auth_tag_len = tag_size;
+        }
+
+        /*
+         * read key from hexadecimal or base64 on command line into an octet
+         * string
+         */
+        if (b64_input) {
+            int pad;
+            expected_len = (policy.rtp.cipher_key_len * 4) / 3;
+            len = base64_string_to_octet_string(key, &pad, input_key,
+                                                expected_len);
+            if (pad != 0) {
+                fprintf(stderr, "error: padding in base64 unexpected\n");
+                exit(1);
+            }
+        } else {
+            expected_len = policy.rtp.cipher_key_len * 2;
+            len = hex_string_to_octet_string(key, input_key, expected_len);
+        }
+        /* check that hex string is the right length */
+        if (len < expected_len) {
+            fprintf(stderr, "error: too few digits in key/salt "
+                            "(should be %d digits, found %d)\n",
+                    expected_len, len);
+            exit(1);
+        }
+        if ((int)strlen(input_key) > policy.rtp.cipher_key_len * 2) {
+            fprintf(stderr, "error: too many digits in key/salt "
+                            "(should be %d hexadecimal digits, found %u)\n",
+                    policy.rtp.cipher_key_len * 2, (unsigned)strlen(input_key));
+            exit(1);
+        }
+
+        printf("set master key/salt to %s/", octet_string_hex_string(key, 16));
+        printf("%s\n", octet_string_hex_string(key + 16, 14));
+
+    } else {
+        /*
+         * we're not providing security services, so set the policy to the
+         * null policy
+         *
+         * Note that this policy does not conform to the SRTP
+         * specification, since RTCP authentication is required.  However,
+         * the effect of this policy is to turn off SRTP, so that this
+         * application is now a vanilla-flavored RTP application.
+         */
+        srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtp);
+        srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtcp);
+        policy.key = (uint8_t *)key;
+        policy.ssrc.type = ssrc_specific;
+        policy.ssrc.value = ssrc;
+        policy.window_size = 0;
+        policy.allow_repeat_tx = 0;
+        policy.ekt = NULL;
+        policy.next = NULL;
+    }
+
+    if (prog_type == sender) {
+#if BEW
+        /* bind to local socket (to match crypto policy, if need be) */
+        memset(&local, 0, sizeof(struct sockaddr_in));
+        local.sin_addr.s_addr = htonl(INADDR_ANY);
+        local.sin_port = htons(port);
+        ret = bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_in));
+        if (ret < 0) {
+            fprintf(stderr, "%s: bind failed\n", argv[0]);
+            perror("");
+            exit(1);
+        }
+#endif /* BEW */
+
+        /* initialize sender's rtp and srtp contexts */
+        snd = rtp_sender_alloc();
+        if (snd == NULL) {
+            fprintf(stderr, "error: malloc() failed\n");
+            exit(1);
+        }
+        rtp_sender_init(snd, sock, name, ssrc);
+        status = rtp_sender_init_srtp(snd, &policy);
+        if (status) {
+            fprintf(stderr, "error: srtp_create() failed with code %d\n",
+                    status);
+            exit(1);
+        }
+
+        /* open dictionary */
+        dict = fopen(dictfile, "r");
+        if (dict == NULL) {
+            fprintf(stderr, "%s: couldn't open file %s\n", argv[0], dictfile);
+            if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+                leave_group(sock, mreq, argv[0]);
+            }
+            exit(1);
+        }
+
+        /* read words from dictionary, then send them off */
+        while (!interrupted && fgets(word, MAX_WORD_LEN, dict) != NULL) {
+            len = strlen(word) + 1; /* plus one for null */
+
+            if (len > MAX_WORD_LEN)
+                printf("error: word %s too large to send\n", word);
+            else {
+                rtp_sendto(snd, word, len);
+                printf("sending word: %s", word);
+            }
+            usleep(USEC_RATE);
+        }
+
+        rtp_sender_deinit_srtp(snd);
+        rtp_sender_dealloc(snd);
+
+        fclose(dict);
+    } else { /* prog_type == receiver */
+        rtp_receiver_t rcvr;
+
+        if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
+            close(sock);
+            fprintf(stderr, "%s: socket bind error\n", argv[0]);
+            perror(NULL);
+            if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+                leave_group(sock, mreq, argv[0]);
+            }
+            exit(1);
+        }
+
+        rcvr = rtp_receiver_alloc();
+        if (rcvr == NULL) {
+            fprintf(stderr, "error: malloc() failed\n");
+            exit(1);
+        }
+        rtp_receiver_init(rcvr, sock, name, ssrc);
+        status = rtp_receiver_init_srtp(rcvr, &policy);
+        if (status) {
+            fprintf(stderr, "error: srtp_create() failed with code %d\n",
+                    status);
+            exit(1);
+        }
+
+        /* get next word and loop */
+        while (!interrupted) {
+            len = MAX_WORD_LEN;
+            if (rtp_recvfrom(rcvr, word, &len) > -1)
+                printf("\tword: %s\n", word);
+        }
+
+        rtp_receiver_deinit_srtp(rcvr);
+        rtp_receiver_dealloc(rcvr);
+    }
+
+    if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+        leave_group(sock, mreq, argv[0]);
+    }
+
+#ifdef RTPW_USE_WINSOCK2
+    ret = closesocket(sock);
+#else
+    ret = close(sock);
+#endif
+    if (ret < 0) {
+        fprintf(stderr, "%s: Failed to close socket", argv[0]);
+        perror("");
+    }
+
+    status = srtp_shutdown();
+    if (status) {
+        printf("error: srtp shutdown failed with error code %d\n", status);
+        exit(1);
+    }
+
+#ifdef RTPW_USE_WINSOCK2
+    WSACleanup();
+#endif
+
+    return 0;
+}
+
+void usage(char *string)
+{
+    printf("usage: %s [-d <debug>]* [-k <key> [-a][-e]] "
+           "[-s | -r] dest_ip dest_port\n"
+           "or     %s -l\n"
+           "where  -a use message authentication\n"
+           "       -e <key size> use encryption (use 128 or 256 for key size)\n"
+           "       -g Use AES-GCM mode (must be used with -e)\n"
+           "       -t <tag size> Tag size to use in GCM mode (use 8 or 16)\n"
+           "       -k <key>  sets the srtp master key given in hexadecimal\n"
+           "       -b <key>  sets the srtp master key given in base64\n"
+           "       -s act as rtp sender\n"
+           "       -r act as rtp receiver\n"
+           "       -l list debug modules\n"
+           "       -d <debug> turn on debugging for module <debug>\n"
+           "       -w <wordsfile> use <wordsfile> for input, rather than %s\n",
+           string, string, DICT_FILE);
+    exit(1);
+}
+
+void leave_group(int sock, struct ip_mreq mreq, char *name)
+{
+    int ret;
+
+    ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq,
+                     sizeof(mreq));
+    if (ret < 0) {
+        fprintf(stderr, "%s: Failed to leave multicast group", name);
+        perror("");
+    }
+}
+
+void handle_signal(int signum)
+{
+    interrupted = 1;
+    /* Reset handler explicitly, in case we don't have sigaction() (and signal()
+       has BSD semantics), or we don't have SA_RESETHAND */
+    signal(signum, SIG_DFL);
+}
+
+int setup_signal_handler(char *name)
+{
+#if HAVE_SIGACTION
+    struct sigaction act;
+    memset(&act, 0, sizeof(act));
+
+    act.sa_handler = handle_signal;
+    sigemptyset(&act.sa_mask);
+#if defined(SA_RESETHAND)
+    act.sa_flags = SA_RESETHAND;
+#else
+    act.sa_flags = 0;
+#endif
+    /* Note that we're not setting SA_RESTART; we want recvfrom to return
+     * EINTR when we signal the receiver. */
+
+    if (sigaction(SIGTERM, &act, NULL) != 0) {
+        fprintf(stderr, "%s: error setting up signal handler", name);
+        perror("");
+        return -1;
+    }
+#else
+    if (signal(SIGTERM, handle_signal) == SIG_ERR) {
+        fprintf(stderr, "%s: error setting up signal handler", name);
+        perror("");
+        return -1;
+    }
+#endif
+    return 0;
+}
new file mode 100755
--- /dev/null
+++ b/netwerk/srtp/src/test/rtpw_test.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+# 
+# usage: rtpw_test <rtpw_commands>
+# 
+# tests the rtpw sender and receiver functions
+#
+# 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.
+#
+
+case $(uname -s) in
+    *CYGWIN*|*MINGW*)
+        EXE=".exe"
+        ;;
+    *)
+        EXE=""
+        ;;
+esac
+
+RTPW=./rtpw$EXE
+DEST_PORT=9999
+DURATION=3
+
+key=Ky7cUDT2GnI0XKWYbXv9AYmqbcLsqzL9mvdN9t/G
+
+ARGS="-b $key -a -e 128"
+
+# First, we run "killall" to get rid of all existing rtpw processes.
+# This step also enables this script to clean up after itself; if this
+# script is interrupted after the rtpw processes are started but before
+# they are killed, those processes will linger.  Re-running the script
+# will get rid of them.
+
+killall rtpw 2>/dev/null
+
+if test -x $RTPW; then
+
+echo  $0 ": starting rtpw receiver process... "
+
+$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT  &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting rtpw sender process..."
+
+$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+
+key=033490ba9e82994fc21013395739038992b2edc5034f61a72345ca598d7bfd0189aa6dc2ecab32fd9af74df6dfc6
+
+ARGS="-k $key -a -e 256"
+
+echo  $0 ": starting rtpw receiver process... "
+
+$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT  &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting rtpw sender process..."
+
+$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+echo $0 ": done (test passed)"
+
+else 
+
+echo "error: can't find executable" $RTPW
+exit 1
+
+fi
+
+# EOF
+
+
new file mode 100755
--- /dev/null
+++ b/netwerk/srtp/src/test/rtpw_test_gcm.sh
@@ -0,0 +1,255 @@
+#!/bin/sh
+# 
+# usage: rtpw_test <rtpw_commands>
+# 
+# tests the rtpw sender and receiver functions
+#
+# 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.
+#
+
+case $(uname -s) in
+    *CYGWIN*|*MINGW*)
+        EXE=".exe"
+        ;;
+    *)
+        EXE=""
+        ;;
+esac
+
+RTPW=./rtpw$EXE
+DEST_PORT=9999
+DURATION=3
+
+# First, we run "killall" to get rid of all existing rtpw processes.
+# This step also enables this script to clean up after itself; if this
+# script is interrupted after the rtpw processes are started but before
+# they are killed, those processes will linger.  Re-running the script
+# will get rid of them.
+
+killall rtpw 2>/dev/null
+
+if test -x $RTPW; then
+
+GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -e 128"
+echo  $0 ": starting GCM mode 128-bit rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting GCM 128-bit rtpw sender process..."
+
+exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -t 16 -e 128"
+echo  $0 ": starting GCM mode 128-bit (16 byte tag) rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS128 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting GCM 128-bit (16 byte tag) rtpw sender process..."
+
+exec $RTPW $* $GCMARGS128 -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+
+GCMARGS256="-k 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -e 256"
+echo  $0 ": starting GCM mode 256-bit rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting GCM 256-bit rtpw sender process..."
+
+exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+GCMARGS256="-k a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 -g -t 16 -e 256"
+echo  $0 ": starting GCM mode 256-bit (16 byte tag) rtpw receiver process... "
+
+exec $RTPW $* $GCMARGS256 -r 127.0.0.1 $DEST_PORT &
+
+receiver_pid=$!
+
+echo $0 ": receiver PID = $receiver_pid"
+
+sleep 1 
+
+# verify that the background job is running
+ps -e | grep -q $receiver_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 254
+fi
+
+echo  $0 ": starting GCM 256-bit (16 byte tag) rtpw sender process..."
+
+exec $RTPW $* $GCMARGS256 -s 127.0.0.1 $DEST_PORT  &
+
+sender_pid=$!
+
+echo $0 ": sender PID = $sender_pid"
+
+# verify that the background job is running
+ps -e | grep -q $sender_pid
+retval=$?
+echo $retval
+if [ $retval != 0 ]; then
+    echo $0 ": error"
+    exit 255
+fi
+
+sleep $DURATION
+
+kill $receiver_pid
+kill $sender_pid
+
+wait $receiver_pid 2>/dev/null
+wait $sender_pid 2>/dev/null
+
+echo $0 ": done (test passed)"
+
+else 
+
+echo "error: can't find executable" $RTPW
+exit 1
+
+fi
+
+# EOF
+
+
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/srtp_driver.c
@@ -0,0 +1,3831 @@
+/*
+ * srtp_driver.c
+ *
+ * a test driver for libSRTP
+ *
+ * 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.
+ *
+ */
+
+#include <string.h>   /* for memcpy()          */
+#include <time.h>     /* for clock()           */
+#include <stdlib.h>   /* for malloc(), free()  */
+#include <stdio.h>    /* for print(), fflush() */
+#include "getopt_s.h" /* for local getopt()    */
+
+#include "srtp_priv.h"
+#include "util.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+#define PRINT_REFERENCE_PACKET 1
+
+srtp_err_status_t srtp_validate(void);
+
+#ifdef OPENSSL
+srtp_err_status_t srtp_validate_gcm(void);
+#endif
+
+srtp_err_status_t srtp_validate_encrypted_extensions_headers(void);
+
+#ifdef OPENSSL
+srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm(void);
+#endif
+
+srtp_err_status_t srtp_validate_aes_256(void);
+
+srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list);
+
+srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list);
+
+srtp_err_status_t srtp_test_empty_payload(void);
+
+#ifdef OPENSSL
+srtp_err_status_t srtp_test_empty_payload_gcm(void);
+#endif
+
+srtp_err_status_t srtp_test_remove_stream(void);
+
+srtp_err_status_t srtp_test_update(void);
+
+srtp_err_status_t srtp_test_protect_trailer_length(void);
+
+srtp_err_status_t srtp_test_protect_rtcp_trailer_length(void);
+
+srtp_err_status_t srtp_test_get_roc(void);
+
+srtp_err_status_t srtp_test_set_receiver_roc(void);
+
+srtp_err_status_t srtp_test_set_sender_roc(void);
+
+double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
+
+double srtp_rejections_per_second(int msg_len_octets,
+                                  const srtp_policy_t *policy);
+
+void srtp_do_timing(const srtp_policy_t *policy);
+
+void srtp_do_rejection_timing(const srtp_policy_t *policy);
+
+srtp_err_status_t srtp_test(const srtp_policy_t *policy,
+                            int extension_header,
+                            int mki_index);
+
+srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index);
+
+srtp_err_status_t srtp_session_print_policy(srtp_t srtp);
+
+srtp_err_status_t srtp_print_policy(const srtp_policy_t *policy);
+
+char *srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
+
+double mips_estimate(int num_trials, int *ignore);
+
+#define TEST_MKI_ID_SIZE 4
+
+extern uint8_t test_key[46];
+extern uint8_t test_key_2[46];
+extern uint8_t test_mki_id[TEST_MKI_ID_SIZE];
+extern uint8_t test_mki_id_2[TEST_MKI_ID_SIZE];
+
+// clang-format off
+srtp_master_key_t master_key_1 = {
+    test_key,
+    test_mki_id,
+    TEST_MKI_ID_SIZE
+};
+
+srtp_master_key_t master_key_2 = {
+    test_key_2,
+    test_mki_id_2,
+    TEST_MKI_ID_SIZE
+};
+
+srtp_master_key_t *test_keys[2] = {
+    &master_key_1,
+    &master_key_2
+};
+// clang-format on
+
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -t ][ -c ][ -v ][ -o ][-d <debug_module> ]* [ -l ]\n"
+           "  -t         run timing test\n"
+           "  -r         run rejection timing test\n"
+           "  -c         run codec timing test\n"
+           "  -v         run validation tests\n"
+           "  -o         output logging to stdout\n"
+           "  -d <mod>   turn on debugging module <mod>\n"
+           "  -l         list debugging modules\n",
+           prog_name);
+    exit(1);
+}
+
+void log_handler(srtp_log_level_t level, const char *msg, void *data)
+{
+    char level_char = '?';
+    switch (level) {
+    case srtp_log_level_error:
+        level_char = 'e';
+        break;
+    case srtp_log_level_warning:
+        level_char = 'w';
+        break;
+    case srtp_log_level_info:
+        level_char = 'i';
+        break;
+    case srtp_log_level_debug:
+        level_char = 'd';
+        break;
+    }
+    printf("SRTP-LOG [%c]: %s\n", level_char, msg);
+}
+
+/*
+ * The policy_array is a null-terminated array of policy structs. it
+ * is declared at the end of this file
+ */
+
+extern const srtp_policy_t *policy_array[];
+
+/* the wildcard_policy is declared below; it has a wildcard ssrc */
+
+extern const srtp_policy_t wildcard_policy;
+
+/*
+ * mod_driver debug module - debugging module for this test driver
+ *
+ * we use the crypto_kernel debugging system in this driver, which
+ * makes the interface uniform and increases portability
+ */
+
+srtp_debug_module_t mod_driver = {
+    0,       /* debugging is off by default */
+    "driver" /* printable name for module   */
+};
+
+int main(int argc, char *argv[])
+{
+    int q;
+    unsigned do_timing_test = 0;
+    unsigned do_rejection_test = 0;
+    unsigned do_codec_timing = 0;
+    unsigned do_validation = 0;
+    unsigned do_list_mods = 0;
+    unsigned do_log_stdout = 0;
+    srtp_err_status_t status;
+
+    /*
+     * verify that the compiler has interpreted the header data
+     * structure srtp_hdr_t correctly
+     */
+    if (sizeof(srtp_hdr_t) != 12) {
+        printf("error: srtp_hdr_t has incorrect size"
+               "(size is %ld bytes, expected 12)\n",
+               (long)sizeof(srtp_hdr_t));
+        exit(1);
+    }
+
+    /* initialize srtp library */
+    status = srtp_init();
+    if (status) {
+        printf("error: srtp init failed with error code %d\n", status);
+        exit(1);
+    }
+
+    /*  load srtp_driver debug module */
+    status = srtp_crypto_kernel_load_debug_module(&mod_driver);
+    if (status) {
+        printf("error: load of srtp_driver debug module failed "
+               "with error code %d\n",
+               status);
+        exit(1);
+    }
+
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "trcvold:");
+        if (q == -1) {
+            break;
+        }
+        switch (q) {
+        case 't':
+            do_timing_test = 1;
+            break;
+        case 'r':
+            do_rejection_test = 1;
+            break;
+        case 'c':
+            do_codec_timing = 1;
+            break;
+        case 'v':
+            do_validation = 1;
+            break;
+        case 'o':
+            do_log_stdout = 1;
+            break;
+        case 'l':
+            do_list_mods = 1;
+            break;
+        case 'd':
+            status = srtp_set_debug_module(optarg_s, 1);
+            if (status) {
+                printf("error: set debug module (%s) failed\n", optarg_s);
+                exit(1);
+            }
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (!do_validation && !do_timing_test && !do_codec_timing &&
+        !do_list_mods && !do_rejection_test) {
+        usage(argv[0]);
+    }
+
+    if (do_log_stdout) {
+        status = srtp_install_log_handler(log_handler, NULL);
+        if (status) {
+            printf("error: install log handler failed\n");
+            exit(1);
+        }
+    }
+
+    if (do_list_mods) {
+        status = srtp_list_debug_modules();
+        if (status) {
+            printf("error: list of debug modules failed\n");
+            exit(1);
+        }
+    }
+
+    if (do_validation) {
+        const srtp_policy_t **policy = policy_array;
+        srtp_policy_t *big_policy;
+
+        /* loop over policy array, testing srtp and srtcp for each policy */
+        while (*policy != NULL) {
+            printf("testing srtp_protect and srtp_unprotect\n");
+            if (srtp_test(*policy, 0, -1) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+
+            printf("testing srtp_protect and srtp_unprotect with encrypted "
+                   "extensions headers\n");
+            if (srtp_test(*policy, 1, -1) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+            printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
+            if (srtcp_test(*policy, -1) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+            printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI "
+                   "index set to 0\n");
+            if (srtp_test(*policy, 0, 0) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+            printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI "
+                   "index set to 1\n");
+            if (srtp_test(*policy, 0, 1) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+
+            printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI "
+                   "index set to 0\n");
+            if (srtcp_test(*policy, 0) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+            printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI "
+                   "index set to 1\n");
+            if (srtcp_test(*policy, 1) == srtp_err_status_ok) {
+                printf("passed\n\n");
+            } else {
+                printf("failed\n");
+                exit(1);
+            }
+            policy++;
+        }
+
+        /* create a big policy list and run tests on it */
+        status = srtp_create_big_policy(&big_policy);
+        if (status) {
+            printf("unexpected failure with error code %d\n", status);
+            exit(1);
+        }
+        printf("testing srtp_protect and srtp_unprotect with big policy\n");
+        if (srtp_test(big_policy, 0, -1) == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("testing srtp_protect and srtp_unprotect with big policy and "
+               "encrypted extensions headers\n");
+        if (srtp_test(big_policy, 1, -1) == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+        status = srtp_dealloc_big_policy(big_policy);
+        if (status) {
+            printf("unexpected failure with error code %d\n", status);
+            exit(1);
+        }
+
+        /* run test on wildcard policy */
+        printf("testing srtp_protect and srtp_unprotect on "
+               "wildcard ssrc policy\n");
+        if (srtp_test(&wildcard_policy, 0, -1) == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("testing srtp_protect and srtp_unprotect on "
+               "wildcard ssrc policy and encrypted extensions headers\n");
+        if (srtp_test(&wildcard_policy, 1, -1) == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        /*
+         * run validation test against the reference packets - note
+         * that this test only covers the default policy
+         */
+        printf("testing srtp_protect and srtp_unprotect against "
+               "reference packet\n");
+        if (srtp_validate() == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+#ifdef OPENSSL
+        printf("testing srtp_protect and srtp_unprotect against "
+               "reference packet using GCM\n");
+        if (srtp_validate_gcm() == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+#endif
+
+        printf("testing srtp_protect and srtp_unprotect against "
+               "reference packet with encrypted extensions headers\n");
+        if (srtp_validate_encrypted_extensions_headers() == srtp_err_status_ok)
+            printf("passed\n\n");
+        else {
+            printf("failed\n");
+            exit(1);
+        }
+
+#ifdef OPENSSL
+        printf("testing srtp_protect and srtp_unprotect against "
+               "reference packet with encrypted extension headers (GCM)\n");
+        if (srtp_validate_encrypted_extensions_headers_gcm() ==
+            srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+#endif
+
+        /*
+         * run validation test against the reference packets for
+         * AES-256
+         */
+        printf("testing srtp_protect and srtp_unprotect against "
+               "reference packet (AES-256)\n");
+        if (srtp_validate_aes_256() == srtp_err_status_ok) {
+            printf("passed\n\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        /*
+         * test packets with empty payload
+         */
+        printf("testing srtp_protect and srtp_unprotect against "
+               "packet with empty payload\n");
+        if (srtp_test_empty_payload() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+#ifdef OPENSSL
+        printf("testing srtp_protect and srtp_unprotect against "
+               "packet with empty payload (GCM)\n");
+        if (srtp_test_empty_payload_gcm() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+#endif
+
+        /*
+         * test the function srtp_remove_stream()
+         */
+        printf("testing srtp_remove_stream()...");
+        if (srtp_test_remove_stream() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        /*
+         * test the function srtp_update()
+         */
+        printf("testing srtp_update()...");
+        if (srtp_test_update() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        /*
+         * test the functions srtp_get_protect_trailer_length
+         * and srtp_get_protect_rtcp_trailer_length
+         */
+        printf("testing srtp_get_protect_trailer_length()...");
+        if (srtp_test_protect_trailer_length() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        printf("testing srtp_get_protect_rtcp_trailer_length()...");
+        if (srtp_test_protect_rtcp_trailer_length() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        printf("testing srtp_test_get_roc()...");
+        if (srtp_test_get_roc() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        printf("testing srtp_test_set_receiver_roc()...");
+        if (srtp_test_set_receiver_roc() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+
+        printf("testing srtp_test_set_sender_roc()...");
+        if (srtp_test_set_sender_roc() == srtp_err_status_ok) {
+            printf("passed\n");
+        } else {
+            printf("failed\n");
+            exit(1);
+        }
+    }
+
+    if (do_timing_test) {
+        const srtp_policy_t **policy = policy_array;
+
+        /* loop over policies, run timing test for each */
+        while (*policy != NULL) {
+            srtp_print_policy(*policy);
+            srtp_do_timing(*policy);
+            policy++;
+        }
+    }
+
+    if (do_rejection_test) {
+        const srtp_policy_t **policy = policy_array;
+
+        /* loop over policies, run rejection timing test for each */
+        while (*policy != NULL) {
+            srtp_print_policy(*policy);
+            srtp_do_rejection_timing(*policy);
+            policy++;
+        }
+    }
+
+    if (do_codec_timing) {
+        srtp_policy_t policy;
+        int ignore;
+        double mips_value = mips_estimate(1000000000, &ignore);
+
+        memset(&policy, 0, sizeof(policy));
+        srtp_crypto_policy_set_rtp_default(&policy.rtp);
+        srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+        policy.ssrc.type = ssrc_specific;
+        policy.ssrc.value = 0xdecafbad;
+        policy.key = test_key;
+        policy.ekt = NULL;
+        policy.window_size = 128;
+        policy.allow_repeat_tx = 0;
+        policy.next = NULL;
+
+        printf("mips estimate: %e\n", mips_value);
+
+        printf("testing srtp processing time for voice codecs:\n");
+        printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
+        printf("G.711\t\t%d\t\t\t%e\n", 80,
+               (double)mips_value * (80 * 8) /
+                   srtp_bits_per_second(80, &policy) / .01);
+        printf("G.711\t\t%d\t\t\t%e\n", 160,
+               (double)mips_value * (160 * 8) /
+                   srtp_bits_per_second(160, &policy) / .02);
+        printf("G.726-32\t%d\t\t\t%e\n", 40,
+               (double)mips_value * (40 * 8) /
+                   srtp_bits_per_second(40, &policy) / .01);
+        printf("G.726-32\t%d\t\t\t%e\n", 80,
+               (double)mips_value * (80 * 8) /
+                   srtp_bits_per_second(80, &policy) / .02);
+        printf("G.729\t\t%d\t\t\t%e\n", 10,
+               (double)mips_value * (10 * 8) /
+                   srtp_bits_per_second(10, &policy) / .01);
+        printf("G.729\t\t%d\t\t\t%e\n", 20,
+               (double)mips_value * (20 * 8) /
+                   srtp_bits_per_second(20, &policy) / .02);
+        printf("Wideband\t%d\t\t\t%e\n", 320,
+               (double)mips_value * (320 * 8) /
+                   srtp_bits_per_second(320, &policy) / .01);
+        printf("Wideband\t%d\t\t\t%e\n", 640,
+               (double)mips_value * (640 * 8) /
+                   srtp_bits_per_second(640, &policy) / .02);
+    }
+
+    status = srtp_shutdown();
+    if (status) {
+        printf("error: srtp shutdown failed with error code %d\n", status);
+        exit(1);
+    }
+
+    return 0;
+}
+
+/*
+ * srtp_create_test_packet(len, ssrc) returns a pointer to a
+ * (malloced) example RTP packet whose data field has the length given
+ * by pkt_octet_len and the SSRC value ssrc.  The total length of the
+ * packet is twelve octets longer, since the header is at the
+ * beginning.  There is room at the end of the packet for a trailer,
+ * and the four octets following the packet are filled with 0xff
+ * values to enable testing for overwrites.
+ *
+ * note that the location of the test packet can (and should) be
+ * deallocated with the free() call once it is no longer needed.
+ */
+
+srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len,
+                                    uint32_t ssrc,
+                                    int *pkt_len)
+{
+    int i;
+    uint8_t *buffer;
+    srtp_hdr_t *hdr;
+    int bytes_in_hdr = 12;
+
+    /* allocate memory for test packet */
+    hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
+                               SRTP_MAX_TRAILER_LEN + 4);
+    if (!hdr) {
+        return NULL;
+    }
+
+    hdr->version = 2;            /* RTP version two     */
+    hdr->p = 0;                  /* no padding needed   */
+    hdr->x = 0;                  /* no header extension */
+    hdr->cc = 0;                 /* no CSRCs            */
+    hdr->m = 0;                  /* marker bit          */
+    hdr->pt = 0xf;               /* payload type        */
+    hdr->seq = htons(0x1234);    /* sequence number     */
+    hdr->ts = htonl(0xdecafbad); /* timestamp           */
+    hdr->ssrc = htonl(ssrc);     /* synch. source       */
+
+    buffer = (uint8_t *)hdr;
+    buffer += bytes_in_hdr;
+
+    /* set RTP data to 0xab */
+    for (i = 0; i < pkt_octet_len; i++) {
+        *buffer++ = 0xab;
+    }
+
+    /* set post-data value to 0xffff to enable overrun checking */
+    for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
+        *buffer++ = 0xff;
+    }
+
+    *pkt_len = bytes_in_hdr + pkt_octet_len;
+
+    return hdr;
+}
+
+static srtp_hdr_t *srtp_create_test_packet_extended(int pkt_octet_len,
+                                                    uint32_t ssrc,
+                                                    uint16_t seq,
+                                                    uint32_t ts,
+                                                    int *pkt_len)
+{
+    srtp_hdr_t *hdr;
+
+    hdr = srtp_create_test_packet(pkt_octet_len, ssrc, pkt_len);
+    if (hdr == NULL)
+        return hdr;
+
+    hdr->seq = htons(seq);
+    hdr->ts = htonl(ts);
+    return hdr;
+}
+
+srtp_hdr_t *srtp_create_test_packet_ext_hdr(int pkt_octet_len,
+                                            uint32_t ssrc,
+                                            int *pkt_len)
+{
+    int i;
+    uint8_t *buffer;
+    srtp_hdr_t *hdr;
+    int bytes_in_hdr = 12;
+    uint8_t extension_header[12] = { /* one-byte header */
+                                     0xbe, 0xde,
+                                     /* size */
+                                     0x00, 0x02,
+                                     /* id 1, length 1 (i.e. 2 bytes) */
+                                     0x11,
+                                     /* payload */
+                                     0xca, 0xfe,
+                                     /* padding */
+                                     0x00,
+                                     /* id 2, length 0 (i.e. 1 byte) */
+                                     0x20,
+                                     /* payload */
+                                     0xba,
+                                     /* padding */
+                                     0x00, 0x00
+    };
+
+    /* allocate memory for test packet */
+    hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
+                               sizeof(extension_header) + SRTP_MAX_TRAILER_LEN +
+                               4);
+    if (!hdr)
+        return NULL;
+
+    hdr->version = 2;            /* RTP version two     */
+    hdr->p = 0;                  /* no padding needed   */
+    hdr->x = 1;                  /* no header extension */
+    hdr->cc = 0;                 /* no CSRCs            */
+    hdr->m = 0;                  /* marker bit          */
+    hdr->pt = 0xf;               /* payload type        */
+    hdr->seq = htons(0x1234);    /* sequence number     */
+    hdr->ts = htonl(0xdecafbad); /* timestamp           */
+    hdr->ssrc = htonl(ssrc);     /* synch. source       */
+
+    buffer = (uint8_t *)hdr;
+    buffer += bytes_in_hdr;
+
+    memcpy(buffer, extension_header, sizeof(extension_header));
+    buffer += sizeof(extension_header);
+
+    /* set RTP data to 0xab */
+    for (i = 0; i < pkt_octet_len; i++)
+        *buffer++ = 0xab;
+
+    /* set post-data value to 0xffff to enable overrun checking */
+    for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++)
+        *buffer++ = 0xff;
+
+    *pkt_len = bytes_in_hdr + sizeof(extension_header) + pkt_octet_len;
+
+    return hdr;
+}
+
+void srtp_do_timing(const srtp_policy_t *policy)
+{
+    int len;
+
+    /*
+     * note: the output of this function is formatted so that it
+     * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
+     * terminates a record
+     */
+
+    printf("# testing srtp throughput:\r\n");
+    printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
+
+    for (len = 16; len <= 2048; len *= 2) {
+        printf("%d\t\t\t%f\r\n", len,
+               srtp_bits_per_second(len, policy) / 1.0E6);
+    }
+
+    /* these extra linefeeds let gnuplot know that a dataset is done */
+    printf("\r\n\r\n");
+}
+
+void srtp_do_rejection_timing(const srtp_policy_t *policy)
+{
+    int len;
+
+    /*
+     * note: the output of this function is formatted so that it
+     * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
+     * terminates a record
+     */
+
+    printf("# testing srtp rejection throughput:\r\n");
+    printf("# mesg length (octets)\trejections per second\r\n");
+
+    for (len = 8; len <= 2048; len *= 2) {
+        printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
+    }
+
+    /* these extra linefeeds let gnuplot know that a dataset is done */
+    printf("\r\n\r\n");
+}
+
+#define MAX_MSG_LEN 1024
+
+double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy)
+{
+    srtp_t srtp;
+    srtp_hdr_t *mesg;
+    int i;
+    clock_t timer;
+    int num_trials = 100000;
+    int input_len, len;
+    uint32_t ssrc;
+    srtp_err_status_t status;
+
+    /*
+     * allocate and initialize an srtp session
+     */
+    status = srtp_create(&srtp, policy);
+    if (status) {
+        printf("error: srtp_create() failed with error code %d\n", status);
+        exit(1);
+    }
+
+    /*
+     * if the ssrc is unspecified, use a predetermined one
+     */
+    if (policy->ssrc.type != ssrc_specific) {
+        ssrc = 0xdeadbeef;
+    } else {
+        ssrc = policy->ssrc.value;
+    }
+
+    /*
+     * create a test packet
+     */
+    mesg = srtp_create_test_packet(msg_len_octets, ssrc, &input_len);
+    if (mesg == NULL) {
+        return 0.0; /* indicate failure by returning zero */
+    }
+    timer = clock();
+    for (i = 0; i < num_trials; i++) {
+        len = input_len;
+        /* srtp protect message */
+        status = srtp_protect(srtp, mesg, &len);
+        if (status) {
+            printf("error: srtp_protect() failed with error code %d\n", status);
+            exit(1);
+        }
+
+        /* increment message number */
+        {
+            /* hack sequence to avoid problems with macros for htons/ntohs on
+             * some systems */
+            short new_seq = ntohs(mesg->seq) + 1;
+            mesg->seq = htons(new_seq);
+        }
+    }
+    timer = clock() - timer;
+
+    free(mesg);
+
+    status = srtp_dealloc(srtp);
+    if (status) {
+        printf("error: srtp_dealloc() failed with error code %d\n", status);
+        exit(1);
+    }
+
+    return (double)(msg_len_octets)*8 * num_trials * CLOCKS_PER_SEC / timer;
+}
+
+double srtp_rejections_per_second(int msg_len_octets,
+                                  const srtp_policy_t *policy)
+{
+    srtp_ctx_t *srtp;
+    srtp_hdr_t *mesg;
+    int i;
+    int len;
+    clock_t timer;
+    int num_trials = 1000000;
+    uint32_t ssrc = policy->ssrc.value;
+    srtp_err_status_t status;
+
+    /*
+     * allocate and initialize an srtp session
+     */
+    status = srtp_create(&srtp, policy);
+    if (status) {
+        printf("error: srtp_create() failed with error code %d\n", status);
+        exit(1);
+    }
+
+    mesg = srtp_create_test_packet(msg_len_octets, ssrc, &len);
+    if (mesg == NULL) {
+        return 0.0; /* indicate failure by returning zero */
+    }
+    srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
+
+    timer = clock();
+    for (i = 0; i < num_trials; i++) {
+        len = msg_len_octets;
+        srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
+    }
+    timer = clock() - timer;
+
+    free(mesg);
+
+    status = srtp_dealloc(srtp);
+    if (status) {
+        printf("error: srtp_dealloc() failed with error code %d\n", status);
+        exit(1);
+    }
+
+    return (double)num_trials * CLOCKS_PER_SEC / timer;
+}
+
+void err_check(srtp_err_status_t s)
+{
+    if (s == srtp_err_status_ok) {
+        return;
+    } else {
+        fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
+    }
+    exit(1);
+}
+
+srtp_err_status_t srtp_test_call_protect(srtp_t srtp_sender,
+                                         srtp_hdr_t *hdr,
+                                         int *len,
+                                         int mki_index)
+{
+    if (mki_index == -1) {
+        return srtp_protect(srtp_sender, hdr, len);
+    } else {
+        return srtp_protect_mki(srtp_sender, hdr, len, 1, mki_index);
+    }
+}
+
+srtp_err_status_t srtp_test_call_protect_rtcp(srtp_t srtp_sender,
+                                              srtp_hdr_t *hdr,
+                                              int *len,
+                                              int mki_index)
+{
+    if (mki_index == -1) {
+        return srtp_protect_rtcp(srtp_sender, hdr, len);
+    } else {
+        return srtp_protect_rtcp_mki(srtp_sender, hdr, len, 1, mki_index);
+    }
+}
+
+srtp_err_status_t srtp_test_call_unprotect(srtp_t srtp_sender,
+                                           srtp_hdr_t *hdr,
+                                           int *len,
+                                           int use_mki)
+{
+    if (use_mki == -1) {
+        return srtp_unprotect(srtp_sender, hdr, len);
+    } else {
+        return srtp_unprotect_mki(srtp_sender, hdr, len, use_mki);
+    }
+}
+
+srtp_err_status_t srtp_test_call_unprotect_rtcp(srtp_t srtp_sender,
+                                                srtp_hdr_t *hdr,
+                                                int *len,
+                                                int use_mki)
+{
+    if (use_mki == -1) {
+        return srtp_unprotect_rtcp(srtp_sender, hdr, len);
+    } else {
+        return srtp_unprotect_rtcp_mki(srtp_sender, hdr, len, use_mki);
+    }
+}
+
+srtp_err_status_t srtp_test(const srtp_policy_t *policy,
+                            int extension_header,
+                            int mki_index)
+{
+    int i;
+    srtp_t srtp_sender;
+    srtp_t srtp_rcvr;
+    srtp_err_status_t status = srtp_err_status_ok;
+    srtp_hdr_t *hdr, *hdr2;
+    uint8_t hdr_enc[64];
+    uint8_t *pkt_end;
+    int msg_len_octets, msg_len_enc, msg_len;
+    int len, len2;
+    uint32_t tag_length;
+    uint32_t ssrc;
+    srtp_policy_t *rcvr_policy;
+    srtp_policy_t tmp_policy;
+    int header = 1;
+    int use_mki = 0;
+
+    if (mki_index >= 0)
+        use_mki = 1;
+
+    if (extension_header) {
+        memcpy(&tmp_policy, policy, sizeof(srtp_policy_t));
+        tmp_policy.enc_xtn_hdr = &header;
+        tmp_policy.enc_xtn_hdr_count = 1;
+        err_check(srtp_create(&srtp_sender, &tmp_policy));
+    } else {
+        err_check(srtp_create(&srtp_sender, policy));
+    }
+
+    /* print out policy */
+    err_check(srtp_session_print_policy(srtp_sender));
+
+    /*
+     * initialize data buffer, using the ssrc in the policy unless that
+     * value is a wildcard, in which case we'll just use an arbitrary
+     * one
+     */
+    if (policy->ssrc.type != ssrc_specific) {
+        ssrc = 0xdecafbad;
+    } else {
+        ssrc = policy->ssrc.value;
+    }
+    msg_len_octets = 28;
+    if (extension_header) {
+        hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len);
+        hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len2);
+    } else {
+        hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len);
+        hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2);
+    }
+
+    /* save original msg len */
+    msg_len = len;
+
+    if (hdr == NULL) {
+        free(hdr2);
+        return srtp_err_status_alloc_fail;
+    }
+    if (hdr2 == NULL) {
+        free(hdr);
+        return srtp_err_status_alloc_fail;
+    }
+
+    debug_print(mod_driver, "before protection:\n%s",
+                srtp_packet_to_string(hdr, len));
+
+#if PRINT_REFERENCE_PACKET
+    debug_print(mod_driver, "reference packet before protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+    err_check(srtp_test_call_protect(srtp_sender, hdr, &len, mki_index));
+
+    debug_print(mod_driver, "after protection:\n%s",
+                srtp_packet_to_string(hdr, len));
+#if PRINT_REFERENCE_PACKET
+    debug_print(mod_driver, "after protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+
+    /* save protected message and length */
+    memcpy(hdr_enc, hdr, len);
+    msg_len_enc = len;
+
+    /*
+     * check for overrun of the srtp_protect() function
+     *
+     * The packet is followed by a value of 0xfffff; if the value of the
+     * data following the packet is different, then we know that the
+     * protect function is overwriting the end of the packet.
+     */
+    srtp_get_protect_trailer_length(srtp_sender, use_mki, mki_index,
+                                    &tag_length);
+    pkt_end = (uint8_t *)hdr + msg_len + tag_length;
+    for (i = 0; i < 4; i++) {
+        if (pkt_end[i] != 0xff) {
+            fprintf(stdout, "overwrite in srtp_protect() function "
+                            "(expected %x, found %x in trailing octet %d)\n",
+                    0xff, ((uint8_t *)hdr)[i], i);
+            free(hdr);
+            free(hdr2);
+            return srtp_err_status_algo_fail;
+        }
+    }
+
+    /*
+     * if the policy includes confidentiality, check that ciphertext is
+     * different than plaintext
+     *
+     * Note that this check will give false negatives, with some small
+     * probability, especially if the packets are short.  For that
+     * reason, we skip this check if the plaintext is less than four
+     * octets long.
+     */
+    if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
+        printf("testing that ciphertext is distinct from plaintext...");
+        status = srtp_err_status_algo_fail;
+        for (i = 12; i < msg_len_octets + 12; i++) {
+            if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+                status = srtp_err_status_ok;
+            }
+        }
+        if (status) {
+            printf("failed\n");
+            free(hdr);
+            free(hdr2);
+            return status;
+        }
+        printf("passed\n");
+    }
+
+    /*
+     * if the policy uses a 'wildcard' ssrc, then we need to make a copy
+     * of the policy that changes the direction to inbound
+     *
+     * we always copy the policy into the rcvr_policy, since otherwise
+     * the compiler would fret about the constness of the policy
+     */
+    rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
+    if (rcvr_policy == NULL) {
+        free(hdr);
+        free(hdr2);
+        return srtp_err_status_alloc_fail;
+    }
+    if (extension_header) {
+        memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t));
+        if (tmp_policy.ssrc.type == ssrc_any_outbound) {
+            rcvr_policy->ssrc.type = ssrc_any_inbound;
+        }
+    } else {
+        memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
+        if (policy->ssrc.type == ssrc_any_outbound) {
+            rcvr_policy->ssrc.type = ssrc_any_inbound;
+        }
+    }
+
+    err_check(srtp_create(&srtp_rcvr, rcvr_policy));
+
+    err_check(srtp_test_call_unprotect(srtp_rcvr, hdr, &len, use_mki));
+
+    debug_print(mod_driver, "after unprotection:\n%s",
+                srtp_packet_to_string(hdr, len));
+
+    /* verify that the unprotected packet matches the origial one */
+    for (i = 0; i < len; i++) {
+        if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+            fprintf(stdout, "mismatch at octet %d\n", i);
+            status = srtp_err_status_algo_fail;
+        }
+    }
+    if (status) {
+        free(hdr);
+        free(hdr2);
+        free(rcvr_policy);
+        return status;
+    }
+
+    /*
+     * if the policy includes authentication, then test for false positives
+     */
+    if (policy->rtp.sec_serv & sec_serv_auth) {
+        char *data = ((char *)hdr) + (extension_header ? 24 : 12);
+
+        printf("testing for false positives in replay check...");
+
+        /* unprotect a second time - should fail with a replay error */
+        status =
+            srtp_test_call_unprotect(srtp_rcvr, hdr, &msg_len_enc, use_mki);
+        if (status != srtp_err_status_replay_fail) {
+            printf("failed with error code %d\n", status);
+            free(hdr);
+            free(hdr2);
+            free(rcvr_policy);
+            return status;
+        } else {
+            printf("passed\n");
+        }
+
+        printf("testing for false positives in auth check...");
+
+        /* increment sequence number in header */
+        hdr->seq++;
+
+        /* apply protection */
+        err_check(srtp_test_call_protect(srtp_sender, hdr, &len, mki_index));
+
+        /* flip bits in packet */
+        data[0] ^= 0xff;
+
+        /* unprotect, and check for authentication failure */
+        status = srtp_test_call_unprotect(srtp_rcvr, hdr, &len, use_mki);
+        if (status != srtp_err_status_auth_fail) {
+            printf("failed\n");
+            free(hdr);
+            free(hdr2);
+            free(rcvr_policy);
+            return status;
+        } else {
+            printf("passed\n");
+        }
+    }
+
+    err_check(srtp_dealloc(srtp_sender));
+    err_check(srtp_dealloc(srtp_rcvr));
+
+    free(hdr);
+    free(hdr2);
+    free(rcvr_policy);
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index)
+{
+    int i;
+    srtp_t srtcp_sender;
+    srtp_t srtcp_rcvr;
+    srtp_err_status_t status = srtp_err_status_ok;
+    srtp_hdr_t *hdr, *hdr2;
+    uint8_t hdr_enc[64];
+    uint8_t *pkt_end;
+    int msg_len_octets, msg_len_enc, msg_len;
+    int len, len2;
+    uint32_t tag_length;
+    uint32_t ssrc;
+    srtp_policy_t *rcvr_policy;
+    int use_mki = 0;
+
+    if (mki_index >= 0)
+        use_mki = 1;
+
+    err_check(srtp_create(&srtcp_sender, policy));
+
+    /* print out policy */
+    err_check(srtp_session_print_policy(srtcp_sender));
+
+    /*
+     * initialize data buffer, using the ssrc in the policy unless that
+     * value is a wildcard, in which case we'll just use an arbitrary
+     * one
+     */
+    if (policy->ssrc.type != ssrc_specific) {
+        ssrc = 0xdecafbad;
+    } else {
+        ssrc = policy->ssrc.value;
+    }
+    msg_len_octets = 28;
+    hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len);
+    /* save message len */
+    msg_len = len;
+
+    if (hdr == NULL) {
+        return srtp_err_status_alloc_fail;
+    }
+    hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2);
+    if (hdr2 == NULL) {
+        free(hdr);
+        return srtp_err_status_alloc_fail;
+    }
+
+    debug_print(mod_driver, "before protection:\n%s",
+                srtp_packet_to_string(hdr, len));
+
+#if PRINT_REFERENCE_PACKET
+    debug_print(mod_driver, "reference packet before protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+    err_check(srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index));
+
+    debug_print(mod_driver, "after protection:\n%s",
+                srtp_packet_to_string(hdr, len));
+#if PRINT_REFERENCE_PACKET
+    debug_print(mod_driver, "after protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
+#endif
+
+    /* save protected message and length */
+    memcpy(hdr_enc, hdr, len);
+    msg_len_enc = len;
+
+    /*
+     * check for overrun of the srtp_protect() function
+     *
+     * The packet is followed by a value of 0xfffff; if the value of the
+     * data following the packet is different, then we know that the
+     * protect function is overwriting the end of the packet.
+     */
+    srtp_get_protect_rtcp_trailer_length(srtcp_sender, use_mki, mki_index,
+                                         &tag_length);
+    pkt_end = (uint8_t *)hdr + msg_len + tag_length;
+    for (i = 0; i < 4; i++) {
+        if (pkt_end[i] != 0xff) {
+            fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
+                            "(expected %x, found %x in trailing octet %d)\n",
+                    0xff, ((uint8_t *)hdr)[i], i);
+            free(hdr);
+            free(hdr2);
+            return srtp_err_status_algo_fail;
+        }
+    }
+
+    /*
+     * if the policy includes confidentiality, check that ciphertext is
+     * different than plaintext
+     *
+     * Note that this check will give false negatives, with some small
+     * probability, especially if the packets are short.  For that
+     * reason, we skip this check if the plaintext is less than four
+     * octets long.
+     */
+    if ((policy->rtcp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
+        printf("testing that ciphertext is distinct from plaintext...");
+        status = srtp_err_status_algo_fail;
+        for (i = 12; i < msg_len_octets + 12; i++) {
+            if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+                status = srtp_err_status_ok;
+            }
+        }
+        if (status) {
+            printf("failed\n");
+            free(hdr);
+            free(hdr2);
+            return status;
+        }
+        printf("passed\n");
+    }
+
+    /*
+     * if the policy uses a 'wildcard' ssrc, then we need to make a copy
+     * of the policy that changes the direction to inbound
+     *
+     * we always copy the policy into the rcvr_policy, since otherwise
+     * the compiler would fret about the constness of the policy
+     */
+    rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
+    if (rcvr_policy == NULL) {
+        return srtp_err_status_alloc_fail;
+    }
+    memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
+    if (policy->ssrc.type == ssrc_any_outbound) {
+        rcvr_policy->ssrc.type = ssrc_any_inbound;
+    }
+
+    err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
+
+    err_check(srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki));
+
+    debug_print(mod_driver, "after unprotection:\n%s",
+                srtp_packet_to_string(hdr, len));
+
+    /* verify that the unprotected packet matches the origial one */
+    for (i = 0; i < len; i++) {
+        if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
+            fprintf(stdout, "mismatch at octet %d\n", i);
+            status = srtp_err_status_algo_fail;
+        }
+    }
+    if (status) {
+        free(hdr);
+        free(hdr2);
+        free(rcvr_policy);
+        return status;
+    }
+
+    /*
+     * if the policy includes authentication, then test for false positives
+     */
+    if (policy->rtp.sec_serv & sec_serv_auth) {
+        char *data = ((char *)hdr) + 12;
+
+        printf("testing for false positives in replay check...");
+
+        /* unprotect a second time - should fail with a replay error */
+        status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &msg_len_enc,
+                                               use_mki);
+        if (status != srtp_err_status_replay_fail) {
+            printf("failed with error code %d\n", status);
+            free(hdr);
+            free(hdr2);
+            free(rcvr_policy);
+            return status;
+        } else {
+            printf("passed\n");
+        }
+
+        printf("testing for false positives in auth check...");
+
+        /* increment sequence number in header */
+        hdr->seq++;
+
+        /* apply protection */
+        err_check(
+            srtp_test_call_protect_rtcp(srtcp_sender, hdr, &len, mki_index));
+
+        /* flip bits in packet */
+        data[0] ^= 0xff;
+
+        /* unprotect, and check for authentication failure */
+        status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &len, use_mki);
+        if (status != srtp_err_status_auth_fail) {
+            printf("failed\n");
+            free(hdr);
+            free(hdr2);
+            free(rcvr_policy);
+            return status;
+        } else {
+            printf("passed\n");
+        }
+    }
+
+    err_check(srtp_dealloc(srtcp_sender));
+    err_check(srtp_dealloc(srtcp_rcvr));
+
+    free(hdr);
+    free(hdr2);
+    free(rcvr_policy);
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_session_print_policy(srtp_t srtp)
+{
+    char *serv_descr[4] = { "none", "confidentiality", "authentication",
+                            "confidentiality and authentication" };
+    char *direction[3] = { "unknown", "outbound", "inbound" };
+    srtp_stream_t stream;
+    srtp_session_keys_t *session_keys = NULL;
+
+    /* sanity checking */
+    if (srtp == NULL) {
+        return srtp_err_status_fail;
+    }
+
+    /* if there's a template stream, print it out */
+    if (srtp->stream_template != NULL) {
+        stream = srtp->stream_template;
+        session_keys = &stream->session_keys[0];
+        printf("# SSRC:          any %s\r\n"
+               "# rtp cipher:    %s\r\n"
+               "# rtp auth:      %s\r\n"
+               "# rtp services:  %s\r\n"
+               "# rtcp cipher:   %s\r\n"
+               "# rtcp auth:     %s\r\n"
+               "# rtcp services: %s\r\n"
+               "# window size:   %lu\r\n"
+               "# tx rtx allowed:%s\r\n",
+               direction[stream->direction],
+               session_keys->rtp_cipher->type->description,
+               session_keys->rtp_auth->type->description,
+               serv_descr[stream->rtp_services],
+               session_keys->rtcp_cipher->type->description,
+               session_keys->rtcp_auth->type->description,
+               serv_descr[stream->rtcp_services],
+               srtp_rdbx_get_window_size(&stream->rtp_rdbx),
+               stream->allow_repeat_tx ? "true" : "false");
+
+        printf("# Encrypted extension headers: ");
+        if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
+            int *enc_xtn_hdr = stream->enc_xtn_hdr;
+            int count = stream->enc_xtn_hdr_count;
+            while (count > 0) {
+                printf("%d ", *enc_xtn_hdr);
+                enc_xtn_hdr++;
+                count--;
+            }
+            printf("\n");
+        } else {
+            printf("none\n");
+        }
+    }
+
+    /* loop over streams in session, printing the policy of each */
+    stream = srtp->stream_list;
+    while (stream != NULL) {
+        if (stream->rtp_services > sec_serv_conf_and_auth) {
+            return srtp_err_status_bad_param;
+        }
+        session_keys = &stream->session_keys[0];
+
+        printf("# SSRC:          0x%08x\r\n"
+               "# rtp cipher:    %s\r\n"
+               "# rtp auth:      %s\r\n"
+               "# rtp services:  %s\r\n"
+               "# rtcp cipher:   %s\r\n"
+               "# rtcp auth:     %s\r\n"
+               "# rtcp services: %s\r\n"
+               "# window size:   %lu\r\n"
+               "# tx rtx allowed:%s\r\n",
+               stream->ssrc, session_keys->rtp_cipher->type->description,
+               session_keys->rtp_auth->type->description,
+               serv_descr[stream->rtp_services],
+               session_keys->rtcp_cipher->type->description,
+               session_keys->rtcp_auth->type->description,
+               serv_descr[stream->rtcp_services],
+               srtp_rdbx_get_window_size(&stream->rtp_rdbx),
+               stream->allow_repeat_tx ? "true" : "false");
+
+        printf("# Encrypted extension headers: ");
+        if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) {
+            int *enc_xtn_hdr = stream->enc_xtn_hdr;
+            int count = stream->enc_xtn_hdr_count;
+            while (count > 0) {
+                printf("%d ", *enc_xtn_hdr);
+                enc_xtn_hdr++;
+                count--;
+            }
+            printf("\n");
+        } else {
+            printf("none\n");
+        }
+
+        /* advance to next stream in the list */
+        stream = stream->next;
+    }
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_print_policy(const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+    srtp_t session;
+
+    status = srtp_create(&session, policy);
+    if (status) {
+        return status;
+    }
+    status = srtp_session_print_policy(session);
+    if (status) {
+        return status;
+    }
+    status = srtp_dealloc(session);
+    if (status) {
+        return status;
+    }
+    return srtp_err_status_ok;
+}
+
+/*
+ * srtp_print_packet(...) is for debugging only
+ * it prints an RTP packet to the stdout
+ *
+ * note that this function is *not* threadsafe
+ */
+
+#include <stdio.h>
+
+#define MTU 2048
+
+char packet_string[MTU];
+
+char *srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len)
+{
+    int octets_in_rtp_header = 12;
+    uint8_t *data = ((uint8_t *)hdr) + octets_in_rtp_header;
+    int hex_len = pkt_octet_len - octets_in_rtp_header;
+
+    /* sanity checking */
+    if ((hdr == NULL) || (pkt_octet_len > MTU)) {
+        return NULL;
+    }
+
+    /* write packet into string */
+    sprintf(packet_string, "(s)rtp packet: {\n"
+                           "   version:\t%d\n"
+                           "   p:\t\t%d\n"
+                           "   x:\t\t%d\n"
+                           "   cc:\t\t%d\n"
+                           "   m:\t\t%d\n"
+                           "   pt:\t\t%x\n"
+                           "   seq:\t\t%x\n"
+                           "   ts:\t\t%x\n"
+                           "   ssrc:\t%x\n"
+                           "   data:\t%s\n"
+                           "} (%d octets in total)\n",
+            hdr->version, hdr->p, hdr->x, hdr->cc, hdr->m, hdr->pt, hdr->seq,
+            hdr->ts, hdr->ssrc, octet_string_hex_string(data, hex_len),
+            pkt_octet_len);
+
+    return packet_string;
+}
+
+/*
+ * mips_estimate() is a simple function to estimate the number of
+ * instructions per second that the host can perform.  note that this
+ * function can be grossly wrong; you may want to have a manual sanity
+ * check of its output!
+ *
+ * the 'ignore' pointer is there to convince the compiler to not just
+ * optimize away the function
+ */
+
+double mips_estimate(int num_trials, int *ignore)
+{
+    clock_t t;
+    volatile int i, sum;
+
+    sum = 0;
+    t = clock();
+    for (i = 0; i < num_trials; i++) {
+        sum += i;
+    }
+    t = clock() - t;
+
+    /*   printf("%d\n", sum); */
+    *ignore = sum;
+
+    return (double)num_trials * CLOCKS_PER_SEC / t;
+}
+
+/*
+ * srtp_validate() verifies the correctness of libsrtp by comparing
+ * some computed packets against some pre-computed reference values.
+ * These packets were made with the default SRTP policy.
+ */
+
+srtp_err_status_t srtp_validate()
+{
+    // clang-format off
+    uint8_t srtp_plaintext_ref[28] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab
+    };
+    uint8_t srtp_plaintext[38] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtp_ciphertext[38] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
+        0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
+        0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
+        0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
+    };
+    uint8_t rtcp_plaintext_ref[24] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+    };
+    uint8_t rtcp_plaintext[38] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtcp_ciphertext[38] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0x71, 0x28, 0x03, 0x5b, 0xe4, 0x87, 0xb9, 0xbd,
+        0xbe, 0xf8, 0x90, 0x41, 0xf9, 0x77, 0xa5, 0xa8,
+        0x80, 0x00, 0x00, 0x01, 0x99, 0x3e, 0x08, 0xcd,
+        0x54, 0xd6, 0xc1, 0x23, 0x07, 0x98
+    };
+    // clang-format on
+
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * protect plaintext, then compare with ciphertext
+     */
+    len = 28;
+    status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+    if (status || (len != 38)) {
+        return srtp_err_status_fail;
+    }
+
+    debug_print(mod_driver, "ciphertext:\n  %s",
+                octet_string_hex_string(srtp_plaintext, len));
+    debug_print(mod_driver, "ciphertext reference:\n  %s",
+                octet_string_hex_string(srtp_ciphertext, len));
+
+    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * protect plaintext rtcp, then compare with srtcp ciphertext
+     */
+    len = 24;
+    status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
+    if (status || (len != 38)) {
+        return srtp_err_status_fail;
+    }
+
+    debug_print(mod_driver, "srtcp ciphertext:\n  %s",
+                octet_string_hex_string(rtcp_plaintext, len));
+    debug_print(mod_driver, "srtcp ciphertext reference:\n  %s",
+                octet_string_hex_string(srtcp_ciphertext, len));
+
+    if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+    if (status || (len != 28)) {
+        return status;
+    }
+
+    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * unprotect srtcp ciphertext, then compare with rtcp plaintext
+     */
+    len = 38;
+    status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
+    if (status || (len != 24)) {
+        return status;
+    }
+
+    if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(srtp_snd);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(srtp_recv);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+#ifdef OPENSSL
+/*
+ * srtp_validate_gcm() verifies the correctness of libsrtp by comparing
+ * an computed packet against the known ciphertext for the plaintext.
+ */
+srtp_err_status_t srtp_validate_gcm()
+{
+    // clang-format off
+    unsigned char test_key_gcm[28] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+        0xa8, 0xa9, 0xaa, 0xab
+    };
+    uint8_t rtp_plaintext_ref[28] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab
+    };
+    uint8_t rtp_plaintext[44] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtp_ciphertext[44] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xc5, 0x00, 0x2e, 0xde,
+        0x04, 0xcf, 0xdd, 0x2e, 0xb9, 0x11, 0x59, 0xe0,
+        0x88, 0x0a, 0xa0, 0x6e, 0xd2, 0x97, 0x68, 0x26,
+        0xf7, 0x96, 0xb2, 0x01, 0xdf, 0x31, 0x31, 0xa1,
+        0x27, 0xe8, 0xa3, 0x92
+    };
+    uint8_t rtcp_plaintext_ref[24] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+    };
+    uint8_t rtcp_plaintext[44] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtcp_ciphertext[44] = {
+        0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
+        0xc9, 0x8b, 0x8b, 0x5d, 0xf0, 0x39, 0x2a, 0x55,
+        0x85, 0x2b, 0x6c, 0x21, 0xac, 0x8e, 0x70, 0x25,
+        0xc5, 0x2c, 0x6f, 0xbe, 0xa2, 0xb3, 0xb4, 0x46,
+        0xea, 0x31, 0x12, 0x3b, 0xa8, 0x8c, 0xe6, 0x1e,
+        0x80, 0x00, 0x00, 0x01
+    };
+    // clang-format on
+
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key_gcm;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * protect plaintext rtp, then compare with srtp ciphertext
+     */
+    len = 28;
+    status = srtp_protect(srtp_snd, rtp_plaintext, &len);
+    if (status || (len != 44)) {
+        return srtp_err_status_fail;
+    }
+
+    debug_print(mod_driver, "srtp ciphertext:\n  %s",
+                octet_string_hex_string(rtp_plaintext, len));
+    debug_print(mod_driver, "srtp ciphertext reference:\n  %s",
+                octet_string_hex_string(srtp_ciphertext, len));
+
+    if (octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * protect plaintext rtcp, then compare with srtcp ciphertext
+     */
+    len = 24;
+    status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
+    if (status || (len != 44)) {
+        return srtp_err_status_fail;
+    }
+
+    debug_print(mod_driver, "srtcp ciphertext:\n  %s",
+                octet_string_hex_string(rtcp_plaintext, len));
+    debug_print(mod_driver, "srtcp ciphertext reference:\n  %s",
+                octet_string_hex_string(srtcp_ciphertext, len));
+
+    if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * unprotect srtp ciphertext, then compare with rtp plaintext
+     */
+    len = 44;
+    status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+    if (status || (len != 28)) {
+        return status;
+    }
+
+    if (octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * unprotect srtcp ciphertext, then compare with rtcp plaintext
+     */
+    len = 44;
+    status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
+    if (status || (len != 24)) {
+        return status;
+    }
+
+    if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(srtp_snd);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(srtp_recv);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+#endif
+
+/*
+ * Test vectors taken from RFC 6904, Appendix A
+ */
+srtp_err_status_t srtp_validate_encrypted_extensions_headers()
+{
+    // clang-format off
+    unsigned char test_key_ext_headers[30] = {
+        0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+        0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+        0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+        0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+    };
+    uint8_t srtp_plaintext_ref[56] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
+        0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
+        0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
+    };
+    uint8_t srtp_plaintext[66] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
+        0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
+        0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00
+    };
+    uint8_t srtp_ciphertext[66] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x58, 0x8A, 0x92, 0x70, 0xF4, 0xE1, 0x5E,
+        0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x95, 0x46,
+        0xA9, 0x94, 0xF0, 0xBC, 0x54, 0x78, 0x97, 0x00,
+        0x4e, 0x55, 0xdc, 0x4c, 0xe7, 0x99, 0x78, 0xd8,
+        0x8c, 0xa4, 0xd2, 0x15, 0x94, 0x9d, 0x24, 0x02,
+        0x5a, 0x46, 0xb3, 0xca, 0x35, 0xc5, 0x35, 0xa8,
+        0x91, 0xc7
+    };
+    // clang-format on
+
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+    int headers[3] = { 1, 3, 4 };
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key_ext_headers;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.enc_xtn_hdr = headers;
+    policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status)
+        return status;
+
+    /*
+     * protect plaintext, then compare with ciphertext
+     */
+    len = sizeof(srtp_plaintext_ref);
+    status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+    if (status || (len != sizeof(srtp_plaintext)))
+        return srtp_err_status_fail;
+
+    debug_print(mod_driver, "ciphertext:\n  %s",
+                srtp_octet_string_hex_string(srtp_plaintext, len));
+    debug_print(mod_driver, "ciphertext reference:\n  %s",
+                srtp_octet_string_hex_string(srtp_ciphertext, len));
+
+    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+        return srtp_err_status_fail;
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status)
+        return status;
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+    if (status) {
+        return status;
+    } else if (len != sizeof(srtp_plaintext_ref)) {
+        return srtp_err_status_fail;
+    }
+
+    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+        return srtp_err_status_fail;
+
+    status = srtp_dealloc(srtp_snd);
+    if (status)
+        return status;
+
+    status = srtp_dealloc(srtp_recv);
+    if (status)
+        return status;
+
+    return srtp_err_status_ok;
+}
+
+#ifdef OPENSSL
+
+/*
+ * Headers of test vectors taken from RFC 6904, Appendix A
+ */
+srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm()
+{
+    // clang-format off
+    unsigned char test_key_ext_headers[30] = {
+        0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+        0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+        0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+        0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+    };
+    uint8_t srtp_plaintext_ref[56] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
+        0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
+        0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab
+    };
+    uint8_t srtp_plaintext[64] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x41, 0x42, 0x73, 0xA4, 0x75, 0x26, 0x27,
+        0x48, 0x22, 0x00, 0x00, 0xC8, 0x30, 0x8E, 0x46,
+        0x55, 0x99, 0x63, 0x86, 0xB3, 0x95, 0xFB, 0x00,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtp_ciphertext[64] = {
+        0x90, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xBE, 0xDE, 0x00, 0x06,
+        0x17, 0x12, 0xe0, 0x20, 0x5b, 0xfa, 0x94, 0x9b,
+        0x1C, 0x22, 0x00, 0x00, 0xC8, 0x30, 0xbb, 0x46,
+        0x73, 0x27, 0x78, 0xd9, 0x92, 0x9a, 0xab, 0x00,
+        0x0e, 0xca, 0x0c, 0xf9, 0x5e, 0xe9, 0x55, 0xb2,
+        0x6c, 0xd3, 0xd2, 0x88, 0xb4, 0x9f, 0x6c, 0xa9,
+        0xf4, 0xb1, 0xb7, 0x59, 0x71, 0x9e, 0xb5, 0xbc
+    };
+    // clang-format on
+
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+    int headers[3] = { 1, 3, 4 };
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key_ext_headers;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.enc_xtn_hdr = headers;
+    policy.enc_xtn_hdr_count = sizeof(headers) / sizeof(headers[0]);
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status)
+        return status;
+
+    /*
+     * protect plaintext, then compare with ciphertext
+     */
+    len = sizeof(srtp_plaintext_ref);
+    status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+    if (status || (len != sizeof(srtp_plaintext)))
+        return srtp_err_status_fail;
+
+    debug_print(mod_driver, "ciphertext:\n  %s",
+                srtp_octet_string_hex_string(srtp_plaintext, len));
+    debug_print(mod_driver, "ciphertext reference:\n  %s",
+                srtp_octet_string_hex_string(srtp_ciphertext, len));
+
+    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
+        return srtp_err_status_fail;
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status)
+        return status;
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+    if (status) {
+        return status;
+    } else if (len != sizeof(srtp_plaintext_ref)) {
+        return srtp_err_status_fail;
+    }
+
+    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
+        return srtp_err_status_fail;
+
+    status = srtp_dealloc(srtp_snd);
+    if (status)
+        return status;
+
+    status = srtp_dealloc(srtp_recv);
+    if (status)
+        return status;
+
+    return srtp_err_status_ok;
+}
+#endif
+
+/*
+ * srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
+ * some computed packets against some pre-computed reference values.
+ * These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
+ */
+
+srtp_err_status_t srtp_validate_aes_256()
+{
+    // clang-format off
+    unsigned char aes_256_test_key[46] = {
+        0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
+        0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
+        0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
+        0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
+
+        0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
+        0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
+    };
+    uint8_t srtp_plaintext_ref[28] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab
+    };
+    uint8_t srtp_plaintext[38] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+        0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    uint8_t srtp_ciphertext[38] = {
+        0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
+        0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
+        0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
+        0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
+        0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
+    };
+    // clang-format on
+
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
+    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = aes_256_test_key;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * protect plaintext, then compare with ciphertext
+     */
+    len = 28;
+    status = srtp_protect(srtp_snd, srtp_plaintext, &len);
+    if (status || (len != 38)) {
+        return srtp_err_status_fail;
+    }
+
+    debug_print(mod_driver, "ciphertext:\n  %s",
+                octet_string_hex_string(srtp_plaintext, len));
+    debug_print(mod_driver, "ciphertext reference:\n  %s",
+                octet_string_hex_string(srtp_ciphertext, len));
+
+    if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
+    if (status || (len != 28)) {
+        return status;
+    }
+
+    if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(srtp_snd);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(srtp_recv);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list)
+{
+    extern const srtp_policy_t *policy_array[];
+    srtp_policy_t *p, *tmp;
+    int i = 0;
+    uint32_t ssrc = 0;
+
+    /* sanity checking */
+    if ((list == NULL) || (policy_array[0] == NULL)) {
+        return srtp_err_status_bad_param;
+    }
+
+    /*
+     * loop over policy list, mallocing a new list and copying values
+     * into it (and incrementing the SSRC value as we go along)
+     */
+    tmp = NULL;
+    while (policy_array[i] != NULL) {
+        p = (srtp_policy_t *)malloc(sizeof(srtp_policy_t));
+        if (p == NULL) {
+            return srtp_err_status_bad_param;
+        }
+        memcpy(p, policy_array[i], sizeof(srtp_policy_t));
+        p->ssrc.type = ssrc_specific;
+        p->ssrc.value = ssrc++;
+        p->next = tmp;
+        tmp = p;
+        i++;
+    }
+    *list = p;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list)
+{
+    srtp_policy_t *p, *next;
+
+    for (p = list; p != NULL; p = next) {
+        next = p->next;
+        free(p);
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_empty_payload()
+{
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+    srtp_hdr_t *mesg;
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
+
+    mesg = srtp_create_test_packet(0, policy.ssrc.value, &len);
+    if (mesg == NULL) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_protect(srtp_snd, mesg, &len);
+    if (status) {
+        return status;
+    } else if (len != 12 + 10) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, mesg, &len);
+    if (status) {
+        return status;
+    } else if (len != 12) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(srtp_snd);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(srtp_recv);
+    if (status) {
+        return status;
+    }
+
+    free(mesg);
+
+    return srtp_err_status_ok;
+}
+
+#ifdef OPENSSL
+srtp_err_status_t srtp_test_empty_payload_gcm()
+{
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+    srtp_hdr_t *mesg;
+
+    /*
+     * create a session with a single stream using the default srtp
+     * policy and with the SSRC value 0xcafebabe
+     */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
+    srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
+
+    mesg = srtp_create_test_packet(0, policy.ssrc.value, &len);
+    if (mesg == NULL) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_protect(srtp_snd, mesg, &len);
+    if (status) {
+        return status;
+    } else if (len != 12 + 8) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * create a receiver session context comparable to the one created
+     * above - we need to do this so that the replay checking doesn't
+     * complain
+     */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * unprotect ciphertext, then compare with plaintext
+     */
+    status = srtp_unprotect(srtp_recv, mesg, &len);
+    if (status) {
+        return status;
+    } else if (len != 12) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(srtp_snd);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(srtp_recv);
+    if (status) {
+        return status;
+    }
+
+    free(mesg);
+
+    return srtp_err_status_ok;
+}
+#endif // OPENSSL
+
+srtp_err_status_t srtp_test_remove_stream()
+{
+    srtp_err_status_t status;
+    srtp_policy_t *policy_list, policy;
+    srtp_t session;
+    srtp_stream_t stream;
+
+    /*
+     * srtp_get_stream() is a libSRTP internal function that we declare
+     * here so that we can use it to verify the correct operation of the
+     * library
+     */
+    extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
+
+    status = srtp_create_big_policy(&policy_list);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_create(&session, policy_list);
+    if (status) {
+        return status;
+    }
+
+    /*
+     * check for false positives by trying to remove a stream that's not
+     * in the session
+     */
+    status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
+    if (status != srtp_err_status_no_ctx) {
+        return srtp_err_status_fail;
+    }
+
+    /*
+     * check for false negatives by removing stream 0x1, then
+     * searching for streams 0x0 and 0x2
+     */
+    status = srtp_remove_stream(session, htonl(0x1));
+    if (status != srtp_err_status_ok) {
+        return srtp_err_status_fail;
+    }
+    stream = srtp_get_stream(session, htonl(0x0));
+    if (stream == NULL) {
+        return srtp_err_status_fail;
+    }
+    stream = srtp_get_stream(session, htonl(0x2));
+    if (stream == NULL) {
+        return srtp_err_status_fail;
+    }
+
+    status = srtp_dealloc(session);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    status = srtp_dealloc_big_policy(policy_list);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    /* Now test adding and removing a single stream */
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key;
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+
+    status = srtp_create(&session, NULL);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    status = srtp_add_stream(session, &policy);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    status = srtp_remove_stream(session, htonl(0xcafebabe));
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    status = srtp_dealloc(session);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+// clang-format off
+unsigned char test_alt_key[46] = {
+  0xe5, 0x19, 0x6f, 0x01, 0x5e, 0xf1, 0x9b, 0xe1,
+  0xd7, 0x47, 0xa7, 0x27, 0x07, 0xd7, 0x47, 0x33,
+  0x01, 0xc2, 0x35, 0x4d, 0x59, 0x6a, 0xf7, 0x84,
+  0x96, 0x98, 0xeb, 0xaa, 0xac, 0xf6, 0xa1, 0x45,
+  0xc7, 0x15, 0xe2, 0xea, 0xfe, 0x55, 0x67, 0x96,
+  0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+};
+// clang-format on
+
+/*
+ * srtp_test_update() verifies updating/rekeying exsisting streams.
+ * As stated in https://tools.ietf.org/html/rfc3711#section-3.3.1
+ * the value of the ROC must not be reset after a rekey, this test
+ * atempts to prove that srtp_update does not reset the ROC.
+ */
+
+srtp_err_status_t srtp_test_update()
+{
+    srtp_err_status_t status;
+    uint32_t ssrc = 0x12121212;
+    int msg_len_octets = 32;
+    int protected_msg_len_octets;
+    srtp_hdr_t *msg;
+    srtp_t srtp_snd, srtp_recv;
+    srtp_policy_t policy;
+
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+    policy.ssrc.type = ssrc_any_outbound;
+    policy.key = test_key;
+
+    /* create a send and recive ctx with defualt profile and test_key */
+    status = srtp_create(&srtp_recv, &policy);
+    if (status)
+        return status;
+
+    policy.ssrc.type = ssrc_any_inbound;
+    status = srtp_create(&srtp_snd, &policy);
+    if (status)
+        return status;
+
+    /* protect and unprotect two msg's that will cause the ROC to be equal to 1
+     */
+    msg = srtp_create_test_packet(msg_len_octets, ssrc,
+                                  &protected_msg_len_octets);
+    if (msg == NULL)
+        return srtp_err_status_alloc_fail;
+    msg->seq = htons(65535);
+
+    status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
+    if (status)
+        return srtp_err_status_fail;
+
+    status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
+    if (status)
+        return status;
+
+    free(msg);
+
+    msg = srtp_create_test_packet(msg_len_octets, ssrc,
+                                  &protected_msg_len_octets);
+    if (msg == NULL)
+        return srtp_err_status_alloc_fail;
+    msg->seq = htons(1);
+
+    status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
+    if (status)
+        return srtp_err_status_fail;
+
+    status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
+    if (status)
+        return status;
+
+    free(msg);
+
+    /* update send ctx with same test_key t verify update works*/
+    policy.ssrc.type = ssrc_any_outbound;
+    policy.key = test_key;
+    status = srtp_update(srtp_snd, &policy);
+    if (status)
+        return status;
+
+    msg = srtp_create_test_packet(msg_len_octets, ssrc,
+                                  &protected_msg_len_octets);
+    if (msg == NULL)
+        return srtp_err_status_alloc_fail;
+    msg->seq = htons(2);
+
+    status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
+    if (status)
+        return srtp_err_status_fail;
+
+    status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
+    if (status)
+        return status;
+
+    free(msg);
+
+    /* update send ctx to use test_alt_key */
+    policy.ssrc.type = ssrc_any_outbound;
+    policy.key = test_alt_key;
+    status = srtp_update(srtp_snd, &policy);
+    if (status)
+        return status;
+
+    /* create and protect msg with new key and ROC still equal to 1 */
+    msg = srtp_create_test_packet(msg_len_octets, ssrc,
+                                  &protected_msg_len_octets);
+    if (msg == NULL)
+        return srtp_err_status_alloc_fail;
+    msg->seq = htons(3);
+
+    status = srtp_protect(srtp_snd, msg, &protected_msg_len_octets);
+    if (status)
+        return srtp_err_status_fail;
+
+    /* verify that recive ctx will fail to unprotect as it still uses test_key
+     */
+    status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
+    if (status == srtp_err_status_ok)
+        return srtp_err_status_fail;
+
+    /* create a new recvieve ctx with test_alt_key but since it is new it will
+     * have ROC equal to 1
+     * and therefore should fail to unprotected */
+    {
+        srtp_t srtp_recv_roc_0;
+
+        policy.ssrc.type = ssrc_any_inbound;
+        policy.key = test_alt_key;
+        status = srtp_create(&srtp_recv_roc_0, &policy);
+        if (status)
+            return status;
+
+        status =
+            srtp_unprotect(srtp_recv_roc_0, msg, &protected_msg_len_octets);
+        if (status == srtp_err_status_ok)
+            return srtp_err_status_fail;
+
+        status = srtp_dealloc(srtp_recv_roc_0);
+        if (status)
+            return status;
+    }
+
+    /* update recive ctx to use test_alt_key */
+    policy.ssrc.type = ssrc_any_inbound;
+    policy.key = test_alt_key;
+    status = srtp_update(srtp_recv, &policy);
+    if (status)
+        return status;
+
+    /* verify that can still unprotect, therfore key is updated and ROC value is
+     * preserved */
+    status = srtp_unprotect(srtp_recv, msg, &protected_msg_len_octets);
+    if (status)
+        return status;
+
+    free(msg);
+
+    status = srtp_dealloc(srtp_snd);
+    if (status)
+        return status;
+
+    status = srtp_dealloc(srtp_recv);
+    if (status)
+        return status;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_setup_protect_trailer_streams(
+    srtp_t *srtp_send,
+    srtp_t *srtp_send_mki,
+    srtp_t *srtp_send_aes_gcm,
+    srtp_t *srtp_send_aes_gcm_mki)
+{
+    srtp_err_status_t status;
+    srtp_policy_t policy;
+    srtp_policy_t policy_mki;
+
+#ifdef OPENSSL
+    srtp_policy_t policy_aes_gcm;
+    srtp_policy_t policy_aes_gcm_mki;
+#endif // OPENSSL
+
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ekt = NULL;
+    policy.window_size = 128;
+    policy.allow_repeat_tx = 0;
+    policy.next = NULL;
+    policy.ssrc.type = ssrc_any_outbound;
+    policy.key = test_key;
+
+    memset(&policy_mki, 0, sizeof(policy_mki));
+    srtp_crypto_policy_set_rtp_default(&policy_mki.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy_mki.rtcp);
+    policy_mki.ekt = NULL;
+    policy_mki.window_size = 128;
+    policy_mki.allow_repeat_tx = 0;
+    policy_mki.next = NULL;
+    policy_mki.ssrc.type = ssrc_any_outbound;
+    policy_mki.key = NULL;
+    policy_mki.keys = test_keys;
+    policy_mki.num_master_keys = 2;
+
+#ifdef OPENSSL
+    memset(&policy_aes_gcm, 0, sizeof(policy_aes_gcm));
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtp);
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm.rtcp);
+    policy_aes_gcm.ekt = NULL;
+    policy_aes_gcm.window_size = 128;
+    policy_aes_gcm.allow_repeat_tx = 0;
+    policy_aes_gcm.next = NULL;
+    policy_aes_gcm.ssrc.type = ssrc_any_outbound;
+    policy_aes_gcm.key = test_key;
+
+    memset(&policy_aes_gcm_mki, 0, sizeof(policy_aes_gcm_mki));
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm_mki.rtp);
+    srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy_aes_gcm_mki.rtcp);
+    policy_aes_gcm_mki.ekt = NULL;
+    policy_aes_gcm_mki.window_size = 128;
+    policy_aes_gcm_mki.allow_repeat_tx = 0;
+    policy_aes_gcm_mki.next = NULL;
+    policy_aes_gcm_mki.ssrc.type = ssrc_any_outbound;
+    policy_aes_gcm_mki.key = NULL;
+    policy_aes_gcm_mki.keys = test_keys;
+    policy_aes_gcm_mki.num_master_keys = 2;
+#endif
+
+    /* create a send ctx with defualt profile and test_key */
+    status = srtp_create(srtp_send, &policy);
+    if (status)
+        return status;
+
+    status = srtp_create(srtp_send_mki, &policy_mki);
+    if (status)
+        return status;
+
+#ifdef OPENSSL
+    status = srtp_create(srtp_send_aes_gcm, &policy_aes_gcm);
+    if (status)
+        return status;
+
+    status = srtp_create(srtp_send_aes_gcm_mki, &policy_aes_gcm_mki);
+    if (status)
+        return status;
+#endif // OPENSSL
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_protect_trailer_length()
+{
+    srtp_t srtp_send;
+    srtp_t srtp_send_mki;
+    srtp_t srtp_send_aes_gcm;
+    srtp_t srtp_send_aes_gcm_mki;
+    uint32_t length = 0;
+    srtp_err_status_t status;
+
+    srtp_test_setup_protect_trailer_streams(
+        &srtp_send, &srtp_send_mki, &srtp_send_aes_gcm, &srtp_send_aes_gcm_mki);
+
+    status = srtp_get_protect_trailer_length(srtp_send, 0, 0, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 10 bytes */
+    if (length != 10)
+        return srtp_err_status_fail;
+
+    status = srtp_get_protect_trailer_length(srtp_send_mki, 1, 1, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 10 bytes + MKI length: 4 bytes*/
+    if (length != 14)
+        return srtp_err_status_fail;
+
+#ifdef OPENSSL
+    status = srtp_get_protect_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 16 bytes */
+    if (length != 16)
+        return srtp_err_status_fail;
+
+    status =
+        srtp_get_protect_trailer_length(srtp_send_aes_gcm_mki, 1, 1, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 16 bytes + MKI length: 4 bytes*/
+    if (length != 20)
+        return srtp_err_status_fail;
+#endif // OPENSSL
+
+    srtp_dealloc(srtp_send);
+    srtp_dealloc(srtp_send_mki);
+#ifdef OPENSSL
+    srtp_dealloc(srtp_send_aes_gcm);
+    srtp_dealloc(srtp_send_aes_gcm_mki);
+#endif
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_protect_rtcp_trailer_length()
+{
+    srtp_t srtp_send;
+    srtp_t srtp_send_mki;
+    srtp_t srtp_send_aes_gcm;
+    srtp_t srtp_send_aes_gcm_mki;
+    uint32_t length = 0;
+    srtp_err_status_t status;
+
+    srtp_test_setup_protect_trailer_streams(
+        &srtp_send, &srtp_send_mki, &srtp_send_aes_gcm, &srtp_send_aes_gcm_mki);
+
+    status = srtp_get_protect_rtcp_trailer_length(srtp_send, 0, 0, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 10 bytes + SRTCP Trailer 4 bytes*/
+    if (length != 14)
+        return srtp_err_status_fail;
+
+    status = srtp_get_protect_rtcp_trailer_length(srtp_send_mki, 1, 1, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 10 bytes + SRTCP Trailer 4 bytes + MKI 4 bytes*/
+    if (length != 18)
+        return srtp_err_status_fail;
+
+#ifdef OPENSSL
+    status =
+        srtp_get_protect_rtcp_trailer_length(srtp_send_aes_gcm, 0, 0, &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 16 bytes + SRTCP Trailer 4 bytes*/
+    if (length != 20)
+        return srtp_err_status_fail;
+
+    status = srtp_get_protect_rtcp_trailer_length(srtp_send_aes_gcm_mki, 1, 1,
+                                                  &length);
+    if (status)
+        return status;
+
+    /*  TAG Length: 16 bytes + SRTCP Trailer 4 bytes + MKI 4 bytes*/
+    if (length != 24)
+        return srtp_err_status_fail;
+#endif // OPENSSL
+
+    srtp_dealloc(srtp_send);
+    srtp_dealloc(srtp_send_mki);
+#ifdef OPENSSL
+    srtp_dealloc(srtp_send_aes_gcm);
+    srtp_dealloc(srtp_send_aes_gcm_mki);
+#endif
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_get_roc()
+{
+    srtp_err_status_t status;
+    srtp_policy_t policy;
+    srtp_t session;
+    srtp_hdr_t *pkt;
+    uint32_t i;
+    uint32_t roc;
+    uint32_t ts;
+    uint16_t seq;
+
+    int msg_len_octets = 32;
+    int protected_msg_len_octets;
+
+    memset(&policy, 0, sizeof(policy));
+    srtp_crypto_policy_set_rtp_default(&policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
+    policy.ssrc.type = ssrc_specific;
+    policy.ssrc.value = 0xcafebabe;
+    policy.key = test_key;
+    policy.window_size = 128;
+
+    /* Create a sender session */
+    status = srtp_create(&session, &policy);
+    if (status) {
+        return status;
+    }
+
+    /* Set start sequence so we roll over */
+    seq = 65535;
+    ts = 0;
+
+    for (i = 0; i < 2; i++) {
+        pkt = srtp_create_test_packet_extended(msg_len_octets,
+                                               policy.ssrc.value, seq, ts,
+                                               &protected_msg_len_octets);
+        status = srtp_protect(session, pkt, &protected_msg_len_octets);
+        free(pkt);
+        if (status) {
+            return status;
+        }
+
+        status = srtp_get_stream_roc(session, policy.ssrc.value, &roc);
+        if (status) {
+            return status;
+        }
+
+        if (roc != i) {
+            return srtp_err_status_fail;
+        }
+
+        seq++;
+        ts++;
+    }
+
+    /* Cleanup */
+    status = srtp_dealloc(session);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t test_set_receiver_roc(uint32_t packets,
+                                               uint32_t roc_to_set)
+{
+    srtp_err_status_t status;
+
+    srtp_policy_t sender_policy;
+    srtp_t sender_session;
+
+    srtp_policy_t receiver_policy;
+    srtp_t receiver_session;
+
+    srtp_hdr_t *pkt_1;
+    unsigned char *recv_pkt_1;
+
+    srtp_hdr_t *pkt_2;
+    unsigned char *recv_pkt_2;
+
+    uint32_t i;
+    uint32_t ts;
+    uint16_t seq;
+
+    int msg_len_octets = 32;
+    int protected_msg_len_octets_1;
+    int protected_msg_len_octets_2;
+
+    /* Create sender */
+    memset(&sender_policy, 0, sizeof(sender_policy));
+    srtp_crypto_policy_set_rtp_default(&sender_policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&sender_policy.rtcp);
+    sender_policy.ssrc.type = ssrc_specific;
+    sender_policy.ssrc.value = 0xcafebabe;
+    sender_policy.key = test_key;
+    sender_policy.window_size = 128;
+
+    status = srtp_create(&sender_session, &sender_policy);
+    if (status) {
+        return status;
+    }
+
+    /* Create and protect packets */
+    seq = 0;
+    ts = 0;
+    for (i = 0; i < packets; i++) {
+        srtp_hdr_t *tmp_pkt;
+        int tmp_len;
+
+        tmp_pkt = srtp_create_test_packet_extended(
+            msg_len_octets, sender_policy.ssrc.value, seq, ts, &tmp_len);
+        status = srtp_protect(sender_session, tmp_pkt, &tmp_len);
+        free(tmp_pkt);
+        if (status) {
+            return status;
+        }
+        seq++;
+        ts++;
+    }
+
+    /* Create the first packet to decrypt and test for ROC change */
+    pkt_1 = srtp_create_test_packet_extended(msg_len_octets,
+                                             sender_policy.ssrc.value, seq, ts,
+                                             &protected_msg_len_octets_1);
+    status = srtp_protect(sender_session, pkt_1, &protected_msg_len_octets_1);
+    if (status) {
+        return status;
+    }
+
+    /* Create the second packet to decrypt and test for ROC change */
+    seq++;
+    ts++;
+    pkt_2 = srtp_create_test_packet_extended(msg_len_octets,
+                                             sender_policy.ssrc.value, seq, ts,
+                                             &protected_msg_len_octets_2);
+    status = srtp_protect(sender_session, pkt_2, &protected_msg_len_octets_2);
+    if (status) {
+        return status;
+    }
+
+    /* Create the receiver */
+    memset(&receiver_policy, 0, sizeof(receiver_policy));
+    srtp_crypto_policy_set_rtp_default(&receiver_policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&receiver_policy.rtcp);
+    receiver_policy.ssrc.type = ssrc_specific;
+    receiver_policy.ssrc.value = sender_policy.ssrc.value;
+    receiver_policy.key = test_key;
+    receiver_policy.window_size = 128;
+
+    status = srtp_create(&receiver_session, &receiver_policy);
+    if (status) {
+        return status;
+    }
+
+    /* Make a copy of the first sent protected packet */
+    recv_pkt_1 = malloc(protected_msg_len_octets_1);
+    if (recv_pkt_1 == NULL) {
+        return srtp_err_status_fail;
+    }
+    memcpy(recv_pkt_1, pkt_1, protected_msg_len_octets_1);
+
+    /* Make a copy of the second sent protected packet */
+    recv_pkt_2 = malloc(protected_msg_len_octets_2);
+    if (recv_pkt_2 == NULL) {
+        return srtp_err_status_fail;
+    }
+    memcpy(recv_pkt_2, pkt_2, protected_msg_len_octets_2);
+
+    /* Set the ROC to the wanted value */
+    status = srtp_set_stream_roc(receiver_session, receiver_policy.ssrc.value,
+                                 roc_to_set);
+    if (status) {
+        return status;
+    }
+
+    /* Unprotect the first packet */
+    status = srtp_unprotect(receiver_session, recv_pkt_1,
+                            &protected_msg_len_octets_1);
+    if (status) {
+        return status;
+    }
+
+    /* Unprotect the second packet */
+    status = srtp_unprotect(receiver_session, recv_pkt_2,
+                            &protected_msg_len_octets_2);
+    if (status) {
+        return status;
+    }
+
+    /* Cleanup */
+    status = srtp_dealloc(sender_session);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(receiver_session);
+    if (status) {
+        return status;
+    }
+
+    free(pkt_1);
+    free(recv_pkt_1);
+    free(pkt_2);
+    free(recv_pkt_2);
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t test_set_sender_roc(uint16_t seq, uint32_t roc_to_set)
+{
+    srtp_err_status_t status;
+
+    srtp_policy_t sender_policy;
+    srtp_t sender_session;
+
+    srtp_policy_t receiver_policy;
+    srtp_t receiver_session;
+
+    srtp_hdr_t *pkt;
+    unsigned char *recv_pkt;
+
+    uint32_t ts;
+
+    int msg_len_octets = 32;
+    int protected_msg_len_octets;
+
+    /* Create sender */
+    memset(&sender_policy, 0, sizeof(sender_policy));
+    srtp_crypto_policy_set_rtp_default(&sender_policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&sender_policy.rtcp);
+    sender_policy.ssrc.type = ssrc_specific;
+    sender_policy.ssrc.value = 0xcafebabe;
+    sender_policy.key = test_key;
+    sender_policy.window_size = 128;
+
+    status = srtp_create(&sender_session, &sender_policy);
+    if (status) {
+        return status;
+    }
+
+    /* Set the ROC before encrypting the first packet */
+    status = srtp_set_stream_roc(sender_session, sender_policy.ssrc.value,
+                                 roc_to_set);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    /* Create the packet to decrypt */
+    ts = 0;
+    pkt = srtp_create_test_packet_extended(msg_len_octets,
+                                           sender_policy.ssrc.value, seq, ts,
+                                           &protected_msg_len_octets);
+    status = srtp_protect(sender_session, pkt, &protected_msg_len_octets);
+    if (status) {
+        return status;
+    }
+
+    /* Create the receiver */
+    memset(&receiver_policy, 0, sizeof(receiver_policy));
+    srtp_crypto_policy_set_rtp_default(&receiver_policy.rtp);
+    srtp_crypto_policy_set_rtcp_default(&receiver_policy.rtcp);
+    receiver_policy.ssrc.type = ssrc_specific;
+    receiver_policy.ssrc.value = sender_policy.ssrc.value;
+    receiver_policy.key = test_key;
+    receiver_policy.window_size = 128;
+
+    status = srtp_create(&receiver_session, &receiver_policy);
+    if (status) {
+        return status;
+    }
+
+    /* Make a copy of the sent protected packet */
+    recv_pkt = malloc(protected_msg_len_octets);
+    if (recv_pkt == NULL) {
+        return srtp_err_status_fail;
+    }
+    memcpy(recv_pkt, pkt, protected_msg_len_octets);
+
+    /* Set the ROC to the wanted value */
+    status = srtp_set_stream_roc(receiver_session, receiver_policy.ssrc.value,
+                                 roc_to_set);
+    if (status) {
+        return status;
+    }
+
+    status =
+        srtp_unprotect(receiver_session, recv_pkt, &protected_msg_len_octets);
+    if (status) {
+        return status;
+    }
+
+    /* Cleanup */
+    status = srtp_dealloc(sender_session);
+    if (status) {
+        return status;
+    }
+
+    status = srtp_dealloc(receiver_session);
+    if (status) {
+        return status;
+    }
+
+    free(pkt);
+    free(recv_pkt);
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_set_receiver_roc()
+{
+    int packets;
+    uint32_t roc;
+    srtp_err_status_t status;
+
+    /* First test does not rollover */
+    packets = 1;
+    roc = 0;
+
+    status = test_set_receiver_roc(packets - 1, roc);
+    if (status) {
+        return status;
+    }
+
+    status = test_set_receiver_roc(packets, roc);
+    if (status) {
+        return status;
+    }
+
+    status = test_set_receiver_roc(packets + 1, roc);
+    if (status) {
+        return status;
+    }
+
+    status = test_set_receiver_roc(packets + 60000, roc);
+    if (status) {
+        return status;
+    }
+
+    /* Second test should rollover */
+    packets = 65535;
+    roc = 0;
+
+    status = test_set_receiver_roc(packets - 1, roc);
+    if (status) {
+        return status;
+    }
+
+    status = test_set_receiver_roc(packets, roc);
+    if (status) {
+        return status;
+    }
+
+    /* Now the rollover counter should be 1 */
+    roc = 1;
+    status = test_set_receiver_roc(packets + 1, roc);
+    if (status) {
+        return status;
+    }
+
+    status = test_set_receiver_roc(packets + 60000, roc);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_test_set_sender_roc()
+{
+    uint32_t roc;
+    uint16_t seq;
+    srtp_err_status_t status;
+
+    seq = 43210;
+    roc = 0;
+    status = test_set_sender_roc(seq, roc);
+    if (status) {
+        return status;
+    }
+
+    roc = 65535;
+    status = test_set_sender_roc(seq, roc);
+    if (status) {
+        return status;
+    }
+
+    roc = 0xffff;
+    status = test_set_sender_roc(seq, roc);
+    if (status) {
+        return status;
+    }
+
+    roc = 0xffff00;
+    status = test_set_sender_roc(seq, roc);
+    if (status) {
+        return status;
+    }
+
+    roc = 0xfffffff0;
+    status = test_set_sender_roc(seq, roc);
+    if (status) {
+        return status;
+    }
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * srtp policy definitions - these definitions are used above
+ */
+
+// clang-format off
+unsigned char test_key[46] = {
+    0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+    0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+    0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
+    0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
+    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+};
+
+unsigned char test_key_2[46] = {
+    0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
+    0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
+    0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
+    0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
+    0xc3, 0x17, 0xf2, 0xda, 0xbe, 0x35, 0x77, 0x93,
+    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
+};
+
+unsigned char test_mki_id[TEST_MKI_ID_SIZE] = {
+    0xe1, 0xf9, 0x7a, 0x0d
+};
+
+unsigned char test_mki_id_2[TEST_MKI_ID_SIZE] = {
+    0xf3, 0xa1, 0x46, 0x71
+};
+// clang-format on
+
+const srtp_policy_t default_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        16,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        16,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+const srtp_policy_t aes_only_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC                        */
+    {
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        0,                              /* auth tag length in octets   */
+        sec_serv_conf                   /* security services flag      */
+    },
+    {
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        0,                              /* auth tag length in octets   */
+        sec_serv_conf                   /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+const srtp_policy_t hmac_only_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_HMAC_SHA1,   /* authentication func type    */
+        20,               /* auth key length in octets   */
+        4,                /* auth tag length in octets   */
+        sec_serv_auth     /* security services flag      */
+    },
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_HMAC_SHA1,   /* authentication func type    */
+        20,               /* auth key length in octets   */
+        4,                /* auth tag length in octets   */
+        sec_serv_auth     /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* Number of Master keys associated with the policy */
+    NULL, /* indicates that EKT is not in use                 */
+    128,  /* replay window size                               */
+    0,    /* retransmission not allowed                       */
+    NULL, /* no encrypted extension headers                   */
+    0,    /* list of encrypted extension headers is empty     */
+    NULL
+};
+
+#ifdef OPENSSL
+const srtp_policy_t aes128_gcm_8_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_GCM_128,               /* cipher type                 */
+        SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_GCM_128,               /* cipher type                 */
+        SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+const srtp_policy_t aes128_gcm_8_cauth_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_GCM_128,               /* cipher type                 */
+        SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_GCM_128,               /* cipher type                 */
+        SRTP_AES_GCM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_auth                   /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+const srtp_policy_t aes256_gcm_8_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_GCM_256,               /* cipher type                 */
+        SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_GCM_256,               /* cipher type                 */
+        SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+const srtp_policy_t aes256_gcm_8_cauth_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_GCM_256,               /* cipher type                 */
+        SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_GCM_256,               /* cipher type                 */
+        SRTP_AES_GCM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_NULL_AUTH,                 /* authentication func type    */
+        0,                              /* auth key length in octets   */
+        8,                              /* auth tag length in octets   */
+        sec_serv_auth                   /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+#endif
+
+const srtp_policy_t null_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_NULL_AUTH,   /* authentication func type    */
+        0,                /* auth key length in octets   */
+        0,                /* auth tag length in octets   */
+        sec_serv_none     /* security services flag      */
+    },
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_NULL_AUTH,   /* authentication func type    */
+        0,                /* auth key length in octets   */
+        0,                /* auth tag length in octets   */
+        sec_serv_none     /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+// clang-format off
+unsigned char test_256_key[46] = {
+    0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
+    0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
+    0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
+    0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
+
+    0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
+    0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
+};
+
+unsigned char test_256_key_2[46] = {
+    0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
+    0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
+    0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
+    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6, 0xc1, 0x73,
+    0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
+    0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
+};
+
+srtp_master_key_t master_256_key_1 = {
+    test_256_key,
+    test_mki_id,
+    TEST_MKI_ID_SIZE
+};
+
+srtp_master_key_t master_256_key_2 = {
+    test_256_key_2,
+    test_mki_id_2,
+    TEST_MKI_ID_SIZE
+};
+
+srtp_master_key_t *test_256_keys[2] = {
+    &master_key_1,
+    &master_key_2
+};
+// clang-format on
+
+const srtp_policy_t aes_256_hmac_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_ICM_256,               /* cipher type                 */
+        SRTP_AES_ICM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        20,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_ICM_256,               /* cipher type                 */
+        SRTP_AES_ICM_256_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        20,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_256_keys,
+    2,    /* indicates the number of Master keys          */
+    NULL, /* indicates that EKT is not in use             */
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
+
+// clang-format off
+uint8_t ekt_test_key[16] = {
+    0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
+    0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
+};
+// clang-format on
+
+#include "ekt.h"
+
+// clang-format off
+srtp_ekt_policy_ctx_t ekt_test_policy = {
+    0xa5a5,                     /* SPI */
+    SRTP_EKT_CIPHER_AES_128_ECB,
+    ekt_test_key,
+    NULL
+};
+// clang-format on
+
+const srtp_policy_t hmac_only_with_ekt_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_HMAC_SHA1,   /* authentication func type    */
+        20,               /* auth key length in octets   */
+        4,                /* auth tag length in octets   */
+        sec_serv_auth     /* security services flag      */
+    },
+    {
+        SRTP_NULL_CIPHER, /* cipher type                 */
+        0,                /* cipher key length in octets */
+        SRTP_HMAC_SHA1,   /* authentication func type    */
+        20,               /* auth key length in octets   */
+        4,                /* auth tag length in octets   */
+        sec_serv_auth     /* security services flag      */
+    },
+    NULL,
+    (srtp_master_key_t **)test_keys,
+    2,                /* indicates the number of Master keys          */
+    &ekt_test_policy, /* indicates that EKT is not in use             */
+    128,              /* replay window size                           */
+    0,                /* retransmission not allowed                   */
+    NULL,             /* no encrypted extension headers               */
+    0,                /* list of encrypted extension headers is empty */
+    NULL
+};
+
+/*
+ * an array of pointers to the policies listed above
+ *
+ * This array is used to test various aspects of libSRTP for
+ * different cryptographic policies.  The order of the elements
+ * matters - the timing test generates output that can be used
+ * in a plot (see the gnuplot script file 'timing').  If you
+ * add to this list, you should do it at the end.
+ */
+
+// clang-format off
+const srtp_policy_t *policy_array[] = {
+    &hmac_only_policy,
+    &aes_only_policy,
+    &default_policy,
+#ifdef OPENSSL
+    &aes128_gcm_8_policy,
+    &aes128_gcm_8_cauth_policy,
+    &aes256_gcm_8_policy,
+    &aes256_gcm_8_cauth_policy,
+#endif
+    &null_policy,
+    &aes_256_hmac_policy,
+    &hmac_only_with_ekt_policy,
+    NULL
+};
+// clang-format on
+
+const srtp_policy_t wildcard_policy = {
+    { ssrc_any_outbound, 0 }, /* SSRC */
+    {
+        /* SRTP policy */
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        16,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    {
+        /* SRTCP policy */
+        SRTP_AES_ICM_128,               /* cipher type                 */
+        SRTP_AES_ICM_128_KEY_LEN_WSALT, /* cipher key length in octets */
+        SRTP_HMAC_SHA1,                 /* authentication func type    */
+        16,                             /* auth key length in octets   */
+        10,                             /* auth tag length in octets   */
+        sec_serv_conf_and_auth          /* security services flag      */
+    },
+    test_key,
+    NULL,
+    0,
+    NULL,
+    128,  /* replay window size                           */
+    0,    /* retransmission not allowed                   */
+    NULL, /* no encrypted extension headers               */
+    0,    /* list of encrypted extension headers is empty */
+    NULL
+};
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/test_srtp.c
@@ -0,0 +1,185 @@
+/*
+ * test_srtp.c
+ *
+ * Unit tests for internal srtp functions
+ *
+ * Cisco Systems, Inc.
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 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.
+ *
+ */
+
+/*
+ * Test specific.
+ */
+#include "cutest.h"
+
+/*
+ * libSRTP specific.
+ */
+#include "../srtp/srtp.c" // Get access to static functions
+
+/*
+ * Standard library.
+ */
+
+/*
+ * Forward declarations for all tests.
+ */
+
+void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output(void);
+void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param(void);
+void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number(void);
+
+/*
+ * NULL terminated array of tests.
+ * The first item in the array is a char[] which give some information about
+ * what is being tested and is displayed to the user during runtime, the second
+ * item is the test function.
+ */
+
+TEST_LIST = { { "srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()",
+                srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output },
+              { "srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()",
+                srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param },
+              { "srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()",
+                srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number },
+              { NULL } /* End of tests */ };
+
+/*
+ * Implementation.
+ */
+
+void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()
+{
+    // Preconditions
+    srtp_session_keys_t session_keys;
+    v128_t init_vector;
+    srtcp_hdr_t header;
+    uint32_t sequence_num;
+
+    // Postconditions
+    srtp_err_status_t status;
+    const v128_t zero_vector;
+    memset((v128_t *)&zero_vector, 0, sizeof(v128_t));
+
+    // Given
+    memset(&session_keys, 0, sizeof(srtp_session_keys_t));
+    memset(&init_vector, 0, sizeof(v128_t));
+    memset(&header, 0, sizeof(srtcp_hdr_t));
+    sequence_num = 0x0UL;
+
+    // When
+    status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
+                                     &header);
+
+    // Then
+    TEST_CHECK(status == srtp_err_status_ok);
+    TEST_CHECK(memcmp(&zero_vector, &init_vector, sizeof(v128_t)) == 0);
+}
+
+void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()
+{
+    // Preconditions
+    srtp_session_keys_t session_keys;
+    v128_t init_vector;
+    srtcp_hdr_t header;
+    uint32_t sequence_num;
+
+    // Postconditions
+    srtp_err_status_t status;
+
+    // Given
+    memset(&session_keys, 0, sizeof(srtp_session_keys_t));
+    memset(&init_vector, 0, sizeof(v128_t));
+    memset(&header, 0, sizeof(srtcp_hdr_t));
+    sequence_num = 0x7FFFFFFFUL + 0x1UL;
+
+    // When
+    status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
+                                     &header);
+
+    // Then
+    TEST_CHECK(status == srtp_err_status_bad_param);
+}
+
+/*
+ * Regression test for issue #256:
+ * Srtcp IV calculation incorrectly masks high bit of sequence number for
+ * little-endian platforms.
+ * Ensure that for each valid sequence number where the most significant bit is
+ * high that we get an expected and unique IV.
+ */
+void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
+{
+#define SAMPLE_COUNT (3)
+    // Preconditions
+    // Test each significant bit high in each full byte.
+    srtp_session_keys_t session_keys;
+    srtcp_hdr_t header;
+    v128_t output_iv[SAMPLE_COUNT];
+    memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
+    uint32_t sequence_num[SAMPLE_COUNT];
+    sequence_num[0] = 0xFF;
+    sequence_num[1] = 0xFF00;
+    sequence_num[2] = 0xFF0000;
+
+    // Postconditions
+    v128_t final_iv[SAMPLE_COUNT];
+    memset(&final_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
+    final_iv[0].v8[11] = 0xFF;
+    final_iv[1].v8[10] = 0xFF;
+    final_iv[2].v8[9] = 0xFF;
+
+    // Given
+    memset(&session_keys, 0, sizeof(srtp_session_keys_t));
+    memset(&header, 0, sizeof(srtcp_hdr_t));
+
+    // When
+    size_t i = 0;
+    for (i = 0; i < SAMPLE_COUNT; i++) {
+        TEST_CHECK(srtp_calc_aead_iv_srtcp(&session_keys, &output_iv[i],
+                                           sequence_num[i],
+                                           &header) == srtp_err_status_ok);
+    }
+
+    // Then all IVs are as expected
+    for (i = 0; i < SAMPLE_COUNT; i++) {
+        TEST_CHECK(memcmp(&final_iv[i], &output_iv[i], sizeof(v128_t)) == 0);
+    }
+#undef SAMPLE_COUNT
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/util.c
@@ -0,0 +1,210 @@
+/*
+ * util.c
+ *
+ * Utilities used by the test apps
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2014-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.
+ *
+ */
+
+#include "util.h"
+
+#include <string.h>
+#include <stdint.h>
+
+char bit_string[MAX_PRINT_STRING_LEN];
+
+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 */
+    return -1; /* this keeps compilers from complaining */
+}
+
+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];
+}
+
+/*
+ * 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;
+}
+
+char *octet_string_hex_string(const void *s, int length)
+{
+    const uint8_t *str = (const uint8_t *)s;
+    int i;
+
+    /* double length, since one octet takes two hex characters */
+    length *= 2;
+
+    /* truncate string if it would be too long */
+    if (length > MAX_PRINT_STRING_LEN) {
+        length = MAX_PRINT_STRING_LEN - 1;
+    }
+
+    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] = 0; /* null terminate string */
+    return bit_string;
+}
+
+static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                               "abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+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++;
+        }
+    }
+
+    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;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/util.h
@@ -0,0 +1,53 @@
+/*
+ * util.h
+ *
+ * Utilities used by the test apps
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2014-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SRTP_TEST_UTIL_H
+#define SRTP_TEST_UTIL_H
+
+#define MAX_PRINT_STRING_LEN 1024
+
+int hex_string_to_octet_string(char *raw, char *hex, int len);
+char *octet_string_hex_string(const void *s, int length);
+int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/netwerk/srtp/src/test/words.txt
@@ -0,0 +1,250 @@
+abducing
+acidheads
+acidness
+actons
+admixtures
+affidavit
+agelastic
+alated
+alimentary
+alleviated
+allseed
+annexure
+arragonite
+atonements
+autacoid
+axe
+axon
+ayres
+beathing
+blazonry
+bottom
+braising
+brehon
+brindisi
+broadcasts
+buds
+bulnbulns
+bushcraft
+calamander
+calipee
+casing
+caveat
+chaffings
+citifies
+clappers
+claques
+clavate
+colonial
+colonials
+commonalty
+compares
+consequent
+consumed
+contango
+courtierly
+creamery
+cruddiest
+cue
+cultish
+cumin
+cyclus
+dahlias
+dentitions
+derailers
+devitrify
+dibs
+diphysite
+disjunes
+drolleries
+dubitated
+dupion
+earliness
+eductor
+elenctic
+empresses
+entames
+epaulettes
+epicanthic
+epochal
+estated
+eurhythmic
+exfoliated
+extremity
+fayence
+figgery
+flaming
+foes
+forelays
+forewings
+forfeits
+fratches
+gardened
+gentile
+glumpish
+glyph
+goatherd
+grow
+gulden
+gumming
+hackling
+hanapers
+hared
+hatters
+hectare
+hedger
+heel
+heterodox
+hidden
+histologic
+howe
+inglobe
+inliers
+inuredness
+iotacism
+japed
+jelled
+jiffy
+jollies
+judgeship
+karite
+kart
+kenophobia
+kittens
+lactarian
+lancets
+leasable
+leep
+leming
+licorice
+listing
+lividly
+lobectomy
+lysosome
+madders
+maderizing
+manacle
+mangels
+marshiest
+maulstick
+meliorates
+mercy
+mikados
+monarchise
+moultings
+mucro
+munnions
+mystic
+myxoedemic
+nointing
+nong
+nonsense
+ochidore
+octuor
+officering
+opaqued
+oragious
+outtell
+oxeye
+pads
+palamae
+pansophy
+parazoa
+pepsines
+perimetric
+pheasant
+phonotypy
+pitarah
+plaintful
+poinders
+poke
+politer
+poonces
+populism
+pouty
+praedial
+presence
+prompter
+pummelled
+punishing
+quippish
+radicality
+radiuses
+rebuffing
+recorded
+redips
+regulators
+replay
+retrocedes
+rigors
+risen
+rootstocks
+rotenone
+rudenesses
+ruggedest
+runabout
+ruthfully
+sagacious
+scapes
+sclera
+sclerotium
+scumbering
+secondi
+serial
+shampoo
+showed
+sights
+sirenised
+sized
+slave
+socle
+solidness
+some
+spetches
+spiels
+squiring
+staminode
+stay
+stewpot
+stunsails
+subhumid
+subprogram
+supawn
+surplusage
+swimming
+swineherd
+tabun
+talliths
+taroks
+tensed
+thinnings
+three
+tipper
+toko
+tomahawks
+tombolos
+torpefy
+torulae
+touns
+travails
+tsarist
+unbeseems
+unblamably
+unbooked
+unnailed
+updates
+valorise
+viability
+virtue
+vulturns
+vulvate
+warran
+weakness
+westernise
+whingeings
+wrenching
+written
+yak
+yate
+yaupon
+zendiks
--- a/netwerk/srtp/srtp_update.log
+++ b/netwerk/srtp/srtp_update.log
@@ -1,1 +1,2 @@
 srtp updated from CVS on Fri Sep 21 14:51:37 EDT 2012
+srtp updated to revision 8f38517394a45678cd4468febf69f75722f35d00 from git on Wed Nov 22 14:15:32 PST 2017