Merge remote-tracking branch 'goog/qt-gsi'

Change-Id: I3510ee0d511351112102c8f8e851097066597a4b
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..358e222
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,79 @@
+AccessModifierOffset: -4
+
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands:   true
+AlignTrailingComments: true
+
+AllowAllParametersOfDeclarationOnNextLine: false
+
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+
+BinPackArguments: true
+BinPackParameters: false
+BraceWrapping:
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   true
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+ContinuationIndentWidth: 4
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+
+IndentCaseLabels: false
+IndentWidth:     4
+IndentWrappedFunctionNames: false
+
+KeepEmptyLinesAtTheStartOfBlocks: false
+
+MaxEmptyLinesToKeep: 1
+
+PenaltyBreakBeforeFirstCallParameter: 16
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000
+PenaltyReturnTypeOnItsOwnLine: 9000
+
+Cpp11BracedListStyle: false
+
+PointerAlignment: Right
+
+ReflowComments:  true
+
+SortIncludes: false
+
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+TabWidth:        4
+UseTab:          Never
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c8b1235
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+# Misc crap
+*~
+old
+old?
+*.pc
+
+# Object files
+*.o
+
+# Libraries
+*.lib
+*.a
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# srtp things
+build
+Debug
+Makefile
+Root
+autom4te.cache
+config.log
+config.status
+crypto/include/config.h
+crypto/test/aes_calc
+crypto/test/cipher_driver
+crypto/test/datatypes_driver
+crypto/test/env
+crypto/test/kernel_driver
+crypto/test/sha1_driver
+crypto/test/stat_driver
+tables/aes_tables
+test/dtls_srtp_driver
+test/rdbx_driver
+test/replay_driver
+test/roc_driver
+test/rtp_decoder
+test/rtpw
+test/srtp_driver
+test/test_srtp
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..a7380f1
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,212 @@
+dist: xenial
+sudo: false
+language: c
+
+env:
+  global:
+    - secure: "QD09MuUxftXRXtz7ZrB7S0NV/3O9yVhjvIlCSbXN8B87rNSDC8wxMThKMT7iZewnqGk53m+Up19PiMw5ERlHose5tm2cmY1FO/l+c9oAyWZaAL+4XNXryq6zI5F5FX5I61NbfqV3xcnfLTI2QIJF6WqDojNxhPjTbNzQGxIDuqw="
+
+matrix:
+  include:
+
+    # linux build
+    - os: linux
+      env:
+        - TEST="linux (gcc / valgrind)"
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - gcc-6
+            - valgrind
+      script:
+        - CC=gcc-6 EXTRA_CFLAGS=-Werror ./configure
+        - make
+        - make runtest
+        - make runtest-valgrind
+        - make distclean
+        - mkdir build && cd build
+        - cmake ..
+        - make
+        - make test
+
+    # linux build with openssl
+    - os: linux
+      env:
+        - TEST="linux openssl (gcc / valgrind)"
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - gcc-6
+            - valgrind
+      script:
+        - CC=gcc-6 EXTRA_CFLAGS=-Werror ./configure --enable-openssl
+        - make
+        - make runtest
+        - make runtest-valgrind
+        - make distclean
+        - mkdir build && cd build
+        - cmake -DENABLE_OPENSSL=ON ..
+        - make
+        - make test
+        - cd ..
+        - mkdir build_shared && cd build_shared
+        - cmake -DENABLE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON ..
+        - make
+        - make test
+
+    # linux build with openssl and clang
+    - os: linux
+      env:
+        - TEST="linux openssl (clang)"
+      addons:
+        apt:
+          packages:
+            - clang
+      script:
+        - CC=clang EXTRA_CFLAGS=-Werror ./configure --enable-openssl
+        - make
+        - make runtest
+
+    # linux build with nss
+    - os: linux
+      env:
+        - TEST="linux nss (gcc / valgrind)"
+      addons:
+        apt:
+          sources:
+            - ubuntu-toolchain-r-test
+          packages:
+            - gcc-6
+            - valgrind
+            - libnss3-dev
+      script:
+        - CC=gcc-6 EXTRA_CFLAGS=-Werror ./configure --enable-nss
+        - make
+        - make runtest
+        - make runtest-valgrind
+
+    # default osx build
+    - os: osx
+      env:
+        - TEST="osx"
+      script:
+        - EXTRA_CFLAGS=-Werror ./configure
+        - make
+        - make runtest
+        - make distclean
+        - mkdir build && cd build
+        - cmake ..
+        - make
+        - make test
+
+    # osx build with openssl
+    - os: osx
+      env:
+        - TEST="osx openssl"
+      before_install:
+            - brew install openssl
+      script:
+        - PKG_CONFIG_PATH=/usr/local/opt/openssl/lib/pkgconfig EXTRA_CFLAGS=-Werror ./configure --enable-openssl
+        - make
+        - make runtest
+        - make distclean
+        - mkdir build && cd build
+        - cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DENABLE_OPENSSL=ON ..
+        - make
+        - make test
+
+    # osx build with nss
+    - os: osx
+      env:
+        - TEST="osx nss"
+      before_install:
+            - brew install nss
+      script:
+        - PKG_CONFIG_PATH=/usr/local/opt/nss/lib/pkgconfig EXTRA_CFLAGS=-Werror ./configure --enable-nss
+        - make
+        - make runtest
+
+    # code format check
+    - os: linux
+      env:
+        - TEST="clang-format"
+      addons:
+        apt:
+          packages:
+            - clang-format-3.9
+      script:
+        - CLANG_FORMAT=clang-format-3.9 ./format.sh -d
+
+    # big-endian
+    - os: linux
+      sudo: true
+      env:
+        - TEST="big-endian"
+      services:
+        - docker
+      addons:
+        apt:
+          packages:
+            - qemu-user-static
+            - qemu-system-mips
+      before_install:
+        - sudo docker run --volume $(pwd):/src --workdir /src --name mipsX --tty --detach ubuntu:16.04 tail
+        - sudo docker exec --tty mipsX apt-get update
+        - sudo docker exec --tty mipsX apt-get install build-essential -y
+        - sudo docker exec --tty mipsX apt-get install gcc-mips-linux-gnu -y
+      script:
+        - sudo docker exec --tty mipsX bash -c 'EXTRA_CFLAGS=-static CC=mips-linux-gnu-gcc ./configure --host=mips-linux-gnu'
+        - sudo docker exec --tty mipsX make
+        - sudo docker kill mipsX
+        - file test/srtp_driver
+        - make runtest
+
+    # linux build of fuzzer
+    - os: linux
+      env:
+        - TEST="fuzzer (build only)"
+      addons:
+        apt:
+          packages:
+            - clang
+      script:
+        - CC=clang CXX=clang++ CXXFLAGS="-fsanitize=fuzzer-no-link,address,undefined -g -O3" CFLAGS="-fsanitize=fuzzer-no-link,address,undefined -g -O3" LDFLAGS="-fsanitize=fuzzer-no-link,address,undefined" ./configure
+        - LIBFUZZER="-fsanitize=fuzzer" make srtp-fuzzer
+
+    # coverity scan
+    - os: linux
+      env:
+        - TEST="Coverity Scan"
+      addons:
+        coverity_scan:
+          project:
+            name: "cisco-libSRTP"
+            description: "Build submitted via Travis CI"
+            version: 2
+          notification_email: pabuhler@cisco.com
+          build_command_prepend: "./configure"
+          build_command: "make"
+          branch_pattern: master
+      script:
+        - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+
+    # windows build
+    - os: windows
+      env:
+        - TEST="windows"
+
+      script:
+        - export PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin":$PATH
+        - mkdir build && cd build
+        - cmake -G "Visual Studio 15 2017" ..
+        - msbuild.exe libsrtp2.sln -p:Configuration=Release
+        - msbuild.exe RUN_TESTS.vcxproj -p:Configuration=Release
+        - cd ..
+        - mkdir build_shared && cd build_shared
+        - cmake -G "Visual Studio 15 2017" -DBUILD_SHARED_LIBS=ON ..
+        - msbuild.exe libsrtp2.sln -p:Configuration=Release
+        - msbuild.exe RUN_TESTS.vcxproj -p:Configuration=Release
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..a14ce10
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,37 @@
+cc_library_static {
+    host_supported: true,
+    name: "libsrtp2",
+    srcs: [
+        "crypto/cipher/aes.c",
+        "crypto/cipher/aes_icm.c",
+        "crypto/cipher/cipher.c",
+        "crypto/cipher/null_cipher.c",
+        "crypto/hash/auth.c",
+        "crypto/hash/hmac.c",
+        "crypto/hash/null_auth.c",
+        "crypto/hash/sha1.c",
+        "crypto/kernel/alloc.c",
+        "crypto/kernel/crypto_kernel.c",
+        "crypto/kernel/err.c",
+        "crypto/kernel/key.c",
+        "crypto/math/datatypes.c",
+        "crypto/math/stat.c",
+        "crypto/replay/rdb.c",
+        "crypto/replay/rdbx.c",
+        "crypto/replay/ut_sim.c",
+        "srtp/ekt.c",
+        "srtp/srtp.c",
+    ],
+    local_include_dirs: [
+        "crypto/include",
+        "include",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wno-implicit-function-declaration",
+        "-DHAVE_CONFIG_H",
+    ],
+    export_include_dirs: [
+        "exported_include",
+    ],
+}
diff --git a/CHANGES b/CHANGES
index 949c389..caa2b61 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,223 +1,227 @@
 Changelog
 
-1.3.20
+2.2.0-pre (This version)
 
-  Lots of changes.  Thanks to Jeff Chan for catching a memory leak and
-  helping track down the endian issues with the SSRCs.
+Major changes
 
-1.3.8
+All code has been reformatted to be consistent. A .clang-format file and format.sh script has been added that can be use to verify and enforce consistent formatting. An automated check on code formatting is now part of travis build.
 
-  This is an interim release.  Several little-endian bugs were identified
-  and fixed; this means that we can use intel/linux for development again.
+Other changes
 
-  Cleaned up sha1 and hmac code significantly, got rid of some excess
-  functions and properly documented the fuctions in the .h files.
+PR #409 - Compatibilty with LibreSSL
 
-  Eliminated some vestigial files.
+PR #406 - Fix unprotect when pktlen < (2*mki_size + tag_len)
 
-  There is a SIGBUS error in the AES encrypt function on sparc
-  (observed on both solaris and openbsd) with gcc 2.95.  Was unable to
-  find bad pointer anywhere, so I'm wondering if it isn't a compiler
-  problem (there's a known problem whose profile it fits).  It doesn't
-  appear on any other platform, even in the cipher_driver stress
-  tests.
+PR #405 - Prevent potential double free
 
-  Planned changes
+PR #404 - Add back extern to global variables
 
-  Change interface to nonces (xtd_seq_num_t) so that it uses
-  network byte ordering, and is consistent with other arguments.
+PR #403 - Set gcm IV directly with EVP_CipherInit_ex
 
+PR #401 - Fix memory access issue in srtp_get_session_keys()
 
-1.3.6 
+PR #398 - Fix memory access fixes when invalid profiles where used
 
-  Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to
-  /dev/urandom; the latter is non-blocking on all known platforms (which 
-  corrects some programs that seem to hang) and is actually present on 
-  Open BSD (unlike /dev/random, which only works in the presence of 
-  hardware supported random number generation).
+PR #391 - Return NULL when allocating memory of size zero
 
-  Added machine/types.h case in include/integers.h.
+PR #390 - Bitvector of length zero is not valid
 
-1.3.5
+PR #385 - Treat warnings as errors on travis builds
 
-  Removing srtp_t::template and stream_clone().
+PR #388 - Moved externs from crypto_kernel into its own header
 
-  Adding a new policy structure, which will reflect a complete SRTP
-  policy (including SRTCP).
+PR #379 - Fixed several compiler warnings from Firefox builds
 
-  This version is *incomplete* and will undergo more changes.  It is
-  provided only as a basis for discussion.
+PR #377 - Removed variable init code in rdbx which never gets used
 
-1.3.4
+PR #381 - Added error in case the platform is not detected
 
-   Removed tmmh.c and tmmh.h, which implemented version one of TMMH.
+PR #376 - Add coverity scan to travis builds
 
-   Changed srtp_get_trailer_length() to act on streams rather than
-   sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should
-   usually be used rather than that function.
+PR #374 - Add a big endian build on travis
 
-   Removed 'salt' from cipher input. 
+PR #373 - Fixed buffer size issue in test/srtp_driver.c
 
-   Changed rdbx to use err.h error codes.
+PR #372 - Make rtp_decoder compile on MinGW
 
-   Changed malloc() and free() to xalloc() and xfree; these functions
-   are defined in crypto/kernel/alloc.c and declared in 
-   include/alloc.h.
+PR #367 - Rename configure.in to configure.ac
 
-   Added 'output' functions to cipher, in addition to 'encrypt'
-   functions.  It is no longer necessary to zeroize a buffer before
-   encrypting in order to get keystream.
+PR #365 - Replace calls to free() with srtp_crypto_free()
 
-   Changed octet_string_hex_string() so that "times two" isn't needed
-   in its input.
+PR #364 - Add valgrind to travis and fix leaks in tests
 
-   Added crypto_kernel_init() prior to command-line parsing, so that
-   kernel can be passed command-line arguments, such as "-d
-   debug_module".  This was done to for the applications
-   test/srtp-driver, test/kernel-driver, and test/ust-driver.
+PR #363 - Change smtp_crypto_alloc to initialize memory to zero
+
+PR #354 - Fix potential leak if cloning of stream fails
+
+PR #340 - Fix potential leak in srtp_add_stream()
+
+PR #323 - Fix running test in out of source builds
+
+Issue #316  - Remove VERSION file
+
+2.1.0
+
+Compatibility changes
+
+  PR #253 - Cipher type cleanup for AES
+    When libSRTP is compiled with OpenSSL and the AES 256 ICM cipher is used
+    with RTCP an incorrect initialization vector is formed.
+    This change will break backwards compatibility with older versions (1.5,
+    2.0) of libSRTP when using the AES 256 ICM cipher with OpenSSL for RTCP.
+
+  PR #259 - Sequence number incorrectly masked for AES GCM IV
+    The initialization vector for AES GCM encryption was incorrectly formed on
+    little endian machines.
+    This change will break backwards compatibility with older versions (1.5,
+    2.0) of libSRTP when using the AES GCM cipher for RTCP.
+
+  PR #287 - Fix OOB read in key generation for encrypted headers with GCM ciphers
+    Adds padding of GCM salt to the corresponding ICM length used for header
+    encryption.
+    This change will break backwards compatibility with version 2.0 of libSRTP
+    when using the header encryption extension with the AES GCM cipher.
+
+Major changes
+
+  PR #204 - OpenSSL performance improvements
+    Changed key expansion to occur once per key instead of once per packet.
+
+  PR #209 - Restore AES-192 under BoringSSL
+    BoringSSL supports AES-192 and is now enabled in libSRTP.
+
+  PR #224 - Master Key Identifiers (MKI) Support patch
+    Adds MKI support with up to 4 keys.
+
+  PR #234 - Report SSRC instead of srtp_stream_t in srtp_event_data_t
+    srtp_stream_t is an opaque type making the event framework almost useless.
+    Now the SSRC is returned instead for use as a key in the public API.
+
+  PR #238 - Configure changes and improvements
+    CFLAGS check more shell neutral, quotation fixes, always generate and
+    install pkg-config file, improved OpenSSL discovery and linking, remove
+    -fPIC flag on Windows, fix shared library generation under Cygwin, replace
+    hardcoded CFLAGS with compiler checks, and regenerate configure after
+    configure.in changes.
+
+  PR #241 & PR #261 - Improved logging API to receive log messages from libSRTP
+    Provides a logging API and the ability to enable logging to stdout and a
+    file, as well as a switch to enable all internal debug modules.
+
+  PR #289 - Added support for set and get the roll-over-counter
+    Adds an API to set and get the ROC in an (S)RTP session.
+
+  PR #304 - Fix (S)RTP and (S)RTCP for big endian machines
+    The structures srtp_hdr_t, srtcp_hdr_t and srtcp_trailer_t were defined
+    incorrectly on big endian systems.
+
+Other changes
+
+  PR #149 - Don't create a symlink if there is no $(SHAREDLIBVERSION)
+
+  PR #151 - Make srtp_driver compile for MIPS
+
+  PR #160 - Use PKG_PROG_PKG_CONFIG to find correct pkg-config
+
+  PR #167 - Additional RTCP and SRTCP tests
+
+  PR #169 - Identified merge conflict created by commit 6b71fb9
+
+  PR #173 - Avoid error 'possibly undefined macro: AM_PROG_AR'
 
-   Improved srtp_init_aes_128_prf - wrote key derivation function
-   (srtp_kdf_t).
+  PR #174 - Avoid warning 'The macro AC_TRY_LINK is obsolete.'
 
-   Add the tag_len as an argument to the auth_compute() function, but
-   not the corresponding macro.  This change allows the tag length for
-   a given auth func to be set to different values at initialization
-   time.  Previously, the structure auth_t contained the
-   output_length, but that value was inaccessible from hmac_compute()
-   and other functions.
+  PR #175 - Remove 2nd -fPIC
 
-   Re-named files from a-b.c to a_b.c. in order to help portability.
+  PR #182 - Add a length check before reading packet data
 
-   Re-named rijndael to aes (or aes_128 as appropriate).
+  PR #191 - On debug, output correct endianness of SSRC
 
+  PR #192 - Replace octet_string_is_eq with a constant-time implementation
 
-1.2.1 
+  PR #195 - Add missing __cplusplus header guards
 
-  Changes so that 1.2.0 compiles on cygwin-win2k.
+  PR #198 - Update sha1_driver.c to avoid memory leaks
 
-  Added better error reporting system.  If syslog is present on the
-  OS, then it is used.
+  PR #202 - Add an explicit cast to avoid a printf format warning on macOS
 
+  PR #205 - Update Windows build files to Visual Studio 2015
 
-1.2.0 Many improvements and additions, and a fex fixes
+  PR #207 - Fix to install-win.bat syntax, and add installation of x64 libraries
 
-   Fixed endian issues in RTP header construction in the function
-   rtp_sendto() in srtp/rtp.c.
+  PR #208 - Make replace_cipher and replace_auth public again
 
-   Implemented RIJNDAEL decryption operation, adding the functions
-   rijndael_decrypt() and rijndael_expand_decryption_key().  Also
-   re-named rijndael_expand_key() to rijndael_expand_encryption_key()
-   for consistency.
+  PR #211 - Changes for OpenSSL 1.1.0 compatibility
 
-   Implemented random number source using /dev/random, in the files
-   crypto/rng/rand_source.c and include/rand_source.h.
+  PR #213 - Add cast to `unsigned int` in call to printf in test
 
-   Added index check to SEAL cipher (only values less than 2^32 are
-   allowed)
+  PR #214 - Avoid empty initializer braces
 
-   Added test case for null_auth authentication function.
+  PR #222 - Fix issue: No consistency when use some srtp_* functions
 
-   Added a timing test which tests the effect of CPU cache thrash on
-   cipher throughput.  The test is done by the function
-   cipher_test_throughput_array(); the function
-   cipher_array_alloc_init() creates an array of ciphers for use in
-   this test.  This test can be accessed by using the -a flag to
-   the application cipher-driver in the test subdirectory.
- 
-   Added argument processing to ust-driver.c, and added that app to
-   the 'runtest' target in Makefile.in.
+  PR #231 - Advance version on master in preparation for 2.1 release
 
-   A minor auth_t API change: last argument of auth_init() eliminated.
+  PR #232 - Update Travis, do not build with OpenSSL on OSX
 
+  PR #233 - crypto/replay/rdbx.c: Return type of srtp_index_guess from int to
+    int32_t
 
-1.0.6 A small but important fix
+  PR #236 - test/rtp_decoder.c: Removed superfluous conditional
 
-   Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero()
-   after buffer allocation.
+  PR #237 - test/rtp_decoder.c: spring cleaning
 
-   Eliminated references to no-longer-existing variables in debugging
-   code in srtp/srtp.c.  This fixes the compilation failure that
-   occured when using PRINT_DEBUG in that file.
+  PR #239 - octet_string_set_to_zero() delegates to OPENSSL_cleanse() if
+    available, if not it will use srtp_cleanse() to zero memory
 
-   Corrected spelling of Richard Priestley's name in credits.  Sorry
-   Richard!
+  PR #243 - EKT is not really supported yet, remove from install
 
+  PR #244 - Add simple error checking in timing test to avoid false results
 
-1.0.5 Many little fixes
+  PR #245 - Add missing srtp_cipher_dealloc calls when test fails
 
-   Fixed octet_string_set_to_zero(), which was writing one
-   more zero octet than it should.  This bug caused srtp_protect()
-   and srtp_unprotect() to overwrite the byte that followed the
-   srtp packet.
+  PR #246 - test/rtp_decoder: Add missing conditional
 
-   Changed sizeof(uint32_t) to srtp_get_trailer_length() in
-   srtp-driver.c.  This is just defensive coding.
+  PR #248 - New README.md that integrates intro, credits and references from
+    /doc/ and is used to generate documentation
 
-   Added NULL check to malloc in srtp_alloc().
+  PR #249 - Remove support for generic aesicm from configure.in
 
+  PR #250 - Update README.md, incorrect tag for link
 
-1.0.4 Many minor fixes and two big ones (thanks for the bug reports!)
+  PR #255 - Cleanup outdated comment related to MKI
 
-   Removed 'ssrc' from the srtp_init_aes_128_prf() function argument
-   list.  This is so that applications which do not a priori know the
-   ssrc which they will be receiving can still use libsrtp.  Now the
-   SSRC value is gleaned from the rtp header and exored into the
-   counter mode offset in the srtp_protect() and srtp_unprotect()
-   functions, if that cipher is used.  This change cascaed through
-   many other functions, including srtp_init_from_hex(),
-   srtp_sender_init() and srtp_receiver_init() in rtp.c, and also
-   changing the CLI to test/rtpw.  In the future, another function
-   call will be added to the library that enables multiple ssrc/key
-   pairs to be installed into the same srtp session, so that libsrtp
-   works with multiple srtp senders.  For now, this functionality is
-   lacking.
+  PR #258 - Add AES-GCM to DTLS-SRTP Protection Profiles
 
-   Removed the GDOI interface to the rtpw demo program.  This will be
-   added again at a later date, after the SRTP and GDOI distributions
-   stabilize.  For now, I've left in the GDOI #defines and autoconf
-   definitions so that they'll be in place when needed.
+  PR #263 - Cleaning up and removing duplicated and outdated code
 
-   Updated tmmhv2_compute() so that it didn't assume any particular
-   alginment of the output tag.
+  PR #265 - Introduction of unit test framework: CUTest
 
-   Changed bit field variables in srtp.h to unsigned char from
-   unsigned int in order to avoid a potential endianness issue.
+  PR #267 - crypto/kernel/err.c: Include datatypes.h
 
-   Fixed rdbx_estimate_index() to handle all input cases.  This solves
-   the now notorious "abaft" bug in the rtpw demo app on linux/intel,
-   in which spurious replay protection failures happen after that word
-   is received.
+  PR #272 - Reduce literal constants
 
-   Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed
-   from rijndael_icm_set_segment().
+  PR #273 - SRTP AEAD SRTCP initialization vector regression tests
 
-   Added error checking and handling to srtp_sender_init() and
-   srtp_receiver_init().
+  PR #274 - Update Travis build - add ccache
 
-   Changed srtp_alloc() so that it does what you'd expect: allocate an
-   srtp_ctx_t structure.  This hides the library internals.
+  PR #276 - Reference and docs updates
 
+  PR #278 - Removed crypto/test/auth_driver.c and test/lfsr.c
 
-1.0.1   Many minor fixes
+  PR #279 - Bump copyright year
 
-   Added cipher_driver_buffer_test(...) to test/cipher-driver.c.  This
-   function checks that the byte-buffering functions used by a cipher
-   are correct.
+  PR #283 - Add missing docs in srtp.h
 
-   Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and
-   changed index_t to xtd_seq_num_t (see include/rdbx.h).
+  PR #284 - Add strict-prototypes warning if supported
 
-   Fixed SEAL3.0 output byte buffering, added byte-buffering test to
-   cipher/cipher-driver.c.
+  PR #291 - Use const char * for srtp_set_debug_module()
 
-   Fixed roc-driver so that the non-sequential insertion test
-   automatically recovers from bad estimates.  This was required to
-   prevent spurious failures.
+  PR #294 - Fix incorrect result of rdb_increment on overflow
 
-   Made rdbx_estimate_index(...) function smarter, so that initial RTP
-   sequence numbers greater than 32,768 don't cause it to estimate the
-   rollover counter of 0xffffffff.
+  PR #300 - Standalone tests
 
+  PR #301 - Configure fixes
 
-1.0.0   Initial release
+  PR #302 - Fix warning regarding unused variable
 
+  PR #303 - Makefile.in: Add gnu as match for shared lib suffix
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..0293892
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,200 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(libsrtp2 LANGUAGES C)
+
+set(PACKAGE_VERSION 2.3.0)
+set(PACKAGE_STRING "${CMAKE_PROJECT_NAME} ${PACKAGE_VERSION}")
+
+include(TestBigEndian)
+include(CheckIncludeFile)
+include(CheckFunctionExists)
+include(CheckTypeSize)
+include(CheckCSourceCompiles)
+
+test_big_endian(WORDS_BIGENDIAN)
+
+check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
+check_include_file(byteswap.h HAVE_BYTESWAP_H)
+check_include_file(inttypes.h HAVE_INTTYPES_H)
+check_include_file(machine/types.h HAVE_MACHINE_TYPES_H)
+check_include_file(netinet/in.h HAVE_NETINET_IN_H)
+check_include_file(stdint.h HAVE_STDINT_H)
+check_include_file(stdlib.h HAVE_STDLIB_H)
+check_include_file(sys/int_types.h HAVE_SYS_INT_TYPES_H)
+check_include_file(sys/socket.h HAVE_SYS_SOCKET_H)
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(unistd.h HAVE_UNISTD_H)
+check_include_file(windows.h HAVE_WINDOWS_H)
+check_include_file(winsock2.h HAVE_WINSOCK2_H)
+
+check_function_exists(sigaction HAVE_SIGACTION)
+check_function_exists(inet_aton HAVE_INET_ATON)
+check_function_exists(usleep HAVE_USLEEP)
+
+check_type_size(uint8_t UINT8_T)
+check_type_size(uint16_t UINT16_T)
+check_type_size(uint32_t UINT32_T)
+check_type_size(uint64_t UINT64_T)
+check_type_size(int32_t INT32_T)
+check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG)
+check_type_size("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG)
+
+check_c_source_compiles("inline void func(); void func() { } int main() { func(); return 0; }" HAVE_INLINE)
+if(NOT HAVE_INLINE)
+  check_c_source_compiles("__inline void func(); void func() { } int main() { func(); return 0; }" HAVE___INLINE)
+endif()
+
+set(ENABLE_DEBUG_LOGGING OFF CACHE BOOL "Enable debug logging in all modules")
+set(ERR_REPORTING_STDOUT OFF CACHE BOOL "Enable logging to stdout")
+set(ERR_REPORTING_FILE "" CACHE FILEPATH "Use file for logging")
+set(ENABLE_OPENSSL OFF CACHE BOOL "Enable OpenSSL crypto engine")
+set(TEST_APPS ON CACHE BOOL "Build test applications")
+option(BUILD_SHARED_LIBS "Build shared library" OFF)
+
+if(ENABLE_OPENSSL)
+  find_package(OpenSSL REQUIRED)
+  include_directories(${OPENSSL_INCLUDE_DIR})
+endif()
+set(OPENSSL ${ENABLE_OPENSSL} CACHE BOOL INTERNAL)
+set(GCM ${ENABLE_OPENSSL} CACHE BOOL INTERNAL)
+
+set(CONFIG_FILE_DIR ${CMAKE_CURRENT_BINARY_DIR})
+include_directories(${CONFIG_FILE_DIR})
+
+configure_file(config_in_cmake.h ${CONFIG_FILE_DIR}/config.h)
+add_definitions(-DHAVE_CONFIG_H)
+
+set(SOURCES_C
+  srtp/ekt.c
+  srtp/srtp.c
+)
+
+set(CIPHERS_SOURCES_C
+  crypto/cipher/cipher.c
+  crypto/cipher/null_cipher.c
+)
+
+if(ENABLE_OPENSSL)
+  list(APPEND CIPHERS_SOURCES_C
+    crypto/cipher/aes_icm_ossl.c
+    crypto/cipher/aes_gcm_ossl.c
+  )
+else()
+  list(APPEND  CIPHERS_SOURCES_C
+    crypto/cipher/aes.c
+    crypto/cipher/aes_icm.c
+  )
+endif()
+
+set(HASHES_SOURCES_C
+    crypto/hash/auth.c
+    crypto/hash/null_auth.c
+)
+
+if(ENABLE_OPENSSL)
+  list(APPEND HASHES_SOURCES_C
+    crypto/hash/hmac_ossl.c
+  )
+else()
+  list(APPEND  HASHES_SOURCES_C
+    crypto/hash/hmac.c
+    crypto/hash/sha1.c
+  )
+endif()
+
+set(KERNEL_SOURCES_C
+  crypto/kernel/alloc.c
+  crypto/kernel/crypto_kernel.c
+  crypto/kernel/err.c
+  crypto/kernel/key.c
+)
+
+set(MATH_SOURCES_C
+  crypto/math/datatypes.c
+  crypto/math/stat.c
+)
+
+set(REPLAY_SOURCES_C
+  crypto/replay/rdb.c
+  crypto/replay/rdbx.c
+  crypto/replay/ut_sim.c
+)
+
+set(SOURCES_H
+  crypto/include/aes.h
+  crypto/include/aes_icm.h
+  crypto/include/alloc.h
+  crypto/include/auth.h
+  crypto/include/cipher.h
+  crypto/include/cipher_types.h
+  crypto/include/crypto_kernel.h
+  crypto/include/crypto_types.h
+  crypto/include/datatypes.h
+  crypto/include/err.h
+  crypto/include/hmac.h
+  crypto/include/integers.h
+  crypto/include/key.h
+  crypto/include/null_auth.h
+  crypto/include/null_cipher.h
+  crypto/include/rdb.h
+  crypto/include/rdbx.h
+  crypto/include/sha1.h
+  crypto/include/stat.h
+  include/srtp.h
+  include/srtp_priv.h
+  include/ut_sim.h
+  ${CONFIG_FILE_DIR}/config.h
+)
+
+if(BUILD_SHARED_LIBS AND WIN32)
+  list(APPEND SOURCES_C
+    srtp.def
+  )
+endif()
+
+source_group("src" FILES ${SOURCES_C})
+source_group("src\\Ciphers" FILES ${CIPHERS_SOURCES_C})
+source_group("src\\Hashes" FILES ${HASHES_SOURCES_C})
+source_group("src\\Kernel" FILES ${KERNEL_SOURCES_C})
+source_group("src\\Math" FILES ${MATH_SOURCES_C})
+source_group("src\\Replay" FILES ${REPLAY_SOURCES_C})
+source_group("include" FILES ${SOURCES_H})
+
+add_library(srtp2
+  ${SOURCES_C}
+  ${CIPHERS_SOURCES_C}
+  ${HASHES_SOURCES_C}
+  ${KERNEL_SOURCES_C}
+  ${MATH_SOURCES_C}
+  ${REPLAY_SOURCES_C}
+  ${SOURCES_H}
+)
+
+target_include_directories(srtp2 PUBLIC crypto/include include)
+if(ENABLE_OPENSSL)
+  target_link_libraries(srtp2 OpenSSL::Crypto)
+endif()
+if(WIN32)
+  target_link_libraries(srtp2 ws2_32)
+endif()
+
+install(TARGETS srtp2 DESTINATION lib)
+install(FILES include/srtp.h crypto/include/auth.h
+  crypto/include/cipher.h
+  crypto/include/cipher_types.h
+  DESTINATION include/srtp2)
+
+if(TEST_APPS)
+  enable_testing()
+
+if(NOT (BUILD_SHARED_LIBS AND WIN32))
+  add_executable(test_srtp test/test_srtp.c)
+  target_link_libraries(test_srtp srtp2)
+  add_test(test_srtp test_srtp)
+endif()
+
+  add_executable(srtp_driver test/srtp_driver.c
+    test/util.c test/getopt_s.c)
+  target_link_libraries(srtp_driver srtp2)
+  add_test(srtp_driver srtp_driver -v)
+endif()
diff --git a/LICENSE b/LICENSE
index 02ca507..af0a2ac 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 /*
  *	
- * Copyright (c) 2001-2003 Cisco Systems, Inc.
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
diff --git a/Makefile.in b/Makefile.in
index fc041e0..6a9eb9b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,119 +1,242 @@
-# Makefile for secure rtp 
+# Makefile for secure rtp
 #
 # David A. McGrew
 # Cisco Systems, Inc.
 
 # targets:
 #
-# runtest       runs test applications 
+# runtest       runs test applications
+# runtest-valgrind runs test applications with valgrind
 # test		builds test applications
-# libcrypt.a	static library implementing crypto engine
-# libsrtp.a	static library implementing srtp
+# libsrtp2.a	static library implementing srtp
+# libsrtp2.so	shared library implementing srtp
 # clean		removes objects, libs, and executables
-# distribution	cleans and builds a .tgz
-# tags		builds etags file from all .c and .h files
+# distribution  cleans and builds a .tgz
+# tags          builds etags file from all .c and .h files
 
-.PHONY: test all runtest
+DYNAMIC_PATH_VAR = @DYNAMIC_PATH_VAR@
+CRYPTO_LIBDIR = @CRYPTO_LIBDIR@
+USE_EXTERNAL_CRYPTO = @USE_EXTERNAL_CRYPTO@
+HAVE_PCAP = @HAVE_PCAP@
+
+# Specify how tests should find shared libraries on macOS and Linux
+#
+# macOS purges DYLD_LIBRARY_PATH when spawning subprocesses, so it's
+# not possible to pass this in from the outside; we have to specify
+# it for any subprocesses we call. No support for dynamic linked
+# tests on Windows.
+ifneq ($(strip $(CRYPTO_LIBDIR)),)
+	ifneq ($(OS),Windows_NT)
+		UNAME_S = $(shell uname -s)
+		ifeq ($(UNAME_S),Linux)
+			FIND_LIBRARIES = LD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+		endif
+		ifeq ($(UNAME_S),Darwin)
+			FIND_LIBRARIES = DYLD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+		endif
+		CRYPTO_LIBDIR_FORWARD = CRYPTO_LIBDIR=$(CRYPTO_LIBDIR)
+	endif
+endif
+
+.PHONY: all shared_library test
+
+all: test
 
 runtest: test
-	@echo "running libsrtp test applications..."
-	test/cipher_driver$(EXE) -v >/dev/null
-	test/rdbx_driver$(EXE) -v >/dev/null
-	test/srtp_driver$(EXE) -v >/dev/null
-	test/roc_driver$(EXE) -v >/dev/null
-	test/kernel_driver$(EXE) -v >/dev/null
-	@echo "libsrtp test applications passed."
+	@echo "running libsrtp2 test applications..."
+	$(FIND_LIBRARIES) crypto/test/cipher_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) crypto/test/kernel_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/test_srtp$(EXE) >/dev/null
+	$(FIND_LIBRARIES) test/rdbx_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/srtp_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/roc_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/replay_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/dtls_srtp_driver$(EXE) >/dev/null
+	cd test; $(CRYPTO_LIBDIR_FORWARD) $(abspath $(srcdir))/test/rtpw_test.sh -w $(abspath $(srcdir))/test/words.txt >/dev/null
+ifeq (1, $(USE_EXTERNAL_CRYPTO))
+	cd test; $(CRYPTO_LIBDIR_FORWARD) $(abspath $(srcdir))/test/rtpw_test_gcm.sh -w $(abspath $(srcdir))/test/words.txt >/dev/null
+endif
+	@echo "libsrtp2 test applications passed."
+	$(MAKE) -C crypto runtest
 
-all: test tables
+runtest-valgrind: test
+	@echo "running libsrtp2 test applications... (valgrind)"
+	valgrind --error-exitcode=1 --leak-check=full test/test_srtp$(EXE) -v >/dev/null
+	valgrind --error-exitcode=1 --leak-check=full test/srtp_driver$(EXE) -v >/dev/null
+	@echo "libsrtp2 test applications passed. (valgrind)"
 
 # makefile variables
 
-CC     = @CC@
-CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops
-CDEFS  = -DHAVE_CONFIG_H
-INCDIR = -I./include/ -I./crypto/include
-LIBS   = @LIBS@ -lsrtp 
-LIBDIR = -L.
+CC	= @CC@
+CXX	= @CXX@
+INCDIR	= -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include
+DEFS	= @DEFS@
+CPPFLAGS= @CPPFLAGS@
+CFLAGS	= @CFLAGS@
+CXXFLAGS= @CXXFLAGS@
+srtp-fuzzer: CFLAGS += -g
+srtp-fuzzer: CXXFLAGS += -g
+LIBS	= @LIBS@
+LDFLAGS	= -L. @LDFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
+SRTPLIB	= -lsrtp2
+PCAP_LIB = @PCAP_LIB@
 
+AR      = @AR@
+RANLIB	= @RANLIB@
+INSTALL	= @INSTALL@
+
+# EXE defines the suffix on executables - it's .exe for Windows, and
+# null on linux, bsd, and OS X and other OSes.
+EXE	= @EXE@
+
+HMAC_OBJS = @HMAC_OBJS@
+AES_ICM_OBJS = @AES_ICM_OBJS@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+includedir = @includedir@
+libdir = @libdir@
+bindir = @bindir@
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsrtp2.pc
+
+SHAREDLIBVERSION = 1
+ifneq (,$(or $(findstring linux,@host@), $(findstring gnu,@host@)))
+SHAREDLIB_DIR = $(libdir)
+SHAREDLIB_LDFLAGS = -shared -Wl,-soname,$@
+SHAREDLIBSUFFIXNOVER = so
+SHAREDLIBSUFFIX = $(SHAREDLIBSUFFIXNOVER).$(SHAREDLIBVERSION)
+else ifneq (,$(or $(findstring cygwin,@host@), $(findstring mingw,@host@)))
+SHAREDLIB_DIR = $(bindir)
+SHAREDLIB_LDFLAGS = -shared -Wl,--out-implib,libsrtp2.dll.a
+SHAREDLIBVERSION =
+SHAREDLIBSUFFIXNOVER = dll
+SHAREDLIBSUFFIX = $(SHAREDLIBSUFFIXNOVER)
+else ifeq (darwin,$(findstring darwin,@host@))
+SHAREDLIB_DIR = $(libdir)
+SHAREDLIB_LDFLAGS = -dynamiclib -twolevel_namespace -undefined dynamic_lookup \
+		-fno-common -headerpad_max_install_names -install_name $(libdir)/$@
+SHAREDLIBSUFFIXNOVER = dylib
+SHAREDLIBSUFFIX = $(SHAREDLIBVERSION).$(SHAREDLIBSUFFIXNOVER)
+endif
 
 # implicit rules for object files and test apps
 
 %.o: %.c
-	$(CC) $(CDEFS) -c $(CFLAGS) $(INCDIR) $< -o $@
+	$(COMPILE) -c $< -o $@
 
-%: %.c libsrtp.a 
-	$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ $(LIBDIR) $(LIBS)
-
-
-# libcrypt.a (the crypto engine) 
+%$(EXE): %.c
+	$(COMPILE) $(LDFLAGS) $< -o $@ $(SRTPLIB) $(LIBS)
 
 ciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o      \
-          crypto/cipher/aes.o crypto/cipher/aes_icm.o             \
-          crypto/cipher/aes_cbc.o
+		  $(AES_ICM_OBJS)
 
-hashes  = crypto/hash/null_auth.o crypto/hash/sha1.o \
-          crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o 
+hashes  = crypto/hash/null_auth.o  crypto/hash/auth.o            \
+	  $(HMAC_OBJS)
 
 replay  = crypto/replay/rdb.o crypto/replay/rdbx.o               \
-          crypto/replay/ut_sim.o 
+		  crypto/replay/ut_sim.o
 
 math    = crypto/math/datatypes.o crypto/math/stat.o
 
-ust     = crypto/ust/ust.o 
-
-rng     = crypto/rng/rand_source.o crypto/rng/prng.o crypto/rng/ctr_prng.o
+ust     = crypto/ust/ust.o
 
 err     = crypto/kernel/err.o
 
 kernel  = crypto/kernel/crypto_kernel.o  crypto/kernel/alloc.o   \
-          crypto/kernel/key.o $(rng) $(err) # $(ust) 
+		  crypto/kernel/key.o $(err) # $(ust)
 
-cryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay)
+cryptobj =  $(ciphers) $(hashes) $(math) $(kernel) $(replay)
 
-aesicmobj = $(aesicm)  $(rng)
+# libsrtp2.a (implements srtp processing)
 
-# gdoi is the group domain of interpretation for isakmp, a group key
-# management system which can provide keys for srtp
+srtpobj = srtp/srtp.o srtp/ekt.o
 
-gdoi	= @GDOI_OBJS@
+libsrtp2.a: $(srtpobj) $(cryptobj) $(gdoi)
+	$(AR) cr libsrtp2.a $^
+	$(RANLIB) libsrtp2.a
 
-# libsrtp.a (implements srtp processing)
+libsrtp2.$(SHAREDLIBSUFFIX): $(srtpobj) $(cryptobj) $(gdoi)
+	$(CC) -shared -o $@ $(SHAREDLIB_LDFLAGS) \
+				$^ $(LDFLAGS) $(LIBS)
+	if [ -n "$(SHAREDLIBVERSION)" ]; then \
+		ln -sfn $@ libsrtp2.$(SHAREDLIBSUFFIXNOVER); \
+	fi
 
-srtpobj = srtp/srtp.o 
+shared_library: libsrtp2.$(SHAREDLIBSUFFIX)
 
-libsrtp.a: $(srtpobj) $(cryptobj) $(gdoi)
-	ar cr libsrtp.a $(srtpobj) $(cryptobj) $(gdoi)
-	ranlib libsrtp.a
+libsrtp2.so: $(srtpobj) $(cryptobj)
+	$(CC) -shared -Wl,-soname,libsrtp2.so \
+		-o libsrtp2.so $^ $(LDFLAGS)
 
-# libaesicm.a provides an icm implementation used by mpeg4ip
+# test applications
+ifneq (1, $(USE_EXTERNAL_CRYPTO))
+AES_CALC = crypto/test/aes_calc$(EXE)
+endif
 
-libaesicm.a: $(aesicmobj)
-	ar cr libaesicm.a $(aesicmobj)
-	ranlib libaesicm.a
+crypto_testapp = $(AES_CALC) crypto/test/cipher_driver$(EXE) \
+	crypto/test/datatypes_driver$(EXE) crypto/test/kernel_driver$(EXE) \
+	crypto/test/sha1_driver$(EXE) crypto/test/stat_driver$(EXE) \
+	crypto/test/env$(EXE)
 
-# libcryptomath.a contains general-purpose routines that are used to
-# generate tables and verify cryptoalgorithm implementations - this
-# library is not meant to be included in production code
+testapp = $(crypto_testapp) test/srtp_driver$(EXE) test/replay_driver$(EXE) \
+	  test/roc_driver$(EXE) test/rdbx_driver$(EXE) test/rtpw$(EXE) \
+	  test/dtls_srtp_driver$(EXE) test/test_srtp$(EXE)
 
-cryptomath = crypto/math/math.o crypto/math/gf2_8.o crypto/math/gf2_128.o
+ifeq (1, $(HAVE_PCAP))
+testapp += test/rtp_decoder$(EXE)
+endif
 
-libcryptomath.a: $(cryptomath)
-	ar cr libcryptomath.a $(cryptomath)
-	ranlib libcryptomath.a
+$(testapp): libsrtp2.a
 
+test/rtpw$(EXE): test/rtpw.c test/rtp.c test/util.c test/getopt_s.c \
+		crypto/math/datatypes.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
 
-# test applications 
+ifeq (1, $(HAVE_PCAP))
+test/rtp_decoder$(EXE): test/rtp_decoder.c test/rtp.c test/util.c test/getopt_s.c \
+		crypto/math/datatypes.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(PCAP_LIB) $(LIBS) $(SRTPLIB)
+endif
 
-testapp = test/cipher_driver test/datatypes_driver test/srtp_driver \
-          test/replay_driver test/roc_driver test/rdbx_driver       \
-          test/stat_driver test/sha1_driver test/kernel_driver      \
-          test/aes_calc test/rand_gen # test/ust_driver @GDOI_APPS@
-#          test/auth_driver test/rtpw                 \
+crypto/test/aes_calc$(EXE): crypto/test/aes_calc.c test/util.c
+	$(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
 
-test/rtpw: test/rtpw.c test/rtp.c
-	$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) -o test/rtpw test/rtpw.c test/rtp.c $(LIBDIR) $(LIBS)
+test/test_srtp$(EXE): test/test_srtp.c
+	$(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+crypto/test/datatypes_driver$(EXE): crypto/test/datatypes_driver.c test/util.c
+	$(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+crypto/test/sha1_driver$(EXE): crypto/test/sha1_driver.c test/util.c
+	$(COMPILE) -I$(srcdir)/test $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+test/srtp_driver$(EXE): test/srtp_driver.c test/util.c test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+test/rdbx_driver$(EXE): test/rdbx_driver.c test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+test/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c test/util.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+crypto/test/cipher_driver$(EXE): crypto/test/cipher_driver.c test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+crypto/test/kernel_driver$(EXE): crypto/test/kernel_driver.c test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
+
+crypto/test/env$(EXE): crypto/test/env.c test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
 
 test: $(testapp)
+	@echo "Build done. Please run '$(MAKE) runtest' to run self tests."
 
 memtest: test/srtp_driver
 	@test/srtp_driver -v -d "alloc" > tmp
@@ -124,17 +247,6 @@
 	@echo "passed (same number of alloc() and dealloc() calls found)"
 	@rm freed allocated tmp
 
-# tables_apps are used to generate the tables used in the crypto
-# implementations; these need only be generated during porting, not
-# for building libsrtp or the test applications
-
-table_apps = tables/aes_tables tables/gf_128_tables
-
-# in the tables/ subdirectory, we use libcryptomath instead of libsrtp
-
-tables/%: tables/%.c libcryptomath.a 
-	$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ $(LIBDIR) libcryptomath.a
-
 # the target 'plot' runs the timing test (test/srtp_driver -t) then
 # uses gnuplot to produce plots of the results - see the script file
 # 'timing'
@@ -146,65 +258,74 @@
 # bookkeeping: tags, clean, and distribution
 
 tags:
-	etags */*.[ch] */*/*.[ch] 
+	etags */*.[ch] */*/*.[ch]
 
 
-# documentation - the target libsrtpdoc builds a PDF file documenting
-# libsrtp
+# documentation - the target libsrtp2doc builds html documentation
 
-libsrtpdoc:
-	cd doc; make
+libsrtp2doc:
+	$(MAKE) -C doc
 
-# EXE defines the suffix on executables - it's .exe for cygwin, and
-# null on linux, bsd, and OS X and other OSes.  we define this so that
-# `make clean` will work on the cygwin platform
+# fuzzer
 
-EXE = @EXE@
+srtp-fuzzer: libsrtp2.a
+	$(MAKE) -C fuzzer
 
-.PHONY: clean superclean install
+.PHONY: clean superclean distclean install
 
 install:
-	if [ -d /usr/local/include/srtp ]; then \
-	   echo "you should run 'make uninstall' first"; exit 1;  \
+	$(INSTALL) -d $(DESTDIR)$(includedir)/srtp2
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	cp $(srcdir)/include/srtp.h $(DESTDIR)$(includedir)/srtp2
+	cp $(srcdir)/crypto/include/cipher.h $(DESTDIR)$(includedir)/srtp2
+	cp $(srcdir)/crypto/include/auth.h $(DESTDIR)$(includedir)/srtp2
+	cp $(srcdir)/crypto/include/crypto_types.h $(DESTDIR)$(includedir)/srtp2
+	if [ -f libsrtp2.a ]; then cp libsrtp2.a $(DESTDIR)$(libdir)/; fi
+	if [ -f libsrtp2.dll.a ]; then cp libsrtp2.dll.a $(DESTDIR)$(libdir)/; fi
+	if [ -f libsrtp2.$(SHAREDLIBSUFFIX) ]; then \
+		$(INSTALL) -d $(DESTDIR)$(SHAREDLIB_DIR); \
+		cp libsrtp2.$(SHAREDLIBSUFFIX) $(DESTDIR)$(SHAREDLIB_DIR)/; \
+		cp libsrtp2.$(SHAREDLIBSUFFIXNOVER) $(DESTDIR)$(SHAREDLIB_DIR)/; \
+		if [ -n "$(SHAREDLIBVERSION)" ]; then \
+			ln -sfn libsrtp2.$(SHAREDLIBSUFFIX) $(DESTDIR)$(SHAREDLIB_DIR)/libsrtp2.$(SHAREDLIBSUFFIXNOVER); \
+		fi; \
 	fi
-	mkdir /usr/local/include/srtp
-	cp include/*.h /usr/local/include/srtp  
-	cp crypto/include/*.h /usr/local/include/srtp
-	cp libsrtp.a /usr/local/lib/
-	if [ -f libaesicm.a ]; then cp libaesicm.a /usr/local/lib/; fi 
+	$(INSTALL) -d $(DESTDIR)$(pkgconfigdir)
+	cp $(top_builddir)/$(pkgconfig_DATA) $(DESTDIR)$(pkgconfigdir)/
 
 uninstall:
-	rm -rf /usr/local/include/srtp
-	rm -rf /usr/local/lib/libsrtp.a
-	if [ -f libaesicm.a ]; then rm -rf /usr/local/lib/libaesicm.a; fi
+	rm -f $(DESTDIR)$(includedir)/srtp2/*.h
+	rm -f $(DESTDIR)$(libdir)/libsrtp2.*
+	-rmdir $(DESTDIR)$(includedir)/srtp2
+	rm -f $(DESTDIR)$(pkgconfigdir)/$(pkgconfig_DATA)
 
 clean:
-	rm -rf $(cryptobj) $(srtpobj) $(cryptomath) $(table_apps) TAGS \
-        libcryptomath.a libsrtp.a libaesicm.a core *.core test/core
+	rm -rf $(cryptobj) $(srtpobj) TAGS \
+		libsrtp2.a libsrtp2.so libsrtp2.dll.a core *.core test/core
 	for a in * */* */*/*; do			\
-              if [ -f "$$a~" ] ; then rm -f $$a~; fi;	\
-        done;
-	for a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done
-	rm -rf *.pict *.jpg *.dat 
+			  if [ -f "$$a~" ] ; then rm -f $$a~; fi;	\
+		done;
+	for a in $(testapp); do rm -rf $$a$(EXE); done
+	rm -rf *.pict *.jpg *.dat
 	rm -rf freed allocated tmp
-	cd doc; make clean
-	cd crypto; make clean
-
+	$(MAKE) -C doc clean
+	$(MAKE) -C fuzzer clean
 
 superclean: clean
-	rm -rf include/config.h config.log config.cache config.status \
-               Makefile .gdb_history test/.gdb_history .DS_Store
+	rm -rf crypto/include/config.h config.log config.cache config.status \
+			   Makefile crypto/Makefile doc/Makefile \
+			   .gdb_history test/.gdb_history .DS_Store
 	rm -rf autom4te.cache
 
-distname = srtp-$(shell cat VERSION)
+distclean: superclean
 
-distribution: superclean
+distname = libsrtp-$(shell cat VERSION)
+
+distribution: runtest superclean
 	if ! [ -f VERSION ]; then exit 1; fi
 	if [ -f ../$(distname).tgz ]; then               \
-           mv ../$(distname).tgz ../$(distname).tgz.bak; \
-        fi
-	cd ..; tar cvzf $(distname).tgz srtp
+		   mv ../$(distname).tgz ../$(distname).tgz.bak; \
+		fi
+	cd ..; tar cvzf $(distname).tgz libsrtp
 
-# EOF 
-
-
+# EOF
diff --git a/README b/README
deleted file mode 100644
index 66c8f3f..0000000
--- a/README
+++ /dev/null
@@ -1,171 +0,0 @@
-Secure RTP (SRTP) and UST Reference Implementations
-David A. McGrew
-Cisco Systems, Inc.
-mcgrew@cisco.com
-
-
-This package provides an implementation of the Secure Real-time
-Transport Protocol (SRTP), the Universal Security Transform (UST), and
-a supporting cryptographic kernel.  These mechanisms are documented in
-the Internet Drafts in the doc/ subdirectory.  The SRTP API is
-documented in include/srtp.h, and the library is in libsrtp.a (after
-compilation).
-
-
-Installation:
-
-./configure [ options ]       # GNU autoconf script 
-make                          # or gmake if needed; use GNU make
-
-The configure script accepts the following options:
-
-   --help              provides a usage summary
-   --disable-debug     compile without the runtime debugging system
-   --enable-syslog     use syslog for error reporting
-   --disable-stdout    use stdout for error reporting
-   --enable-console    use /dev/console for error reporting
-   --gdoi              use GDOI key management (disabled at present)
-
-By default, debbuging is enabled and stdout is used for debugging.
-You can use the above configure options to have the debugging output
-sent to syslog or the system console.  Alternatively, you can define
-ERR_REPORTING_FILE in include/conf.h to be any other file that can be
-opened by libSRTP, and debug messages will be sent to it.  
-
-This package has been tested on Mac OS X (powerpc-apple-darwin1.4),
-Cygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6).  Previous
-versions have been tested on Linux and OpenBSD on both x86 and sparc
-platforms.
-
-A quick tour of this package:
-
-Makefile		targets: all, clean, ...
-README			this file
-CHANGES                 change log 
-VERSION			version number of this package
-LICENSE                 legal details (it's a BSD-like license)
-crypto/ciphers/		ciphers (null, aes_icm, ...)
-crypto/math/		crypto math routines
-crypto/hash/            crypto hashing (hmac, tmmhv2, ...)
-crypto/replay/		replay protection
-doc/			documentation: rfcs, apis, and suchlike
-include/		include files for all code in distribution
-srtp/			secure real-time transport protocol implementation
-tables/                 apps for generating tables (useful in porting)
-test/			test drivers 
-
-
-Applications
-
-  Several test drivers and a simple and portable srtp application
-  are included in the test/ subdirectory.
-
-  test driver	function tested	
-  -------------------------------------------------------------
-  kernel_driver crypto kernel (ciphers, auth funcs, rng)
-  srtp_driver	srtp in-memory tests (does not use the network)
-  rdbx_driver	rdbx (extended replay database)
-  roc_driver	extended sequence number functions 
-  replay_driver	replay database (n.b. not used in libsrtp)
-  cipher_driver	ciphers 
-  auth_driver	hash functions 
-
-  The app rtpw is a simple rtp application which reads words from
-  /usr/dict/words and then sends them out one at a time using [s]rtp.
-  Manual srtp keying uses the -k option; automated key management
-  using gdoi will be added later.
-
-usage: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port
-or     rtpw -l
-
-  Either the -s (sender) or -r (receiver) option must be chosen.
-
-  The values dest_ip, dest_port are the ip address and udp port to
-  which the dictionary will be sent, respectively.  
-
-  options:
-
-  -s		(s)rtp sender - causes app to send words
-
-  -r		(s)rtp receive - causes app to receve words
-
-  -k <key>      use srtp master key <key>, where the
-		key is a hexadecimal value (without the
-                leading "0x")
-
-  -e            encrypt/decrypt (for data confidentiality)
-                (requires use of -k option as well)
-
-  -a            message authentication 
-                (requires use of -k option as well)
-
-  -l            list debug modules
-
-  -d <debug>    turn on debugging for module <debug>
-
-
-In order to get random 30-byte values for use as key/salt pairs , you
-can use the following bash function to format the output of
-/dev/random (where that device is available).
-
-function randhex() {
-   cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
-}
-
-
-An example of an SRTP session using two rtpw programs follows:
-
-set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
-
-[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 
-Security services: confidentiality message authentication
-set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
-setting SSRC to 2078917053
-sending word: A
-sending word: a
-sending word: aa
-sending word: aal
-...
-
-[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 
-security services: confidentiality message authentication
-set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
-19 octets received from SSRC 2078917053 word: A
-19 octets received from SSRC 2078917053 word: a
-20 octets received from SSRC 2078917053 word: aa
-21 octets received from SSRC 2078917053 word: aal
-...
-
-Implementation Notes
-
-  * The srtp_protect() function assumes that the buffer holding the
-    rtp packet has enough storage allocated that the authentication 
-    tag can be written to the end of that packet.  If this assumption
-    is not valid, memory corruption will ensue.  
-
-  * Automated tests for the crypto functions are provided through
-    the cipher_type_self_test() and auth_type_self_test() functions.
-    These functions should be used to test each port of this code 
-    to a new platform.
-
-  * Replay protection is contained in the crypto engine, and
-    tests for it are provided.
-
-  * This implementation provides calls to initialize, protect, and
-    unprotect RTP packets, and makes as few as possible assumptions
-    about how these functions will be called.  For example, the
-    caller is not expected to provide packets in order (though if
-    they're called more than 65k out of sequence, synchronization
-    will be lost).
-    
-  * The sequence number in the rtp packet is used as the low 16 bits
-    of the sender's local packet index. Note that RTP will start its
-    sequence number in a random place, and the SRTP layer just jumps
-    forward to that number at its first invocation.  An earlier
-    version of this library used initial sequence numbers that are
-    less than 32,768; this trick is no longer required as the
-    rdbx_estimate_index(...) function has been made smarter.
-
-  * The replay window is 128 bits in length, and is hard-coded to this
-    value for now.  
-
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..721a066
--- /dev/null
+++ b/README.md
@@ -0,0 +1,508 @@
+[![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-us"></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-us)
+  - [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)
+  - [Using Visual Studio](#using-visual-studio)
+- [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` structure contains two `srtp_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 `srtp_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
+`srtp_crypto_policy_t` structure can be initialized by using either the
+`srtp_crypto_policy_set_rtp_default()` or `srtp_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="using-visual-studio"></a>
+## Using Visual Studio
+
+On Windows one can use Visual Studio via CMake. CMake can be downloaded here:
+https://cmake.org/ . To create Visual Studio build files, for example run the
+following commands:
+
+```
+# Create build subdirectory
+mkdir build
+cd build
+
+# Make project files
+cmake .. -G "Visual Studio 15 2017"
+
+# Or for 64 bit project files
+cmake .. -G "Visual Studio 15 2017 Win64"
+```
+
+--------------------------------------------------------------------------------
+
+<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
+srtp_crypto_policy_set_rtp_default(&policy.rtp);
+srtp_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)
diff --git a/TODO b/TODO
deleted file mode 100644
index 4fe470a..0000000
--- a/TODO
+++ /dev/null
@@ -1,66 +0,0 @@
-TODO List
-
-  - add tests for key_limit_t datatype 
-
-  - move octet_get_weight() from datatypes.c to math.c (any other
-    funcs?)
-
-Changes and additions planned
-
-  Make cipher and auth dealloc() functions zeroize the key-storage
-  areas before calling free().
-
-  Fix UST
-    - implement scatter/gather API
-    - SRTP using UST
-    - possibly add legacy SHA1 usage
-
-  Eliminate key_len from auth_init()
-
-  Doucument internal APIs (cipher, auth, srtp_protect, ...)
-
-
-SRTP options not (yet) included in this libaray:
-
- - the aes-f8-mode cipher
- - HMAC-SHA-1
- - the Master Key Index
- - re-keying using the key derivation function (only the initial
-   use of the PRF has been implemented, as it's sufficient
-   for most uses)
-
-INCOMPLETE ADDITIONS
-
-   Added DES and 3DES ICM.
-
-
-PLANNED CHANGES
-
-   strip out test/lfsr.c
-
-   Write new documentation!!!
-
-   Fix the x86 assembly code in aes.c.
-
-   Eliminate /* DAM */ - there's one in srtp.c
-
-   Change debugging so that it can print more than one line.  Or perhaps
-   just change it so that a single check of the debug-enabled flag is
-   needed.
-
-   Improve interface between cipher and rdbx - perhaps generalize rdbx
-   into 'nonce' datatype.
-
-   Make rijndael_icm accept variable sized keys.
-
-   Add rdbx functions that allow different-sized explicit sequence
-   numbers to be used.
-
-   Write uniform byte-buffering code for PRFs, preferably as macros.
-
-   Consider eliminating low-level alloc functions in favor of len()
-   functions, so that there need not be multiple allocations within a
-   particular alloc() function.
-
-   Update test/stat-driver.c so that it tests the rand_source API.
-   Add a pseudorandom rand_source.
diff --git a/VERSION b/VERSION
deleted file mode 100644
index 88c5fb8..0000000
--- a/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.4.0
diff --git a/config.guess b/config.guess
index 0ce538b..c4bd827 100755
--- a/config.guess
+++ b/config.guess
@@ -1,11 +1,12 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-#   Free Software Foundation, Inc.
-#
+#   Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-05-15'
+
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -14,200 +15,342 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Written by Per Bothner <bothner@cygnus.com>.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
 # Please send patches to <config-patches@gnu.org>.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit system type (host/target name).
-#
-# Only a few systems have been added to this list; please add others
-# (but try to keep the structure clean).
-#
 
-# Use $HOST_CC if defined. $CC may point to a cross-compiler
-if test x"$CC_FOR_BUILD" = x; then
-  if test x"$HOST_CC" != x; then
-    CC_FOR_BUILD="$HOST_CC"
-  else
-    if test x"$CC" != x; then
-      CC_FOR_BUILD="$CC"
-    else
-      CC_FOR_BUILD=cc
-    fi
-  fi
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
 fi
 
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
+# (ghazi@noc.rutgers.edu 1994-08-24)
 if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	;;
+esac
 
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
-	# Netbsd (nbsd) targets should (where applicable) match one or
-	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
 	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
 	# switched to ELF, *-*-netbsd* would select the old
 	# object file format.  This provides both forward
 	# compatibility and a consistent mechanism for selecting the
 	# object file format.
-	# Determine the machine/vendor (is the vendor relevant).
-	case "${UNAME_MACHINE}" in
-	    amiga) machine=m68k-cbm ;;
-	    arm32) machine=arm-unknown ;;
-	    atari*) machine=m68k-atari ;;
-	    sun3*) machine=m68k-sun ;;
-	    mac68k) machine=m68k-apple ;;
-	    macppc) machine=powerpc-apple ;;
-	    hp3[0-9][05]) machine=m68k-hp ;;
-	    ibmrt|romp-ibm) machine=romp-ibm ;;
-	    *) machine=${UNAME_MACHINE}-unknown ;;
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    /sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || \
+	    echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    earmv*)
+		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+		machine=${arch}${endian}-unknown
+		;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
-	# The Operating System including object format.
-	if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-		| grep __ELF__ >/dev/null
-	then
-	    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
-	    # Return netbsd for either.  FIX?
-	    os=netbsd
-	else
-	    os=netbsdelf
-	fi
+	# The Operating System including object format, if it has switched
+	# to ELF recently (or will in the future) and ABI.
+	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		os=netbsdelf
+		;;
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# Determine ABI tags.
+	case "${UNAME_MACHINE_ARCH}" in
+	    earm*)
+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+		;;
+	esac
 	# The OS release
-	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		;;
+	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}"
-	exit 0 ;;
+	echo "${machine}-${os}${release}${abi}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:LibertyBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:Sortix:*:*)
+	echo ${UNAME_MACHINE}-unknown-sortix
+	exit ;;
     alpha:OSF1:*:*)
-	if test $UNAME_RELEASE = "V4.0"; then
+	case $UNAME_RELEASE in
+	*4.0)
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-	fi
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE=alpha ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE=alpha ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE=alpha ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE=alphaev5 ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE=alphaev56 ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE=alphapca56 ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE=alphapca57 ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE=alphaev6 ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE=alphaev67 ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE=alphaev68 ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE=alphaev68 ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE=alphaev68 ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE=alphaev69 ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE=alphaev7 ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE=alphaev79 ;;
+	esac
+	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	cat <<EOF >$dummy.s
-	.data
-\$Lformat:
-	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
-
-	.text
-	.globl main
-	.align 4
-	.ent main
-main:
-	.frame \$30,16,\$26,0
-	ldgp \$29,0(\$27)
-	.prologue 1
-	.long 0x47e03d80 # implver \$0
-	lda \$2,-1
-	.long 0x47e20c21 # amask \$2,\$1
-	lda \$16,\$Lformat
-	mov \$0,\$17
-	not \$1,\$18
-	jsr \$26,printf
-	ldgp \$29,0(\$26)
-	mov 0,\$16
-	jsr \$26,exit
-	.end main
-EOF
-	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-	if test "$?" = 0 ; then
-		case `./$dummy` in
-			0-0)
-				UNAME_MACHINE="alpha"
-				;;
-			1-0)
-				UNAME_MACHINE="alphaev5"
-				;;
-			1-1)
-				UNAME_MACHINE="alphaev56"
-				;;
-			1-101)
-				UNAME_MACHINE="alphapca56"
-				;;
-			2-303)
-				UNAME_MACHINE="alphaev6"
-				;;
-			2-307)
-				UNAME_MACHINE="alphaev67"
-				;;
-		esac
-	fi
-	rm -f $dummy.s $dummy
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	exit 0 ;;
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
     Alpha\ *:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# Should we change UNAME_MACHINE based on the output of uname instead
 	# of the specific Alpha model?
 	echo alpha-pc-interix
-	exit 0 ;;
+	exit ;;
     21064:Windows_NT:50:3)
 	echo alpha-dec-winnt3.5
-	exit 0 ;;
+	exit ;;
     Amiga*:UNIX_System_V:4.0:*)
-	echo m68k-cbm-sysv4
-	exit 0;;
-    amiga:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-unknown-sysv4
+	exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-amigaos
-	exit 0 ;;
-    arc64:OpenBSD:*:*)
-	echo mips64el-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    arc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    hkmips:OpenBSD:*:*)
-	echo mips-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    pmax:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    sgi:OpenBSD:*:*)
-	echo mips-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    wgrisc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
     *:OS/390:*:*)
 	echo i370-ibm-openedition
-	exit 0 ;;
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
-	exit 0;;
-    SR2?01:HI-UX/MPP:*:*)
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
 	echo hppa1.1-hitachi-hiuxmpp
-	exit 0;;
+	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
 	if test "`(/bin/universe) 2>/dev/null`" = att ; then
@@ -215,25 +358,51 @@
 	else
 		echo pyramid-pyramid-bsd
 	fi
-	exit 0 ;;
+	exit ;;
     NILE*:*:*:dcosx)
 	echo pyramid-pyramid-svr4
-	exit 0 ;;
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
-    i86pc:SunOS:5.*:*)
-	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH=i386
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH=x86_64
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
 	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     sun4*:SunOS:*:*)
 	case "`/usr/bin/arch -k`" in
 	    Series*|S4*)
@@ -242,13 +411,13 @@
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
 	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-	exit 0 ;;
+	exit ;;
     sun3*:SunOS:*:*)
 	echo m68k-sun-sunos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     sun*:*:4.2BSD:*)
-	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
 	case "`/bin/arch`" in
 	    sun3)
 		echo m68k-sun-sunos${UNAME_RELEASE}
@@ -257,13 +426,10 @@
 		echo sparc-sun-sunos${UNAME_RELEASE}
 		;;
 	esac
-	exit 0 ;;
+	exit ;;
     aushp:SunOS:*:*)
 	echo sparc-auspex-sunos${UNAME_RELEASE}
-	exit 0 ;;
-    atari*:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -273,51 +439,43 @@
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 	echo m68k-atari-mint${UNAME_RELEASE}
-        exit 0 ;;
+	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit 0 ;;
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit 0 ;;
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit 0 ;;
-    sun3*:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mac68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme88k:OpenBSD:*:*)
-	echo m88k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
     powerpc:machten:*:*)
 	echo powerpc-apple-machten${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     RISC*:Mach:*:*)
 	echo mips-dec-mach_bsd4.3
-	exit 0 ;;
+	exit ;;
     RISC*:ULTRIX:*:*)
 	echo mips-dec-ultrix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     VAX*:ULTRIX*:*:*)
 	echo vax-dec-ultrix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
 	echo clipper-intergraph-clix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -339,27 +497,36 @@
 	  exit (-1);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy \
-	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
-	  && rm $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
 	echo mips-mips-riscos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
     Night_Hawk:Power_UNIX:*:*)
 	echo powerpc-harris-powerunix
-	exit 0 ;;
+	exit ;;
     m88k:CX/UX:7*:*)
 	echo m88k-harris-cxux7
-	exit 0 ;;
+	exit ;;
     m88k:*:4*:R4*)
 	echo m88k-motorola-sysv4
-	exit 0 ;;
+	exit ;;
     m88k:*:3*:R3*)
 	echo m88k-motorola-sysv3
-	exit 0 ;;
+	exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
 	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
 	then
 	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -372,31 +539,40 @@
 	else
 	    echo i586-dg-dgux${UNAME_RELEASE}
 	fi
- 	exit 0 ;;
+	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 	echo m88k-dolphin-sysv3
-	exit 0 ;;
+	exit ;;
     M88*:*:R3*:*)
 	# Delta 88k system running SVR3
 	echo m88k-motorola-sysv3
-	exit 0 ;;
+	exit ;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
 	echo m88k-tektronix-sysv3
-	exit 0 ;;
+	exit ;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
 	echo m68k-tektronix-bsd
-	exit 0 ;;
+	exit ;;
     *:IRIX*:*:*)
 	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-	exit 0 ;;
+	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
-	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
-    i?86:AIX:*:*)
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
 	echo i386-ibm-aix
-	exit 0 ;;
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
 		sed 's/^		//' << EOF >$dummy.c
 		#include <sys/systemcfg.h>
 
@@ -408,95 +584,142 @@
 			exit(0);
 			}
 EOF
-		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
-		rm -f $dummy.c $dummy
-		echo rs6000-ibm-aix3.2.5
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
 		echo rs6000-ibm-aix3.2.4
 	else
 		echo rs6000-ibm-aix3.2
 	fi
-	exit 0 ;;
-    *:AIX:*:4)
-	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
-	if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/oslevel ] ; then
-		IBM_REV=`/usr/bin/oslevel`
+	if [ -x /usr/bin/lslpp ] ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
 	else
-		IBM_REV=4.${UNAME_RELEASE}
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-	exit 0 ;;
+	exit ;;
     *:AIX:*:*)
 	echo rs6000-ibm-aix
-	exit 0 ;;
+	exit ;;
     ibmrt:4.4BSD:*|romp-ibm:BSD:*)
 	echo romp-ibm-bsd4.4
-	exit 0 ;;
+	exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
 	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-	exit 0 ;;                           # report: romp-ibm BSD 4.3
+	exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
 	echo rs6000-bull-bosx
-	exit 0 ;;
+	exit ;;
     DPX/2?00:B.O.S.:*:*)
 	echo m68k-bull-sysv3
-	exit 0 ;;
+	exit ;;
     9000/[34]??:4.3bsd:1.*:*)
 	echo m68k-hp-bsd
-	exit 0 ;;
+	exit ;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
 	echo m68k-hp-bsd4.4
-	exit 0 ;;
+	exit ;;
     9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	case "${UNAME_MACHINE}" in
 	    9000/31? )            HP_ARCH=m68000 ;;
 	    9000/[34]?? )         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-              sed 's/^              //' << EOF >$dummy.c
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH=hppa2.0n ;;
+			  64) HP_ARCH=hppa2.0w ;;
+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
 
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
 
-                  switch (cpu)
-              	{
-              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-              	case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-              	    switch (bits)
-              		{
-              		case 64: puts ("hppa2.0w"); break;
-              		case 32: puts ("hppa2.0n"); break;
-              		default: puts ("hppa2.0"); break;
-              		} break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-              	    puts ("hppa2.0"); break;
-              #endif
-              	default: puts ("hppa1.0"); break;
-              	}
-                  exit (0);
-              }
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
 EOF
-	(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
-	rm -f $dummy.c $dummy
+		    (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
 	esac
-	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	if [ ${HP_ARCH} = hppa2.0w ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH=hppa2.0w
+	    else
+		HP_ARCH=hppa64
+	    fi
+	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-	exit 0 ;;
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
     3050*:HI-UX:*:*)
+	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#include <unistd.h>
 	int
@@ -522,447 +745,465 @@
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
 	echo unknown-hitachi-hiuxwe2
-	exit 0 ;;
+	exit ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
 	echo hppa1.1-hp-bsd
-	exit 0 ;;
+	exit ;;
     9000/8??:4.3bsd:*:*)
 	echo hppa1.0-hp-bsd
-	exit 0 ;;
-    *9??*:MPE/iX:*:*)
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
 	echo hppa1.0-hp-mpeix
-	exit 0 ;;
+	exit ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
 	echo hppa1.1-hp-osf
-	exit 0 ;;
+	exit ;;
     hp8??:OSF1:*:*)
 	echo hppa1.0-hp-osf
-	exit 0 ;;
-    i?86:OSF1:*:*)
+	exit ;;
+    i*86:OSF1:*:*)
 	if [ -x /usr/sbin/sysversion ] ; then
 	    echo ${UNAME_MACHINE}-unknown-osf1mk
 	else
 	    echo ${UNAME_MACHINE}-unknown-osf1
 	fi
-	exit 0 ;;
+	exit ;;
     parisc*:Lites*:*:*)
 	echo hppa1.1-hp-lites
-	exit 0 ;;
-    hppa*:OpenBSD:*:*)
-	echo hppa-unknown-openbsd
-	exit 0 ;;
+	exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
-        exit 0 ;;
+	exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-        exit 0 ;;
+	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 	echo c34-convex-bsd
-        exit 0 ;;
+	exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 	echo c38-convex-bsd
-        exit 0 ;;
+	exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
-        exit 0 ;;
-    CRAY*X-MP:*:*:*)
-	echo xmp-cray-unicos
-        exit 0 ;;
+	exit ;;
     CRAY*Y-MP:*:*:*)
-	echo ymp-cray-unicos${UNAME_RELEASE}
-	exit 0 ;;
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*[A-Z]90:*:*:*)
 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
-	exit 0 ;;
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*TS:*:*:*)
 	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
     CRAY*T3E:*:*:*)
-	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     CRAY*SV1:*:*:*)
 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
-    CRAY-2:*:*:*)
-	echo cray2-cray-unicos
-        exit 0 ;;
-    F300:UNIX_System_V:*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit 0 ;;
-    F301:UNIX_System_V:*:*)
-       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
-       exit 0 ;;
-    hp300:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     sparc*:BSD/OS:*:*)
 	echo sparc-unknown-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:BSD/OS:*:*)
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:FreeBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit 0 ;;
-    *:OpenBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
-	exit 0 ;;
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
-	exit 0 ;;
-    i*:MINGW*:*)
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
-	exit 0 ;;
+	exit ;;
+    *:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
 	# UNAME_MACHINE based on the output of uname instead of i386?
-	echo i386-pc-interix
-	exit 0 ;;
+	echo i586-pc-interix
+	exit ;;
     i*:UWIN*:*)
 	echo ${UNAME_MACHINE}-pc-uwin
-	exit 0 ;;
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
     p*:CYGWIN*:*)
 	echo powerpcle-unknown-cygwin
-	exit 0 ;;
+	exit ;;
     prep*:SunOS:5.*:*)
 	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     *:GNU:*:*)
-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-	exit 0 ;;
-    *:Linux:*:*)
-
-	# The BFD linker knows what the default object file format is, so
-	# first see if it will tell us. cd to the root directory to prevent
-	# problems with other programs or directories called `ld' in the path.
-	ld_help_string=`cd /; ld --help 2>&1`
-	ld_supported_emulations=`echo $ld_help_string \
-			 | sed -ne '/supported emulations:/!d
-				    s/[ 	][ 	]*/ /g
-				    s/.*supported emulations: *//
-				    s/ .*//
-				    p'`
-        case "$ld_supported_emulations" in
-	  *ia64)
-		echo "${UNAME_MACHINE}-unknown-linux"
-		exit 0
-		;;
-	  i?86linux)
-		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit 0
-		;;
-	  elf_i?86)
-		echo "${UNAME_MACHINE}-pc-linux"
-		exit 0
-		;;
-	  i?86coff)
-		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit 0
-		;;
-	  sparclinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  armlinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  elf32arm*)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
-		exit 0
-		;;
-	  armelf_linux*)
-		echo "${UNAME_MACHINE}-unknown-linux-gnu"
-		exit 0
-		;;
-	  m68klinux)
-		echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
-		exit 0
-		;;
-	  elf32ppc | elf32ppclinux)
-		# Determine Lib Version
-		cat >$dummy.c <<EOF
-#include <features.h>
-#if defined(__GLIBC__)
-extern char __libc_version[];
-extern char __libc_release[];
-#endif
-main(argc, argv)
-     int argc;
-     char *argv[];
-{
-#if defined(__GLIBC__)
-  printf("%s %s\n", __libc_version, __libc_release);
-#else
-  printf("unkown\n");
-#endif
-  return 0;
-}
-EOF
-		LIBC=""
-		$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
-		if test "$?" = 0 ; then
-			./$dummy | grep 1\.99 > /dev/null
-			if test "$?" = 0 ; then
-				LIBC="libc1"
-			fi
-		fi
-		rm -f $dummy.c $dummy
-		echo powerpc-unknown-linux-gnu${LIBC}
-		exit 0
-		;;
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
 	esac
-
-	if test "${UNAME_MACHINE}" = "alpha" ; then
-		cat <<EOF >$dummy.s
-			.data
-		\$Lformat:
-			.byte 37,100,45,37,120,10,0	# "%d-%x\n"
-
-			.text
-			.globl main
-			.align 4
-			.ent main
-		main:
-			.frame \$30,16,\$26,0
-			ldgp \$29,0(\$27)
-			.prologue 1
-			.long 0x47e03d80 # implver \$0
-			lda \$2,-1
-			.long 0x47e20c21 # amask \$2,\$1
-			lda \$16,\$Lformat
-			mov \$0,\$17
-			not \$1,\$18
-			jsr \$26,printf
-			ldgp \$29,0(\$26)
-			mov 0,\$16
-			jsr \$26,exit
-			.end main
-EOF
-		LIBC=""
-		$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-		if test "$?" = 0 ; then
-			case `./$dummy` in
-			0-0)
-				UNAME_MACHINE="alpha"
-				;;
-			1-0)
-				UNAME_MACHINE="alphaev5"
-				;;
-			1-1)
-				UNAME_MACHINE="alphaev56"
-				;;
-			1-101)
-				UNAME_MACHINE="alphapca56"
-				;;
-			2-303)
-				UNAME_MACHINE="alphaev6"
-				;;
-			2-307)
-				UNAME_MACHINE="alphaev67"
-				;;
-			esac
-
-			objdump --private-headers $dummy | \
-			  grep ld.so.1 > /dev/null
-			if test "$?" = 0 ; then
-				LIBC="libc1"
-			fi
-		fi
-		rm -f $dummy.s $dummy
-		echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
-	elif test "${UNAME_MACHINE}" = "mips" ; then
-	  cat >$dummy.c <<EOF
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-	int main (int argc, char *argv[]) {
-#else
-	int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __MIPSEB__
-  printf ("%s-unknown-linux-gnu\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
-  printf ("%sel-unknown-linux-gnu\n", argv[1]);
-#endif
-  return 0;
-}
-EOF
-	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
-	  rm -f $dummy.c $dummy
-	elif test "${UNAME_MACHINE}" = "s390"; then
-	  echo s390-ibm-linux && exit 0
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	else
-	  # Either a pre-BFD a.out linker (linux-gnuoldld)
-	  # or one that does not give us useful --help.
-	  # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
-	  # If ld does not provide *any* "supported emulations:"
-	  # that means it is gnuoldld.
-	  echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
-	  test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
-
-	  case "${UNAME_MACHINE}" in
-	  i?86)
-	    VENDOR=pc;
-	    ;;
-	  *)
-	    VENDOR=unknown;
-	    ;;
-	  esac
-	  # Determine whether the default compiler is a.out or elf
-	  cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-	int main (int argc, char *argv[]) {
-#else
-	int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-#  if __GLIBC__ >= 2
-    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
-#  else
-    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-#  endif
-# else
-   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-# endif
-#else
-  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
-#endif
-  return 0;
-}
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    e2k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    k1om:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
 EOF
-	  $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
-	  rm -f $dummy.c $dummy
-	fi ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
-# are messed up and put the nodename in both sysname and nodename.
-    i?86:DYNIX/ptx:4*:*)
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
 	echo i386-sequent-sysv4
-	exit 0 ;;
-    i?86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
+	# Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-	exit 0 ;;
-    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
 		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
 	else
 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
 	fi
-	exit 0 ;;
-    i?86:*:5:7*)
-        # Fixed at (any) Pentium or better
-        UNAME_MACHINE=i586
-        if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
-	    echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
-	else
-	    echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
-	fi
-	exit 0 ;;
-    i?86:*:3.2:*)
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
 		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
-		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
-		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 			&& UNAME_MACHINE=i586
-		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
 		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
 	else
 		echo ${UNAME_MACHINE}-pc-sysv32
 	fi
-	exit 0 ;;
-    i?86:*DOS:*:*)
-	echo ${UNAME_MACHINE}-pc-msdosdjgpp
-	exit 0 ;;
+	exit ;;
     pc:*:*:*)
 	# Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-	echo i386-pc-msdosdjgpp
-        exit 0 ;;
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configure will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
     Intel:Mach:3*:*)
 	echo i386-pc-mach3
-	exit 0 ;;
+	exit ;;
     paragon:*:*:*)
 	echo i860-intel-osf1
-	exit 0 ;;
+	exit ;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
 	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
 	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
 	fi
-	exit 0 ;;
+	exit ;;
     mini*:CTIX:SYS*5:*)
 	# "miniframe"
 	echo m68010-convergent-sysv
-	exit 0 ;;
-    M68*:*:R3V[567]*:*)
-	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
-    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && echo i486-ncr-sysv4 && exit 0 ;;
-    m68*:LynxOS:2.*:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     mc68030:UNIX_System_V:4.*:*)
 	echo m68k-atari-sysv4
-	exit 0 ;;
-    i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
-	echo i386-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     TSUNAMI:LynxOS:2.*:*)
 	echo sparc-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
-    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+	exit ;;
+    rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
     SM[BE]S:UNIX_SV:*:*)
 	echo mips-dde-sysv${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     RM*:ReliantUNIX-*:*:*)
 	echo mips-sni-sysv4
-	exit 0 ;;
+	exit ;;
     RM*:SINIX-*:*:*)
 	echo mips-sni-sysv4
-	exit 0 ;;
+	exit ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
@@ -970,214 +1211,246 @@
 	else
 		echo ns32k-sni-sysv
 	fi
-	exit 0 ;;
-    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                           # says <Richard.M.Bartel@ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit 0 ;;
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes@openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
 	echo hppa1.1-stratus-sysv4
-	exit 0 ;;
+	exit ;;
     *:*:*:FTX*)
 	# From seanf@swdc.stratus.com.
 	echo i860-stratus-sysv4
-	exit 0 ;;
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
     mc68*:A/UX:*:*)
 	echo m68k-apple-aux${UNAME_RELEASE}
-	exit 0 ;;
-    news*:NEWS-OS:*:6*)
+	exit ;;
+    news*:NEWS-OS:6*:*)
 	echo mips-sony-newsos6
-	exit 0 ;;
+	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
-	        echo mips-nec-sysv${UNAME_RELEASE}
+		echo mips-nec-sysv${UNAME_RELEASE}
 	else
-	        echo mips-unknown-sysv${UNAME_RELEASE}
+		echo mips-unknown-sysv${UNAME_RELEASE}
 	fi
-        exit 0 ;;
+	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 	echo powerpc-be-beos
-	exit 0 ;;
+	exit ;;
     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
 	echo powerpc-apple-beos
-	exit 0 ;;
+	exit ;;
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 	echo i586-pc-beos
-	exit 0 ;;
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     SX-5:SUPER-UX:*:*)
 	echo sx5-nec-superux${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-ACE:SUPER-UX:*:*)
+	echo sxace-nec-superux${UNAME_RELEASE}
+	exit ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:Rhapsody:*:*)
 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:Darwin:*:*)
-	echo `uname -p`-apple-darwin${UNAME_RELEASE}
-	exit 0 ;;
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
+	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
-	if test "${UNAME_MACHINE}" = "x86pc"; then
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = x86; then
+		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
-	echo `uname -p`-${UNAME_MACHINE}-nto-qnx
-	exit 0 ;;
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
     *:QNX:*:4*)
 	echo i386-pc-qnx
-	exit 0 ;;
-    NSR-W:NONSTOP_KERNEL:*:*)
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
     BS2000:POSIX*:*:*)
 	echo bs2000-siemens-sysv
-	exit 0 ;;
+	exit ;;
     DS/*:UNIX_System_V:*:*)
 	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = 386; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+    amd64:Isilon\ OneFS:*:*)
+	echo x86_64-unknown-onefs
+	exit ;;
 esac
 
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+cat >&2 <<EOF
+$0: unable to guess system type
 
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-          "4"
-#else
-	  ""
-#endif
-         ); exit (0);
-#endif
-#endif
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
 
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix"); exit (0);
-#endif
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
 
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
+config.guess timestamp = $timestamp
 
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
 
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
 
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
 
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-	printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-	printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-#if !defined (ultrix)
-  printf ("vax-dec-bsd\n"); exit (0);
-#else
-  printf ("vax-dec-ultrix\n"); exit (0);
-#endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
 EOF
 
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-	echo c1-convex-bsd
-	exit 0 ;;
-    c2*)
-	if getsysinfo -f scalar_acc
-	then echo c32-convex-bsd
-	else echo c2-convex-bsd
-	fi
-	exit 0 ;;
-    c34*)
-	echo c34-convex-bsd
-	exit 0 ;;
-    c38*)
-	echo c38-convex-bsd
-	exit 0 ;;
-    c4*)
-	echo c4-convex-bsd
-	exit 0 ;;
-    esac
-fi
-
-#echo '(Unable to guess system type)' 1>&2
-
 exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h_win32vc7 b/config.h_win32vc7
new file mode 100644
index 0000000..3b2a78c
--- /dev/null
+++ b/config.h_win32vc7
@@ -0,0 +1,162 @@
+/* Hacked config.h for Windows XP 32-bit & VC7  */
+
+#ifdef (_MSC_VER >= 1400)
+# define HAVE_RAND_S	1
+#endif
+
+/* Define if building for a CISC machine (e.g. Intel). */
+#define CPU_CISC 1
+
+/* Define if building for a RISC machine (assume slow byte access). */
+#undef CPU_RISC
+
+/* Path to random device */
+#undef DEV_URANDOM
+
+/* Define to enabled debug logging for all mudules. */
+#undef ENABLE_DEBUG_LOGGING
+
+/* Logging statments will be writen to this file. */
+#undef ERR_REPORTING_FILE
+
+/* Define to redirect logging to stdout. */
+#undef ERR_REPORTING_STDOUT
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
+
+/* Define to 1 if you have the `inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define to 1 if the system has the type `int16_t'. */
+#undef HAVE_INT16_T
+
+/* Define to 1 if the system has the type `int32_t'. */
+#undef HAVE_INT32_T
+
+/* Define to 1 if the system has the type `int8_t'. */
+#undef HAVE_INT8_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the <machine/types.h> header file. */
+#undef HAVE_MACHINE_TYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/int_types.h> header file. */
+#undef HAVE_SYS_INT_TYPES_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#undef HAVE_UINT16_T
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#undef HAVE_UINT32_T 
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#undef HAVE_UINT8_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the <windows.h> header file. */
+#define HAVE_WINDOWS_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#define HAVE_WINSOCK2_H 1
+
+/* Define to use X86 inlined assembly code */
+#undef HAVE_X86
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of a `unsigned long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG 4
+
+/* The size of a `unsigned long long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG_LONG 8
+
+/* Define to use GDOI. */
+#undef SRTP_GDOI
+
+/* Define to compile for kernel contexts. */
+#undef SRTP_KERNEL
+
+/* Define to compile for Linux kernel context. */
+#undef SRTP_KERNEL_LINUX
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define to empty if `const' does not conform to ANSI C. */
+//#undef const
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+//#ifndef __cplusplus
+//#undef inline
+//#endif
+#define inline __inline
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+//#undef size_t
diff --git a/config.hw b/config.hw
new file mode 100644
index 0000000..6fc65df
--- /dev/null
+++ b/config.hw
@@ -0,0 +1,182 @@
+/* crypto/include/config.h.  Generated by configure.  */
+/* config_in.h.  Generated from configure.in by autoheader.  */
+
+#if (_MSC_VER >= 1400)
+# define HAVE_RAND_S	1
+# define _CRT_RAND_S
+#endif
+
+/* Define if building for a CISC machine (e.g. Intel). */
+#define CPU_CISC 1
+
+/* Define if building for a RISC machine (assume slow byte access). */
+/* #undef CPU_RISC */
+
+/* Define to enabled debug logging for all mudules. */
+#undef ENABLE_DEBUG_LOGGING
+
+/* Logging statments will be writen to this file. */
+/* #undef ERR_REPORTING_FILE */
+
+/* Define to redirect logging to stdout. */
+#undef ERR_REPORTING_STDOUT
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+/* #undef HAVE_ARPA_INET_H */
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+/* #undef HAVE_BYTESWAP_H */
+
+/* Define to 1 if you have the `inet_aton' function. */
+/* #undef HAVE_INET_ATON */
+
+/* Define to 1 if the system has the type `int16_t'. */
+#define HAVE_INT16_T 1
+
+/* Define to 1 if the system has the type `int32_t'. */
+#define HAVE_INT32_T 1
+
+/* Define to 1 if the system has the type `int8_t'. */
+#define HAVE_INT8_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the <machine/types.h> header file. */
+/* #undef HAVE_MACHINE_TYPES_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+/* #undef HAVE_NETINET_IN_H */
+
+/* Define to 1 if you have the `socket' function. */
+/* #undef HAVE_SOCKET */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/int_types.h> header file. */
+/* #undef HAVE_SYS_INT_TYPES_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+/* #undef HAVE_SYS_UIO_H */
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#define HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#define HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#define HAVE_UINT8_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define to 1 if you have the `usleep' function. */
+/* #undef HAVE_USLEEP */
+
+/* Define to 1 if you have the <windows.h> header file. */
+#define HAVE_WINDOWS_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#define HAVE_WINSOCK2_H 1
+
+/* Define to use X86 inlined assembly code */
+/* #undef HAVE_X86 */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* The size of a `unsigned long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG 4
+
+/* The size of a `unsigned long long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG_LONG 8
+
+/* Define to use GDOI. */
+/* #undef SRTP_GDOI */
+
+/* Define to compile for kernel contexts. */
+/* #undef SRTP_KERNEL */
+
+/* Define to compile for Linux kernel context. */
+/* #undef SRTP_KERNEL_LINUX */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define 'inline' to nothing, since the MSVC compiler doesn't support it.  */
+#define inline 
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+#if (_MSC_VER >= 1400) // VC8+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+#endif // VC8+
+
+#ifndef uint32_t
+typedef unsigned __int8		uint8_t;
+typedef unsigned __int16	uint16_t;
+typedef unsigned __int32	uint32_t;
+typedef unsigned __int64    uint64_t;
+typedef __int8		int8_t;
+typedef __int16		int16_t;
+typedef __int32		int32_t;
+typedef __int64		int64_t;
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable:4311)
+#endif
diff --git a/config.sub b/config.sub
index c8e7785..6d86a1e 100755
--- a/config.sub
+++ b/config.sub
@@ -1,33 +1,30 @@
 #! /bin/sh
-# Configuration validation subroutine script, version 1.1.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-#   Free Software Foundation, Inc.
-#
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# Configuration validation subroutine script.
+#   Copyright 1992-2016 Free Software Foundation, Inc.
+
+timestamp='2016-05-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
 
-# Written by Per Bothner <bothner@cygnus.com>.
+
 # Please send patches to <config-patches@gnu.org>.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
@@ -35,6 +32,9 @@
 # If it is invalid, we print an error message on stderr and exit with code 1.
 # Otherwise, we print the canonical config type on stdout and succeed.
 
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
 # that are meaningful with *any* GNU software.
@@ -50,33 +50,82 @@
 #	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 # It is wrong to echo any other type of specification.
 
-if [ x$1 = x ]
-then
-	echo Configuration name missing. 1>&2
-	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
-	echo "or     $0 ALIAS" 1>&2
-	echo where ALIAS is a recognized configuration type. 1>&2
-	exit 1
-fi
+me=`echo "$0" | sed -e 's,.*/,,'`
 
-# First pass through any local machine types.
-case $1 in
-	*local*)
-		echo $1
-		exit 0
-		;;
-	*)
-	;;
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2016 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
 esac
 
 # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu*)
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -99,10 +148,13 @@
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple)
+	-apple | -axis | -knuth | -cray | -microblaze*)
 		os=
 		basic_machine=$1
 		;;
+	-bluegene*)
+		os=-cnk
+		;;
 	-sim | -cisco | -oki | -wec | -winbond)
 		os=
 		basic_machine=$1
@@ -113,9 +165,21 @@
 		os=-vxworks
 		basic_machine=$1
 		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
 	-hiux*)
 		os=-hiuxwe2
 		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco5)
 		os=-sco3.2v5
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -132,6 +196,10 @@
 		# Don't forget version if it is 3.2v4 or newer.
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco*)
 		os=-sco3.2v2
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -149,6 +217,12 @@
 	-isc*)
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
 	-lynx*)
 		os=-lynxos
 		;;
@@ -171,30 +245,121 @@
 case $basic_machine in
 	# Recognize the basic CPU types without company name.
 	# Some are omitted here because they have special meanings below.
-	tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
-		| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
-		| 580 | i960 | h8300 \
-		| x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
-		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
-		| hppa64 \
-		| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
-		| alphaev6[78] \
-		| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
-		| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
-		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
-		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
-		| mips64vr5000 | miprs64vr5000el | mcore \
-		| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
-		| thumb | d10v | fr30 | avr)
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| ba \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| e2k | epiphany \
+	| fido | fr30 | frv | ft32 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| k1om \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 | or1k | or1knd | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| riscv32 | riscv64 \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| visium \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
 		basic_machine=$basic_machine-unknown
 		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	leon|leon[3-9])
+		basic_machine=sparc-$basic_machine
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
 		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
-	i[34567]86)
+	i*86 | x86_64)
 	  basic_machine=$basic_machine-pc
 	  ;;
 	# Object if more than one company name word.
@@ -203,28 +368,91 @@
 		exit 1
 		;;
 	# Recognize the basic CPU types with company name.
-	# FIXME: clean up the formatting here.
-	vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
-	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
-	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
-	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
-	      | xmp-* | ymp-* \
-	      | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
-	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
-	      | hppa2.0n-* | hppa64-* \
-	      | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
-	      | alphaev6[78]-* \
-	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
-	      | clipper-* | orion-* \
-	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
-	      | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
-	      | mips64el-* | mips64orion-* | mips64orionel-* \
-	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
-	      | mipstx39-* | mipstx39el-* | mcore-* \
-	      | f301-* | armv*-* | s390-* | sv1-* | t3e-* \
-	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
-	      | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
-	      | bs2000-*)
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| ba-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| e2k-* | elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| k1om-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| or1k*-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| riscv32-* | riscv64-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| visium-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
 		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
@@ -242,6 +470,9 @@
 		basic_machine=a29k-amd
 		os=-udi
 		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
 	adobe68k)
 		basic_machine=m68010-adobe
 		os=-scout
@@ -256,19 +487,25 @@
 		basic_machine=a29k-none
 		os=-bsd
 		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	amdahl)
 		basic_machine=580-amdahl
 		os=-sysv
 		;;
 	amiga | amiga-*)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		;;
 	amigaos | amigados)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		os=-amigaos
 		;;
 	amigaunix | amix)
-		basic_machine=m68k-cbm
+		basic_machine=m68k-unknown
 		os=-sysv4
 		;;
 	apollo68)
@@ -279,6 +516,13 @@
 		basic_machine=m68k-apollo
 		os=-bsd
 		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	asmjs)
+		basic_machine=asmjs-unknown
+		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -287,6 +531,35 @@
 		basic_machine=ns32k-sequent
 		os=-dynix
 		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -307,27 +580,45 @@
 		basic_machine=c38-convex
 		os=-bsd
 		;;
-	cray | ymp)
-		basic_machine=ymp-cray
+	cray | j90)
+		basic_machine=j90-cray
 		os=-unicos
 		;;
-	cray2)
-		basic_machine=cray2-cray
-		os=-unicos
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
 		;;
-	[ctj]90-cray)
-		basic_machine=c90-cray
-		os=-unicos
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
 		;;
 	crds | unos)
 		basic_machine=m68k-crds
 		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
 	da30 | da30-*)
 		basic_machine=m68k-da30
 		;;
 	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
 		basic_machine=mips-dec
 		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
 	delta | 3300 | motorola-3300 | motorola-delta \
 	      | 3300-motorola | delta-motorola)
 		basic_machine=m68k-motorola
@@ -336,6 +627,14 @@
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
 	dpx20 | dpx20-*)
 		basic_machine=rs6000-bull
 		os=-bosx
@@ -369,6 +668,10 @@
 		basic_machine=tron-gmicro
 		os=-sysv
 		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
 	h3050r* | hiux*)
 		basic_machine=hppa1.1-hitachi
 		os=-hiuxwe2
@@ -443,20 +746,19 @@
 	i370-ibm* | ibm*)
 		basic_machine=i370-ibm
 		;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-	i[34567]86v32)
+	i*86v32)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv32
 		;;
-	i[34567]86v4*)
+	i*86v4*)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv4
 		;;
-	i[34567]86v)
+	i*86v)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-sysv
 		;;
-	i[34567]86sol2)
+	i*86sol2)
 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 		os=-solaris2
 		;;
@@ -468,14 +770,6 @@
 		basic_machine=i386-unknown
 		os=-vsta
 		;;
-	i386-go32 | go32)
-		basic_machine=i386-unknown
-		os=-go32
-		;;
-	i386-mingw32 | mingw32)
-		basic_machine=i386-unknown
-		os=-mingw32
-		;;
 	iris | iris4d)
 		basic_machine=mips-sgi
 		case $os in
@@ -490,6 +784,17 @@
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
+	leon-*|leon[3-9]-*)
+		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	m88k-omron*)
 		basic_machine=m88k-omron
 		;;
@@ -501,6 +806,21 @@
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -508,36 +828,43 @@
 		basic_machine=m68k-atari
 		os=-mint
 		;;
-	mipsel*-linux*)
-		basic_machine=mipsel-unknown
-		os=-linux-gnu
-		;;
-	mips*-linux*)
-		basic_machine=mips-unknown
-		os=-linux-gnu
-		;;
 	mips3*-*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
 		;;
 	mips3*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 		;;
-	mmix*)
-		basic_machine=mmix-knuth
-		os=-mmixware
-		;;
 	monitor)
 		basic_machine=m68k-rom68k
 		os=-coff
 		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	moxiebox)
+		basic_machine=moxie-unknown
+		os=-moxiebox
+		;;
 	msdos)
-		basic_machine=i386-unknown
+		basic_machine=i386-pc
 		os=-msdos
 		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
 	mvs)
 		basic_machine=i370-ibm
 		os=-mvs
 		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
 	ncr3000)
 		basic_machine=i486-ncr
 		os=-sysv4
@@ -595,9 +922,19 @@
 		basic_machine=i960-intel
 		os=-mon960
 		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
 	np1)
 		basic_machine=np1-gould
 		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -605,6 +942,13 @@
 		basic_machine=hppa1.1-oki
 		os=-proelf
 		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
 	OSE68000 | ose68000)
 		basic_machine=m68000-ericsson
 		os=-ose
@@ -621,51 +965,94 @@
 		basic_machine=i860-intel
 		os=-osf
 		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	pbd)
 		basic_machine=sparc-tti
 		;;
 	pbb)
 		basic_machine=m68k-tti
 		;;
-        pc532 | pc532-*)
+	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
-	pentium | p5 | k5 | k6 | nexen)
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
-	pentiumpro | p6 | 6x86)
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
 		basic_machine=i686-pc
 		;;
-	pentiumii | pentium2)
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
 		basic_machine=i786-pc
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexen-*)
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentiumpro-* | p6-* | 6x86-*)
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentiumii-* | pentium2-*)
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
 		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	pn)
 		basic_machine=pn-gould
 		;;
-	power)	basic_machine=rs6000-ibm
+	power)	basic_machine=power-ibm
 		;;
-	ppc)	basic_machine=powerpc-unknown
-	        ;;
-	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppcle | powerpclittle | ppc-le | powerpc-little)
 		basic_machine=powerpcle-unknown
-	        ;;
+		;;
 	ppcle-* | powerpclittle-*)
 		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	ps2)
 		basic_machine=i386-ibm
 		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -676,10 +1063,30 @@
 	rtpc | rtpc-*)
 		basic_machine=romp-ibm
 		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
 	sa29200)
 		basic_machine=a29k-amd
 		os=-udi
 		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
 	sequent)
 		basic_machine=i386-sequent
 		;;
@@ -687,7 +1094,13 @@
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
-	sparclite-wrs)
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
 		basic_machine=sparclite-wrs
 		os=-vxworks
 		;;
@@ -705,6 +1118,9 @@
 		basic_machine=i860-stratus
 		os=-sysv4
 		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	sun2)
 		basic_machine=m68000-sun
 		;;
@@ -754,18 +1170,34 @@
 		os=-dynix
 		;;
 	t3e)
-		basic_machine=t3e-cray
+		basic_machine=alphaev5-cray
 		os=-unicos
 		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
 	tx39)
 		basic_machine=mipstx39-unknown
 		;;
 	tx39el)
 		basic_machine=mipstx39el-unknown
 		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
 	tower | tower-32)
 		basic_machine=m68k-ncr
 		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
 	udi29k)
 		basic_machine=a29k-amd
 		os=-udi
@@ -787,8 +1219,8 @@
 		os=-vms
 		;;
 	vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
+		basic_machine=f301-fujitsu
+		;;
 	vxworks960)
 		basic_machine=i960-wrs
 		os=-vxworks
@@ -809,17 +1241,28 @@
 		basic_machine=hppa1.1-winbond
 		os=-proelf
 		;;
-	xmp)
-		basic_machine=xmp-cray
-		os=-unicos
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
 		;;
-        xps | xps100)
+	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
 	z8k-*-coff)
 		basic_machine=z8k-unknown
 		os=-sim
 		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
 	none)
 		basic_machine=none-none
 		os=-none
@@ -836,32 +1279,35 @@
 	op60c)
 		basic_machine=hppa1.1-oki
 		;;
-	mips)
-		if [ x$os = x-linux-gnu ]; then
-			basic_machine=mips-unknown
-		else
-			basic_machine=mips-mips
-		fi
-		;;
 	romp)
 		basic_machine=romp-ibm
 		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
 	rs6000)
 		basic_machine=rs6000-ibm
 		;;
 	vax)
 		basic_machine=vax-dec
 		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
 	pdp11)
 		basic_machine=pdp11-dec
 		;;
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sparc | sparcv9)
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 		basic_machine=sparc-sun
 		;;
-        cydra)
+	cydra)
 		basic_machine=cydra-cydrome
 		;;
 	orion)
@@ -876,9 +1322,8 @@
 	pmac | pmac-mpw)
 		basic_machine=powerpc-apple
 		;;
-	c4x*)
-		basic_machine=c4x-none
-		os=-coff
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
 		;;
 	*)
 		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
@@ -903,9 +1348,12 @@
 if [ x"$os" != x"" ]
 then
 case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
+	# First match some system type aliases
+	# that might get confused with valid system types.
 	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
 	-solaris1 | -solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
@@ -926,41 +1374,58 @@
 	# Each alternative MUST END IN A *, to match a version number.
 	# -sysv* is not here because it comes later, after sysvr4.
 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* \
+	      | -aos* | -aros* | -cloudabi* | -sortix* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
-	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
-	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
-	      | -openstep* | -oskit*)
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+	      | -onefs* | -tirtos* | -phoenix*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
 		case $basic_machine in
-		    x86-* | i[34567]86-*)
+		    x86-* | i*86-*)
 			;;
 		    *)
 			os=-nto$os
 			;;
 		esac
 		;;
+	-nto-qnx*)
+		;;
 	-nto*)
-		os=-nto-qnx
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
 	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
 	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 		;;
 	-mac*)
 		os=`echo $os | sed -e 's|mac|macos|'`
 		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
 	-linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
@@ -973,6 +1438,9 @@
 	-opened*)
 		os=-openedition
 		;;
+	-os400*)
+		os=-os400
+		;;
 	-wince*)
 		os=-wince
 		;;
@@ -991,16 +1459,25 @@
 	-acis*)
 		os=-aos
 		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
 	-386bsd)
 		os=-bsd
 		;;
 	-ctix* | -uts*)
 		os=-sysv
 		;;
-	-ns2 )
-	        os=-nextstep2
+	-nova*)
+		os=-rtmk-nova
 		;;
-	-nsk)
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
 		os=-nsk
 		;;
 	# Preserve the version number of sinix5.
@@ -1010,6 +1487,9 @@
 	-sinix*)
 		os=-sysv4
 		;;
+	-tpf*)
+		os=-tpf
+		;;
 	-triton*)
 		os=-sysv3
 		;;
@@ -1037,8 +1517,21 @@
 	-xenix)
 		os=-xenix
 		;;
-        -*mint | -*MiNT)
-	        os=-mint
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-ios)
 		;;
 	-none)
 		;;
@@ -1062,6 +1555,12 @@
 # system, and we'll never get to this point.
 
 case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1071,7 +1570,29 @@
 	arm*-semi)
 		os=-aout
 		;;
-        pdp11-*)
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
 		os=-none
 		;;
 	*-dec | vax-*)
@@ -1085,19 +1606,22 @@
 		;;
 	m68000-sun)
 		os=-sunos3
-		# This also exists in the configure program, but was not the
-		# default.
-		# os=-sunos4
 		;;
 	m68*-cisco)
 		os=-aout
 		;;
+	mep-*)
+		os=-elf
+		;;
 	mips*-cisco)
 		os=-elf
 		;;
 	mips*-*)
 		os=-elf
 		;;
+	or32-*)
+		os=-coff
+		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
 		os=-sysv3
 		;;
@@ -1107,9 +1631,15 @@
 	*-be)
 		os=-beos
 		;;
+	*-haiku)
+		os=-haiku
+		;;
 	*-ibm)
 		os=-aix
 		;;
+	*-knuth)
+		os=-mmixware
+		;;
 	*-wec)
 		os=-proelf
 		;;
@@ -1161,25 +1691,25 @@
 	*-next)
 		os=-nextstep3
 		;;
-        *-gould)
+	*-gould)
 		os=-sysv
 		;;
-        *-highlevel)
+	*-highlevel)
 		os=-bsd
 		;;
 	*-encore)
 		os=-bsd
 		;;
-        *-sgi)
+	*-sgi)
 		os=-irix
 		;;
-        *-siemens)
+	*-siemens)
 		os=-sysv4
 		;;
 	*-masscomp)
 		os=-rtu
 		;;
-	f301-fujitsu)
+	f30[01]-fujitsu | f700-fujitsu)
 		os=-uxpv
 		;;
 	*-rom68k)
@@ -1212,7 +1742,7 @@
 			-sunos*)
 				vendor=sun
 				;;
-			-aix*)
+			-cnk*|-aix*)
 				vendor=ibm
 				;;
 			-beos*)
@@ -1242,10 +1772,16 @@
 			-mvs* | -opened*)
 				vendor=ibm
 				;;
+			-os400*)
+				vendor=ibm
+				;;
 			-ptx*)
 				vendor=sequent
 				;;
-			-vxsim* | -vxworks*)
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
 				vendor=wrs
 				;;
 			-aux*)
@@ -1257,12 +1793,23 @@
 			-mpw* | -macos*)
 				vendor=apple
 				;;
-			-*mint | -*MiNT)
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 				vendor=atari
 				;;
+			-vos*)
+				vendor=stratus
+				;;
 		esac
 		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
 		;;
 esac
 
 echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config_in.h b/config_in.h
index 41aebc5..31e6ffe 100644
--- a/config_in.h
+++ b/config_in.h
@@ -1,104 +1,196 @@
-/*
- * config_in.h
- *
- * template for header config file for Secure RTP and UST implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
+/* config_in.h.  Generated from configure.ac by autoheader.  */
 
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
 
-#ifndef CONFIG_H
-#define CONFIG_H
+/* Define if building for a CISC machine (e.g. Intel). */
+#undef CPU_CISC
 
-/* if we're on a big endian machine, we need to define this */
+/* Define if building for a RISC machine (assume slow byte access). */
+#undef CPU_RISC
 
-#define WORDS_BIGENDIAN      0
+/* Define to enabled debug logging for all mudules. */
+#undef ENABLE_DEBUG_LOGGING
 
-/* check for <stdint.h> or <machine/types.h>              */
+/* Logging statments will be writen to this file. */
+#undef ERR_REPORTING_FILE
 
-#define HAVE_STDINT_H        0
-#define HAVE_MACHINE_TYPES_H 0
-#define HAVE_SYS_INT_TYPES_H 0
+/* Define to redirect logging to stdout. */
+#undef ERR_REPORTING_STDOUT
 
-/* check for microsoft integer definitions (e.g., cygwin) */
+/* Define this to use AES-GCM. */
+#undef GCM
 
-#define HAVE_MS_TYPES        1
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
 
-/* if we don't have uio.h, we'll need to define struct iovec */
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
 
-#define HAVE_SYS_UIO_H       0
+/* Define to 1 if you have the `inet_aton' function. */
+#undef HAVE_INET_ATON
 
-/* <unistd.h> is used by some test/ apps                  */
+/* Define to 1 if the system has the type `int16_t'. */
+#undef HAVE_INT16_T
 
-#define HAVE_UNISTD_H        0
+/* Define to 1 if the system has the type `int32_t'. */
+#undef HAVE_INT32_T
 
-/* test apps should use inet_aton(), if it's available */
+/* Define to 1 if the system has the type `int8_t'. */
+#undef HAVE_INT8_T
 
-#define HAVE_INET_ATON       0
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
 
-/* check if we have syslog functions                      */
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
 
-#define HAVE_SYSLOG_H        0
+/* Define to 1 if you have the `nspr4' library (-lnspr4). */
+#undef HAVE_LIBNSPR4
 
-/* check to see if the user has requested the use of syslog */
+/* Define to 1 if you have the `nss3' library (-lnss3). */
+#undef HAVE_LIBNSS3
 
-#define USE_SYSLOG           0
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
 
-#define ERR_REPORTING_STDOUT 0
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
 
-#define ERR_REPORTING_SYSLOG (HAVE_SYSLOG_H & USE_SYSLOG)
+/* Define to 1 if you have the <machine/types.h> header file. */
+#undef HAVE_MACHINE_TYPES_H
 
-/* define ERR_REPORTING_FILE to have messages sent to file */
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
 
-#define ERR_REPORTING_FILE 
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
 
-/* 
- * set ENABLE_DEBUGGING to 1 to compile in dynamic debugging system,
- * set it to 0 to not compile in dynamic debugging (for a slight
- * performance improvement)
- */
+/* Define to 1 if you have the <nss.h> header file. */
+#undef HAVE_NSS_H
 
-#define ENABLE_DEBUGGING     0
+/* Define to 1 if you have the `winpcap' library (-lwpcap) */
+#undef HAVE_PCAP
 
-/* if we're going to use GDOI, define SRTP_GDOI to 1      */
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
 
-#define SRTP_GDOI            0
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
 
-/*
- * CPU_type is defined as 1 if the host processor is of that type.
- * Note that more than one type can be defined at once; this is so
- * that special instructions and other optimizations can be handled
- * independently.
- * 
- * CPU_RISC     RISC machines (assume slow byte access)
- * CPU_CISC     CISC machines (e.g. Intel)
- * CPU_ALTIVEC  Motorola's SIMD instruction set
- * 
- */
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
 
-#define CPU_RISC     0
-#define CPU_CISC     0
-#define CPU_ALTIVEC  0
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
 
-/*
- * if /dev/random is available, then DEV_RANDOM == 1
- *
- * /dev/random is a (true) random number generator which is
- * implemented in many modern operating systems
- */
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
 
-#define DEV_RANDOM 0
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
 
-/* check for stdlib.h - we use it for xalloc() and free() */
+/* Define to 1 if you have the <sys/int_types.h> header file. */
+#undef HAVE_SYS_INT_TYPES_H
 
-#define HAVE_STDLIB_H 0
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
 
-/* whether to use ismacryp code */
-#define GENERIC_AESICM 0
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
 
-#endif /* CONFIG_H */
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
 
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
 
+/* Define to 1 if the system has the type `uint16_t'. */
+#undef HAVE_UINT16_T
 
+/* Define to 1 if the system has the type `uint32_t'. */
+#undef HAVE_UINT32_T
 
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#undef HAVE_UINT8_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `usleep' function. */
+#undef HAVE_USLEEP
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#undef HAVE_WINSOCK2_H
+
+/* Define to use X86 inlined assembly code */
+#undef HAVE_X86
+
+/* Define this to use NSS crypto. */
+#undef NSS
+
+/* Define this to use OpenSSL crypto. */
+#undef OPENSSL
+
+/* Define this if OPENSSL_cleanse is broken. */
+#undef OPENSSL_CLEANSE_BROKEN
+
+/* Define this to use OpenSSL KDF for SRTP. */
+#undef OPENSSL_KDF
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/config_in_cmake.h b/config_in_cmake.h
new file mode 100644
index 0000000..57e0864
--- /dev/null
+++ b/config_in_cmake.h
@@ -0,0 +1,115 @@
+/* clang-format off */
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
+
+/* Define to enabled debug logging for all mudules. */
+#cmakedefine ENABLE_DEBUG_LOGGING 1
+
+/* Logging statments will be writen to this file. */
+#cmakedefine ERR_REPORTING_FILE "@ERR_REPORTING_FILE@"
+
+/* Define to redirect logging to stdout. */
+#cmakedefine ERR_REPORTING_STDOUT 1
+
+/* Define this to use OpenSSL crypto. */
+#cmakedefine OPENSSL 1
+
+/* Define this to use AES-GCM. */
+#cmakedefine GCM 1
+
+/* Define if building for a CISC machine (e.g. Intel). */
+#define CPU_CISC 1
+
+/* Define if building for a RISC machine (assume slow byte access). */
+/* #undef CPU_RISC */
+
+/* Define to use X86 inlined assembly code */
+#define HAVE_X86 1
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#cmakedefine WORDS_BIGENDIAN 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#cmakedefine HAVE_BYTESWAP_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <machine/types.h> header file. */
+#cmakedefine HAVE_MACHINE_TYPES_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <sys/int_types.h> header file. */
+#cmakedefine HAVE_SYS_INT_TYPES_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#cmakedefine HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <windows.h> header file. */
+#cmakedefine HAVE_WINDOWS_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#cmakedefine HAVE_WINSOCK2_H 1
+
+/* Define to 1 if you have the `inet_aton' function. */
+#cmakedefine HAVE_INET_ATON 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#cmakedefine HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `usleep' function. */
+#cmakedefine HAVE_USLEEP 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#cmakedefine HAVE_UINT8_T 1
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#cmakedefine HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#cmakedefine HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#cmakedefine HAVE_UINT64_T 1
+
+/* Define to 1 if the system has the type `int32_t'. */
+#cmakedefine HAVE_INT32_T 1
+
+/* The size of `unsigned long', as computed by sizeof. */
+@SIZEOF_UNSIGNED_LONG_CODE@
+
+/* The size of `unsigned long long', as computed by sizeof. */
+@SIZEOF_UNSIGNED_LONG_LONG_CODE@
+
+/* Define inline to what is supported by compiler  */
+#cmakedefine HAVE_INLINE 1
+#cmakedefine HAVE___INLINE 1
+#ifndef HAVE_INLINE
+  #ifdef HAVE___INLINE
+    #define inline __inline
+  #else
+    #define inline
+  #endif
+#endif
diff --git a/configure b/configure
index edd6829..65ccff3 100755
--- a/configure
+++ b/configure
@@ -1,81 +1,462 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.57.
+# Generated by GNU Autoconf 2.69 for libsrtp2 2.3.0-pre.
 #
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
+# Report bugs to <https://github.com/cisco/libsrtp/issues>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
-fi
-
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
-  as_unset=unset
+  setopt NO_GLOB_SUBST
 else
-  as_unset=false
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
 fi
 
 
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    $as_unset $as_var
-  fi
-done
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
 
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: https://github.com/cisco/libsrtp/issues about your
+$0: system, including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
 fi
 
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
 
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
 
-
-# PATH needs CR, and LINENO needs CR and PATH.
 # Avoid depending upon Character Ranges.
 as_cr_letters='abcdefghijklmnopqrstuvwxyz'
 as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -83,237 +464,286 @@
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
 
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
-	 /*)
-	   if ("$as_dir/$as_base" -c '
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
     sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
       N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
       t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
+      s/-\n.*//
     ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
   # Exit status is that of the last command.
   exit
 }
 
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
 rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
-    as_ln_s='cp -p'
-  else
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
     as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
   fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
 
 if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
+  test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
-as_executable_p="test -f"
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
 # Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
-exec 6>&1
-
 #
 # Initializations.
 #
 ac_default_prefix=/usr/local
+ac_clean_files=
 ac_config_libobj_dir=.
+LIBOBJS=
 cross_compiling=no
 subdirs=
 MFLAGS=
 MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete.  It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
 
 # Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
+PACKAGE_NAME='libsrtp2'
+PACKAGE_TARNAME='libsrtp2'
+PACKAGE_VERSION='2.3.0-pre'
+PACKAGE_STRING='libsrtp2 2.3.0-pre'
+PACKAGE_BUGREPORT='https://github.com/cisco/libsrtp/issues'
+PACKAGE_URL=''
 
-ac_unique_file="srtp"
 # Factoring default headers for most tests.
 ac_includes_default="\
 #include <stdio.h>
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #endif
-#if HAVE_SYS_STAT_H
+#ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
-#if STDC_HEADERS
+#ifdef STDC_HEADERS
 # include <stdlib.h>
 # include <stddef.h>
 #else
-# if HAVE_STDLIB_H
+# ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
 # endif
 #endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
 #  include <memory.h>
 # endif
 # include <string.h>
 #endif
-#if HAVE_STRINGS_H
+#ifdef HAVE_STRINGS_H
 # include <strings.h>
 #endif
-#if HAVE_INTTYPES_H
+#ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-#  include <stdint.h>
-# endif
 #endif
-#if HAVE_UNISTD_H
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS RANLIB ac_ct_RANLIB CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RNG_OBJS CPP EGREP LIBOBJS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EXE GDOI_OBJS LTLIBOBJS'
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+PCAP_LIB
+HAVE_PCAP
+HMAC_OBJS
+AES_ICM_OBJS
+nss_LIBS
+nss_CFLAGS
+CRYPTO_LIBDIR
+USE_EXTERNAL_CRYPTO
+crypto_LIBS
+crypto_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+EXE
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+EGREP
+GREP
+SED
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+RANLIB
+ac_ct_AR
+AR
+EXTRA_CFLAGS
+ac_ct_CXX
+CXXFLAGS
+CXX
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
 ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_debug_logging
+enable_openssl
+enable_nss
+with_openssl_dir
+enable_openssl_kdf
+with_nss_dir
+enable_log_stdout
+with_log_file
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+EXTRA_CFLAGS
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+crypto_CFLAGS
+crypto_LIBS
+nss_CFLAGS
+nss_LIBS'
+
 
 # Initialize some variables set by options.
 ac_init_help=
 ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
 # The variables have the same names as the options, with
 # dashes changed to underlines.
 cache_file=/dev/null
@@ -336,34 +766,50 @@
 # and all the variables that are supposed to be based on exec_prefix
 # by default will actually change.
 # Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
 bindir='${exec_prefix}/bin'
 sbindir='${exec_prefix}/sbin'
 libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
 
 ac_prev=
+ac_dashdash=
 for ac_option
 do
   # If the previous option needs an argument, assign it.
   if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
+    eval $ac_prev=\$ac_option
     ac_prev=
     continue
   fi
 
-  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
 
-  case $ac_option in
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
 
   -bindir | --bindir | --bindi | --bind | --bin | --bi)
     ac_prev=bindir ;;
@@ -385,33 +831,59 @@
   --config-cache | -C)
     cache_file=config.cache ;;
 
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+  -datadir | --datadir | --datadi | --datad)
     ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
     datadir=$ac_optarg ;;
 
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
   -disable-* | --disable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval "enable_$ac_feature=no" ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
 
   -enable-* | --enable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
     esac
-    eval "enable_$ac_feature='$ac_optarg'" ;;
+    eval enable_$ac_useropt=\$ac_optarg ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -438,6 +910,12 @@
   -host=* | --host=* | --hos=* | --ho=*)
     host_alias=$ac_optarg ;;
 
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
   -includedir | --includedir | --includedi | --included | --include \
   | --includ | --inclu | --incl | --inc)
     ac_prev=includedir ;;
@@ -462,13 +940,16 @@
   | --libexe=* | --libex=* | --libe=*)
     libexecdir=$ac_optarg ;;
 
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
   -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
+  | --localstate | --localstat | --localsta | --localst | --locals)
     ac_prev=localstatedir ;;
   -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
     localstatedir=$ac_optarg ;;
 
   -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -533,10 +1014,29 @@
   | --progr-tra=* | --program-tr=* | --program-t=*)
     program_transform_name=$ac_optarg ;;
 
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -583,26 +1083,36 @@
     ac_init_version=: ;;
 
   -with-* | --with-*)
-    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
     esac
-    eval "with_$ac_package='$ac_optarg'" ;;
+    eval with_$ac_useropt=\$ac_optarg ;;
 
   -without-* | --without-*)
-    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval "with_$ac_package=no" ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -622,27 +1132,26 @@
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; }
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
     ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
-   { (exit 1); exit 1; }; }
-    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
-    eval "$ac_envvar='$ac_optarg'"
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -650,31 +1159,36 @@
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  { echo "$as_me: error: missing argument to $ac_option" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "missing argument to $ac_option"
 fi
 
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
-do
-  eval ac_val=$`echo $ac_var`
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
-done
+fi
 
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
-              localstatedir libdir includedir oldincludedir infodir mandir
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
 do
-  eval ac_val=$`echo $ac_var`
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
   case $ac_val in
-    [\\/$]* | ?:[\\/]* ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
   esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -688,8 +1202,6 @@
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -701,74 +1213,72 @@
 test "$silent" = yes && exec 6>/dev/null
 
 
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_confdir=`(dirname "$0") 2>/dev/null ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$0" : 'X\(//\)[^/]' \| \
-         X"$0" : 'X\(//\)$' \| \
-         X"$0" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
-echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
+  if test ! -r "$srcdir/$ac_unique_file"; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
-   { (exit 1); exit 1; }; }
-  else
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
-   { (exit 1); exit 1; }; }
-  fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
-  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
-   { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
 
 #
 # Report the --help message.
@@ -777,7 +1287,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures libsrtp2 2.3.0-pre to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -791,15 +1301,12 @@
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
       --srcdir=DIR        find the sources in DIR [configure dir or \`..']
 
-_ACEOF
-
-  cat <<_ACEOF
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                           [$ac_default_prefix]
@@ -814,18 +1321,26 @@
 For better control, use the options below.
 
 Fine tuning of the installation directories:
-  --bindir=DIR           user executables [EPREFIX/bin]
-  --sbindir=DIR          system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR       program executables [EPREFIX/libexec]
-  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
-  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
-  --libdir=DIR           object code libraries [EPREFIX/lib]
-  --includedir=DIR       C header files [PREFIX/include]
-  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --infodir=DIR          info documentation [PREFIX/info]
-  --mandir=DIR           man documentation [PREFIX/man]
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/libsrtp2]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
 _ACEOF
 
   cat <<\_ACEOF
@@ -837,112 +1352,679 @@
 fi
 
 if test -n "$ac_init_help"; then
-
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libsrtp2 2.3.0-pre:";;
+   esac
   cat <<\_ACEOF
 
 Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-debug (compile in dynamic debugging system)
-generic-aesicm (compile in changes for ismacryp)
-syslog (use syslog for error reporting)
-stdout (use stdout for error reporting)
-console (use /dev/console for error reporting)
-gdoi (GDOI key management)
+  --enable-debug-logging  Enable debug logging in all modules
+  --enable-openssl        compile in OpenSSL crypto engine
+  --enable-nss            compile in NSS crypto engine
+  --enable-openssl-kdf    Use OpenSSL KDF algorithm
+  --enable-log-stdout     redirecting logging to stdout
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-openssl-dir      Location of OpenSSL installation
+  --with-nss-dir          Location of NSS installation
+  --with-log-file         Use file for logging
 
 Some influential environment variables:
   CC          C compiler command
   CFLAGS      C compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
-  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
-              headers in a nonstandard directory <include dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  EXTRA_CFLAGS
+              C compiler flags appended to the regular C compiler flags
+              instead of overriding them
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
+  crypto_CFLAGS
+              C compiler flags for crypto, overriding pkg-config
+  crypto_LIBS linker flags for crypto, overriding pkg-config
+  nss_CFLAGS  C compiler flags for nss, overriding pkg-config
+  nss_LIBS    linker flags for nss, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
+Report bugs to <https://github.com/cisco/libsrtp/issues>.
 _ACEOF
+ac_status=$?
 fi
 
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
-  ac_popdir=`pwd`
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d $ac_dir || continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
     ac_builddir=.
 
-if test "$ac_dir" != .; then
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
 
 case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
+  .)  # We are building in place.
     ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
     ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
 esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
-    cd $ac_dir
-    # Check for guested configure; otherwise get Cygnus style configure.
-    if test -f $ac_srcdir/configure.gnu; then
-      echo
-      $SHELL $ac_srcdir/configure.gnu  --help=recursive
-    elif test -f $ac_srcdir/configure; then
-      echo
-      $SHELL $ac_srcdir/configure  --help=recursive
-    elif test -f $ac_srcdir/configure.ac ||
-           test -f $ac_srcdir/configure.in; then
-      echo
-      $ac_configure --help
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi
-    cd $ac_popdir
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
   done
 fi
 
-test -n "$ac_init_help" && exit 0
+test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
+libsrtp2 configure 2.3.0-pre
+generated by GNU Autoconf 2.69
 
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
-  exit 0
+  exit
 fi
-exec 5>config.log
-cat >&5 <<_ACEOF
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by $as_me, which was
-generated by GNU Autoconf 2.57.  Invocation command line was
+It was created by libsrtp2 $as_me 2.3.0-pre, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 
 _ACEOF
+exec 5>>config.log
 {
 cat <<_ASUNAME
 ## --------- ##
@@ -961,7 +2043,7 @@
 /bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
 /usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
 /bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
 /bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
@@ -973,8 +2055,9 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  echo "PATH: $as_dir"
-done
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
 
 } >&5
 
@@ -996,7 +2079,6 @@
 ac_configure_args=
 ac_configure_args0=
 ac_configure_args1=
-ac_sep=
 ac_must_keep_next=false
 for ac_pass in 1 2
 do
@@ -1007,126 +2089,137 @@
     -q | -quiet | --quiet | --quie | --qui | --qu | --q \
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
-    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
     2)
-      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      as_fn_append ac_configure_args1 " '$ac_arg'"
       if test $ac_must_keep_next = true; then
-        ac_must_keep_next=false # Got value, back to normal.
+	ac_must_keep_next=false # Got value, back to normal.
       else
-        case $ac_arg in
-          *=* | --config-cache | -C | -disable-* | --disable-* \
-          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-          | -with-* | --with-* | -without-* | --without-* | --x)
-            case "$ac_configure_args0 " in
-              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-            esac
-            ;;
-          -* ) ac_must_keep_next=true ;;
-        esac
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
       fi
-      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
-      # Get rid of the leading space.
-      ac_sep=" "
+      as_fn_append ac_configure_args " '$ac_arg'"
       ;;
     esac
   done
 done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
 
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
 # would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
   # Save into config.log some information that might help in debugging.
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
-{
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
   (set) 2>&1 |
-    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
       sed -n \
-        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
-    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
-      ;;
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
     *)
-      sed -n \
-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
       ;;
-    esac;
-}
+    esac |
+    sort
+)
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
-      eval ac_val=$`echo $ac_var`
-      echo "$ac_var='"'"'$ac_val'"'"'"
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
-	eval ac_val=$`echo $ac_var`
-        echo "$ac_var='"'"'$ac_val'"'"'"
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
-      sed "/^$/d" confdefs.h | sort
+      cat confdefs.h
       echo
     fi
     test "$ac_signal" != 0 &&
-      echo "$as_me: caught signal $ac_signal"
-    echo "$as_me: exit $exit_status"
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
   } >&5
-  rm -f core core.* *.core &&
-  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
-     ' 0
+' 0
 for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
 
 # Predefined preprocessor variables.
 
@@ -1134,112 +2227,137 @@
 #define PACKAGE_NAME "$PACKAGE_NAME"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_TARNAME "$PACKAGE_TARNAME"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_VERSION "$PACKAGE_VERSION"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_STRING "$PACKAGE_STRING"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
 _ACEOF
 
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
 
 # Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
 fi
-for ac_site_file in $CONFIG_SITE; do
-  if test -r "$ac_site_file"; then
-    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
 
 if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
-    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
-      [\\/]* | ?:[\\/]* ) . $cache_file;;
-      *)                      . ./$cache_file;;
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
     esac
   fi
 else
-  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
-               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+for ac_var in $ac_precious_vars; do
   eval ac_old_set=\$ac_cv_env_${ac_var}_set
   eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
-  eval ac_new_val="\$ac_env_${ac_var}_value"
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
   case $ac_old_set,$ac_new_set in
     set,)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,set)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,);;
     *)
       if test "x$ac_old_val" != "x$ac_new_val"; then
-        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
-echo "$as_me:   former value:  $ac_old_val" >&2;}
-        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
-echo "$as_me:   current value: $ac_new_val" >&2;}
-        ac_cache_corrupted=:
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
       fi;;
   esac
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
       *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
     esac
   fi
 done
 if $ac_cache_corrupted; then
-  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
-   { (exit 1); exit 1; }; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -1249,101 +2367,9 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
-  echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
-  ac_ct_RANLIB=$RANLIB
-  # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_RANLIB"; then
-  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_RANLIB="ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
-  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  RANLIB=$ac_ct_RANLIB
-else
-  RANLIB="$ac_cv_prog_RANLIB"
+EMPTY_CFLAGS="no"
+if test "x$CFLAGS" = "x"; then
+      EMPTY_CFLAGS="yes"
 fi
 
 ac_ext=c
@@ -1354,10 +2380,10 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1367,35 +2393,37 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
+
 fi
 if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1405,39 +2433,50 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-  CC=$ac_ct_CC
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 else
   CC="$ac_cv_prog_CC"
 fi
 
 if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1447,77 +2486,37 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
+
   fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
 fi
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1528,18 +2527,19 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
      fi
     ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 if test $ac_prog_rejected = yes; then
   # We found a bogon in the path, so make sure we never use it.
@@ -1557,24 +2557,25 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
+
 fi
 if test -z "$CC"; then
   if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
+  for ac_prog in cl.exe
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1584,39 +2585,41 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
+
     test -n "$CC" && break
   done
 fi
 if test -z "$CC"; then
   ac_ct_CC=$CC
-  for ac_prog in cl
+  for ac_prog in cl.exe
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1626,67 +2629,78 @@
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
+IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
 else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
+
   test -n "$ac_ct_CC" && break
 done
 
-  CC=$ac_ct_CC
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
 fi
 
 fi
 
 
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
 
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -1698,112 +2712,108 @@
 }
 _ACEOF
 ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output" >&5
-echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
 do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-        ;;
-    conftest.$ac_ext )
-        # This is the source file.
-        ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
     [ab].out )
-        # We found the default executable, but exeext='' is most
-        # certainly right.
-        break;;
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
     *.* )
-        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-        # FIXME: I believe we export ac_cv_exeext for Libtool,
-        # but it would be cool to find out if it's true.  Does anybody
-        # maintain Libtool? --akim.
-        export ac_cv_exeext
-        break;;
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
     * )
-        break;;
+	break;;
   esac
 done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
 else
-  echo "$as_me: failed program was:" >&5
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 fi
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
 
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
 # work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -1811,39 +2821,90 @@
 for ac_file in conftest.exe conftest conftest.*; do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-          export ac_cv_exeext
-          break;;
+	  break;;
     * ) break;;
   esac
 done
 else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -1855,46 +2916,46 @@
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
     *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
        break;;
   esac
 done
 else
-  echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -1908,46 +2969,34 @@
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_compiler_gnu=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
+  ac_compiler_gnu=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -1958,29 +3007,49 @@
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_prog_cc_g=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-ac_cv_prog_cc_g=no
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
@@ -1996,24 +3065,18 @@
     CFLAGS=
   fi
 fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_cv_prog_cc_stdc=no
+  ac_cv_prog_cc_c89=no
 ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -2032,6 +3095,21 @@
   va_end (v);
   return s;
 }
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
 int test (int i, double x);
 struct s1 {int (*f) (int a);};
 struct s2 {int (*f) (double a);};
@@ -2046,353 +3124,57 @@
   return 0;
 }
 _ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX			-qlanglvl=ansi
-# Ultrix and OSF/1	-std1
-# HP-UX 10.20 and later	-Ae
-# HP-UX older versions	-Aa -D_HPUX_SOURCE
-# SVR4			-Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
 fi
-rm -f conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
-rm -f conftest.$ac_ext conftest.$ac_objext
+rm -f conftest.$ac_ext
 CC=$ac_save_CC
 
 fi
-
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
   *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
 esac
-
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   ''\
-   '#include <stdlib.h>' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdlib.h>
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if test "x$ac_cv_prog_cc_c89" != xno; then :
 
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
-fi
 
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-
-
-
-echo "$as_me:$LINENO: checking for socket in -lsocket" >&5
-echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6
-if test "${ac_cv_lib_socket_socket+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char socket ();
-int
-main ()
-{
-socket ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_socket_socket=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_socket_socket=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5
-echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6
-if test $ac_cv_lib_socket_socket = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSOCKET 1
-_ACEOF
-
-  LIBS="-lsocket $LIBS"
-
-fi
-
-
-echo "$as_me:$LINENO: checking for srtp_init in -lsrtp" >&5
-echo $ECHO_N "checking for srtp_init in -lsrtp... $ECHO_C" >&6
-if test "${ac_cv_lib_srtp_srtp_init+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsrtp  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-/* Override any gcc2 internal prototype to avoid an error.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char srtp_init ();
-int
-main ()
-{
-srtp_init ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_lib_srtp_srtp_init=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_srtp_srtp_init=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_srtp_srtp_init" >&5
-echo "${ECHO_T}$ac_cv_lib_srtp_srtp_init" >&6
-if test $ac_cv_lib_srtp_srtp_init = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBSRTP 1
-_ACEOF
-
-  LIBS="-lsrtp $LIBS"
-
-fi
-
-
-
-echo "$as_me:$LINENO: checking for /dev/urandom" >&5
-echo $ECHO_N "checking for /dev/urandom... $ECHO_C" >&6
-if test "${ac_cv_file__dev_urandom+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  test "$cross_compiling" = yes &&
-  { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5
-echo "$as_me: error: cannot check for file existence when cross compiling" >&2;}
-   { (exit 1); exit 1; }; }
-if test -r "/dev/urandom"; then
-  ac_cv_file__dev_urandom=yes
-else
-  ac_cv_file__dev_urandom=no
-fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_file__dev_urandom" >&5
-echo "${ECHO_T}$ac_cv_file__dev_urandom" >&6
-if test $ac_cv_file__dev_urandom = yes; then
-  DEV_URANDOM=1
-else
-  DEV_URANDOM=0
-fi
-
-if test $DEV_URANDOM = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define DEV_URANDOM 1
-_ACEOF
-
-   RNG_OBJS=crypto/rng/rand_source.c
-
-fi
-
-
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
     for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
@@ -2406,91 +3188,43 @@
   # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifdef __STDC__
 # include <limits.h>
 #else
 # include <assert.h>
 #endif
-                     Syntax error
+		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
 
+else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+if ac_fn_c_try_cpp "$LINENO"; then :
   # Broken: success on invalid input.
 continue
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
   # Passes both tests.
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
   break
 fi
 
@@ -2502,8 +3236,8 @@
 else
   ac_cv_prog_CPP=$CPP
 fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
@@ -2513,98 +3247,49 @@
   # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifdef __STDC__
 # include <limits.h>
 #else
 # include <assert.h>
 #endif
-                     Syntax error
+		     Syntax error
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
 
+else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether non-existent headers
+  # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+if ac_fn_c_try_cpp "$LINENO"; then :
   # Broken: success on invalid input.
 continue
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
   # Passes both tests.
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
 else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -2613,33 +3298,860 @@
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
-    then ac_cv_prog_egrep='grep -E'
-    else ac_cv_prog_egrep='egrep'
-    fi
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
 fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
-
-
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
 else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2654,42 +4166,23 @@
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_header_stdc=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_header_stdc=no
+  ac_cv_header_stdc=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <string.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
 else
   ac_cv_header_stdc=no
 fi
@@ -2699,19 +4192,14 @@
 
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
+  $EGREP "free" >/dev/null 2>&1; then :
+
 else
   ac_cv_header_stdc=no
 fi
@@ -2721,25 +4209,21 @@
 
 if test $ac_cv_header_stdc = yes; then
   # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
+  if test "$cross_compiling" = yes; then :
   :
 else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ctype.h>
+#include <stdlib.h>
 #if ((' ' & 0x0FF) == 0x020)
 # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
 # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
 #else
 # define ISLOWER(c) \
-                   (('a' <= (c) && (c) <= 'i') \
-                     || ('j' <= (c) && (c) <= 'r') \
-                     || ('s' <= (c) && (c) <= 'z'))
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
 # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
 #endif
 
@@ -2750,101 +4234,40 @@
   int i;
   for (i = 0; i < 256; i++)
     if (XOR (islower (i), ISLOWER (i))
-        || toupper (i) != TOUPPER (i))
-      exit(2);
-  exit (0);
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_run "$LINENO"; then :
 
-( exit $ac_status )
-ac_cv_header_stdc=no
+else
+  ac_cv_header_stdc=no
 fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
 fi
 fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
 if test $ac_cv_header_stdc = yes; then
 
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
 fi
 
 # On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
 for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                  inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  eval "$as_ac_Header=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_Header=no"
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
@@ -2852,1075 +4275,831 @@
 done
 
 
-
-for ac_header in stdlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
 
-ac_header_compiler=no
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+#include <sys/types.h>
+	     #include <sys/param.h>
 
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in stdint.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in sys/uio.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in machine/types.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in sys/int_types.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-for ac_header in syslog.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
-  # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
-  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null; then
-  if test -s conftest.err; then
-    ac_cpp_err=$ac_c_preproc_warn_flag
-  else
-    ac_cpp_err=
-  fi
-else
-  ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc in
-  yes:no )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-  no:yes )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    (
-      cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
-    ) |
-      sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-echo "$as_me:$LINENO: checking for uint16_t" >&5
-echo $ECHO_N "checking for uint16_t... $ECHO_C" >&6
-if test "${ac_cv_type_uint16_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
 int
 main ()
 {
-if ((uint16_t *) 0)
-  return 0;
-if (sizeof (uint16_t))
-  return 0;
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_uint16_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
 
-ac_cv_type_uint16_t=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
-echo "${ECHO_T}$ac_cv_type_uint16_t" >&6
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
 
-
-echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
-echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
-if test "${ac_cv_c_const+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+case $host_cpu in
+  i*86 | x86_64 )
+
+$as_echo "#define CPU_CISC 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_X86 1" >>confdefs.h
+
+    ;;
+  * )
+
+$as_echo "#define CPU_RISC 1" >>confdefs.h
+
+    ;;
+esac
+
+case $host_os in
+  *cygwin*|*mingw* )
+    EXE=.exe
+    ;;
+  * )
+    EXE=""
+    ;;
+esac
+   # define executable suffix; this is needed for `make clean'
+
+supported_cflags=""
+if test "$EMPTY_CFLAGS" = "no"; then
+  supported_cflags="$CFLAGS"
+fi
+
+WERROR=""
+for w in -Werror -errwarn; do
+  if test "x$WERROR" = "x"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts $w" >&5
+$as_echo_n "checking whether ${CC-c} accepts $w... " >&6; }
+    save_cflags="$CFLAGS"
+    if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$w"
+else
+  CFLAGS="$CFLAGS $w"
+fi
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  WERROR="$w"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts -fPIC" >&5
+$as_echo_n "checking whether ${CC-c} accepts -fPIC... " >&6; }
+save_cflags="$CFLAGS"
+if test "x$CFLAGS" = "x"; then :
+  CFLAGS="-fPIC"
+else
+  CFLAGS="$CFLAGS -fPIC"
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if test "x$supported_cflags" = "x"; then :
+  supported_cflags="-fPIC"
+else
+  supported_cflags="$supported_cflags -fPIC"
+fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test "$EMPTY_CFLAGS" = "yes"; then
+  for f in -Wall -pedantic -Wstrict-prototypes; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts $f" >&5
+$as_echo_n "checking whether ${CC-c} accepts $f... " >&6; }
+    save_cflags="$CFLAGS"
+    if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$f"
+else
+  CFLAGS="$CFLAGS $f"
+fi
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if test "x$supported_cflags" = "x"; then :
+  supported_cflags="$f"
+else
+  supported_cflags="$supported_cflags $f"
+fi
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+
+  OOPT=""
+  for f in -O4 -O3; do
+    if test "x$OOPT" = "x"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts $f" >&5
+$as_echo_n "checking whether ${CC-c} accepts $f... " >&6; }
+      save_cflags="$CFLAGS"
+      if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$f"
+else
+  CFLAGS="$CFLAGS $f"
+fi
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if test "x$supported_cflags" = "x"; then :
+  supported_cflags="$f"
+else
+  supported_cflags="$supported_cflags $f"
+fi
+         OOPT="$f"
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+  done
+
+  for f in -fexpensive-optimizations -funroll-loops; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts $f" >&5
+$as_echo_n "checking whether ${CC-c} accepts $f... " >&6; }
+    save_cflags="$CFLAGS"
+    if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$f"
+else
+  CFLAGS="$CFLAGS $f"
+fi
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if test "x$supported_cflags" = "x"; then :
+  supported_cflags="$f"
+else
+  supported_cflags="$supported_cflags $f"
+fi
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+fi
+
+for f in -Wno-language-extension-token; do
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC-c} accepts $f" >&5
+$as_echo_n "checking whether ${CC-c} accepts $f... " >&6; }
+  save_cflags="$CFLAGS"
+  testf=$(echo "$f" | $SED 's|-Wno-\(.*\)|-W\1|g')
+  if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$testf"
+else
+  CFLAGS="$CFLAGS $testf"
+fi
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void) { return 0; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if test "x$supported_cflags" = "x"; then :
+  supported_cflags="$f"
+else
+  supported_cflags="$supported_cflags $f"
+fi
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  CFLAGS="$save_cflags"
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+
+CFLAGS="$supported_cflags"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in unistd.h byteswap.h stdint.h sys/uio.h inttypes.h sys/types.h machine/types.h sys/int_types.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in sys/socket.h netinet/in.h arpa/inet.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in windows.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+ for ac_header in winsock2.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_winsock2_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINSOCK2_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+done
+
+
+ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default"
+if test "x$ac_cv_type_int8_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT8_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint8_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT8_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default"
+if test "x$ac_cv_type_int16_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT16_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint16_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT16_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default"
+if test "x$ac_cv_type_int32_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT32_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint32_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT32_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default"
+if test "x$ac_cv_type_uint64_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT64_T 1
+_ACEOF
+
+
+fi
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
 main ()
 {
-/* FIXME: Include the comments suggested by Paul. */
+
 #ifndef __cplusplus
-  /* Ultrix mips cc rejects this.  */
+  /* Ultrix mips cc rejects this sort of thing.  */
   typedef int charset[2];
-  const charset x;
+  const charset cs = { 0, 0 };
   /* SunOS 4.1.1 cc rejects this.  */
-  char const *const *ccp;
-  char **p;
+  char const *const *pcpcc;
+  char **ppc;
   /* NEC SVR4.0.2 mips cc rejects this.  */
   struct point {int x, y;};
   static struct point const zero = {0,0};
@@ -3929,16 +5108,18 @@
      an arm of an if-expression whose if-part is not a constant
      expression */
   const char *g = "string";
-  ccp = &g + (g ? g-g : 0);
+  pcpcc = &g + (g ? g-g : 0);
   /* HPUX 7.0 cc rejects these. */
-  ++ccp;
-  p = (char**) ccp;
-  ccp = (char const *const *) p;
-  { /* SCO 3.2v4 cc rejects this.  */
-    char *t;
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
     char const *s = 0 ? (char *) 0 : (char const *) 0;
 
     *t++ = 0;
+    if (s) return 0;
   }
   { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
     int x[] = {25, 17};
@@ -3950,64 +5131,45 @@
     iptr p = 0;
     ++p;
   }
-  { /* AIX XL C 1.02.0.0 rejects this saying
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
        "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; };
-    struct s *b; b->j = 5;
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
   }
   { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
     const int foo = 10;
+    if (!foo) return 0;
   }
+  return !cs[0] && !zero.x;
 #endif
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_c_const=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_c_const=no
+  ac_cv_c_const=no
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
-echo "${ECHO_T}$ac_cv_c_const" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
 if test $ac_cv_c_const = no; then
 
-cat >>confdefs.h <<\_ACEOF
-#define const
-_ACEOF
+$as_echo "#define const /**/" >>confdefs.h
 
 fi
 
-echo "$as_me:$LINENO: checking for inline" >&5
-echo $ECHO_N "checking for inline... $ECHO_C" >&6
-if test "${ac_cv_c_inline+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifndef __cplusplus
 typedef int foo_t;
@@ -4016,677 +5178,1303 @@
 #endif
 
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_c_inline=$ac_kw; break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
 done
 
 fi
-echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
-echo "${ECHO_T}$ac_cv_c_inline" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
 case $ac_cv_c_inline in
   inline | yes) ;;
-  no)
-cat >>confdefs.h <<\_ACEOF
-#define inline
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
 _ACEOF
- ;;
-  *)  cat >>confdefs.h <<_ACEOF
-#define inline $ac_cv_c_inline
-_ACEOF
- ;;
+    ;;
 esac
 
-echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6
-if test "${ac_cv_type_size_t+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-if ((size_t *) 0)
-  return 0;
-if (sizeof (size_t))
-  return 0;
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_type_size_t=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
 
-ac_cv_type_size_t=no
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6
-if test $ac_cv_type_size_t = yes; then
-  :
 else
 
 cat >>confdefs.h <<_ACEOF
-#define size_t unsigned
+#define size_t unsigned int
 _ACEOF
 
 fi
 
 
-echo "$as_me:$LINENO: checking for working memcmp" >&5
-echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
-if test "${ac_cv_func_memcmp_working+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_memcmp_working=no
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
+for ac_func in socket inet_aton usleep sigaction
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+
+fi
+done
+
+
+if test "x$ac_cv_func_socket" = "xno"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
+$as_echo_n "checking for socket in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_socket+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-int
-main ()
-{
-
-  /* Some versions of memcmp are not 8-bit clean.  */
-  char c0 = 0x40, c1 = 0x80, c2 = 0x81;
-  if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
-    exit (1);
-
-  /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
-     or more and with at least one buffer not starting on a 4-byte boundary.
-     William Lewis provided this test program.   */
-  {
-    char foo[21];
-    char bar[21];
-    int i;
-    for (i = 0; i < 4; i++)
-      {
-        char *a = foo + i;
-        char *b = bar + i;
-        strcpy (a, "--------01111111");
-        strcpy (b, "--------10000000");
-        if (memcmp (a, b, 16) >= 0)
-          exit (1);
-      }
-    exit (0);
-  }
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_memcmp_working=yes
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_memcmp_working=no
-fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
-echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
-test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext"
-
-
-
-
-for ac_func in socket strerror inet_aton
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-/* Override any gcc2 internal prototype to avoid an error.  */
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
 #ifdef __cplusplus
 extern "C"
-{
 #endif
-/* We use char because int might match the return type of a gcc2
-   builtin and then its argument prototype would still apply.  */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
+char socket ();
 int
 main ()
 {
-return f != $ac_func;
+return socket ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  eval "$as_ac_var=yes"
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_socket=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
+  ac_cv_lib_socket_socket=no
 fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
+$as_echo "$ac_cv_lib_socket_socket" >&6; }
+if test "x$ac_cv_lib_socket_socket" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_LIBSOCKET 1
 _ACEOF
 
+  LIBS="-lsocket $LIBS"
+
 fi
-done
 
-
-echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
-echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
-if test "${ac_cv_c_bigendian+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # See if sys/param.h defines the BYTE_ORDER macro.
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lwsock32" >&5
+$as_echo_n "checking for socket in -lwsock32... " >&6; }
+  SAVELIBS="$LIBS"
+  LIBS="$LIBS -lwsock32"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/param.h>
 
-int
-main ()
+#include <winsock2.h>
+int main(void)
 {
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif
-
-  ;
-  return 0;
+    int fd = socket(0, 0, 0);
+    if (fd < 0)
+      return -1;
+    else
+      return 0;
 }
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  # It does; now see whether it defined to BIG_ENDIAN or not.
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/param.h>
 
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
-
-  ;
-  return 0;
-}
 _ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_c_bigendian=yes
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_socket=yes
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_c_bigendian=no
+  LIBS="$SAVELIBS"
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debug logging in all modules" >&5
+$as_echo_n "checking whether to enable debug logging in all modules... " >&6; }
+# Check whether --enable-debug-logging was given.
+if test "${enable_debug_logging+set}" = set; then :
+  enableval=$enable_debug_logging;
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  enable_debug_logging=no
+fi
 
-# It does not; compile a test program.
-if test "$cross_compiling" = yes; then
-  # try to guess the endianness by grepping values into an object file
-  ac_cv_c_bigendian=unknown
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
-short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
-int
-main ()
-{
- _ascii (); _ebcdic ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-         { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
-  ac_cv_c_bigendian=yes
+if test "$enable_debug_logging" = "yes"; then
+
+$as_echo "#define ENABLE_DEBUG_LOGGING 1" >>confdefs.h
+
 fi
-if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
-  if test "$ac_cv_c_bigendian" = unknown; then
-    ac_cv_c_bigendian=no
-  else
-    # finding both strings is unlikely to happen, but who knows?
-    ac_cv_c_bigendian=unknown
-  fi
-fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_debug_logging" >&5
+$as_echo "$enable_debug_logging" >&6; }
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-else
-  cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-int
-main ()
-{
-  /* Are we little or big endian?  From Harbison&Steele.  */
-  union
-  {
-    long l;
-    char c[sizeof (long)];
-  } u;
-  u.l = 1;
-  exit (u.c[sizeof (long) - 1] == 1);
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_c_bigendian=no
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_bigendian=yes
-fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-fi
-rm -f conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
-echo "${ECHO_T}$ac_cv_c_bigendian" >&6
-case $ac_cv_c_bigendian in
-  yes)
-
-cat >>confdefs.h <<\_ACEOF
-#define WORDS_BIGENDIAN 1
-_ACEOF
- ;;
-  no)
-     ;;
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
   *)
-    { { echo "$as_me:$LINENO: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&5
-echo "$as_me: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
-   { (exit 1); exit 1; }; } ;;
-esac
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f $ac_dir/shtool; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
   fi
 done
-if test -z "$ac_aux_dir"; then
-  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
-echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"
-ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+  done
+IFS=$as_save_IFS
 
-# Make sure we can run config.sub.
-$ac_config_sub sun4 >/dev/null 2>&1 ||
-  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
-echo "$as_me: error: cannot run $ac_config_sub" >&2;}
-   { (exit 1); exit 1; }; }
-
-echo "$as_me:$LINENO: checking build system type" >&5
-echo $ECHO_N "checking build system type... $ECHO_C" >&6
-if test "${ac_cv_build+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_build_alias=$build_alias
-test -z "$ac_cv_build_alias" &&
-  ac_cv_build_alias=`$ac_config_guess`
-test -z "$ac_cv_build_alias" &&
-  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
-echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
-   { (exit 1); exit 1; }; }
-ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_build" >&5
-echo "${ECHO_T}$ac_cv_build" >&6
-build=$ac_cv_build
-build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-echo "$as_me:$LINENO: checking host system type" >&5
-echo $ECHO_N "checking host system type... $ECHO_C" >&6
-if test "${ac_cv_host+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_host_alias=$host_alias
-test -z "$ac_cv_host_alias" &&
-  ac_cv_host_alias=$ac_cv_build_alias
-ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
-  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
-echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
-   { (exit 1); exit 1; }; }
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_host" >&5
-echo "${ECHO_T}$ac_cv_host" >&6
-host=$ac_cv_host
-host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-
-
-if test $host_cpu = x86; then
-   echo "x86 cpu found" # should use inline assembly
-fi
-
-case $host_cpu in
-     i*86 )
-	cat >>confdefs.h <<\_ACEOF
-#define CPU_CISC 1
-_ACEOF
-;;
-	* )
-	cat >>confdefs.h <<\_ACEOF
-#define CPU_RISC 1
-_ACEOF
-;;
+  ;;
 esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
 
-case $host_os in
-  *cygwin* )
-	      cat >>confdefs.h <<\_ACEOF
-#define HAVE_MS_TYPES 1
-_ACEOF
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-	      EXE=.exe;;
-         * )  EXE="";;
+  ;;
 esac
-
-   # define executable suffix; this is needed for `make clean'
-
-# Check whether --enable-debug or --disable-debug was given.
-if test "${enable_debug+set}" = set; then
-  enableval="$enable_debug"
-  USE_DEBUG=0
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
 else
-  USE_DEBUG=1
-fi;
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 
-if test $USE_DEBUG = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define ENABLE_DEBUGGING 1
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
+if test "x$PKG_CONFIG" != "x"; then :
+  PKG_CONFIG="$PKG_CONFIG --static"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to leverage OpenSSL crypto" >&5
+$as_echo_n "checking whether to leverage OpenSSL crypto... " >&6; }
+# Check whether --enable-openssl was given.
+if test "${enable_openssl+set}" = set; then :
+  enableval=$enable_openssl;
+else
+  enable_openssl=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_openssl" >&5
+$as_echo "$enable_openssl" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to leverage NSS crypto" >&5
+$as_echo_n "checking whether to leverage NSS crypto... " >&6; }
+# Check whether --enable-nss was given.
+if test "${enable_nss+set}" = set; then :
+  enableval=$enable_nss;
+else
+  enable_nss=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_nss" >&5
+$as_echo "$enable_nss" >&6; }
+
+if test "$enable_openssl" = "yes"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for user specified OpenSSL directory" >&5
+$as_echo_n "checking for user specified OpenSSL directory... " >&6; }
+
+# Check whether --with-openssl-dir was given.
+if test "${with_openssl_dir+set}" = set; then :
+  withval=$with_openssl_dir; if test "x$PKG_CONFIG" != "x" && test -f $with_openssl_dir/lib/pkgconfig/libcrypto.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_openssl_dir" >&5
+$as_echo "$with_openssl_dir" >&6; }
+       elif test -d $with_openssl_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_openssl_dir/include"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_openssl_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_openssl_dir/lib"
+         fi
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_openssl_dir" >&5
+$as_echo "$with_openssl_dir" >&6; }
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: invalid" >&5
+$as_echo "invalid" >&6; }
+         { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Invalid OpenSSL location: $with_openssl_dir
+See \`config.log' for more details" "$LINENO" 5; }
+       fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+   if test "x$PKG_CONFIG" != "x"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypto" >&5
+$as_echo_n "checking for crypto... " >&6; }
+
+if test -n "$crypto_CFLAGS"; then
+    pkg_cv_crypto_CFLAGS="$crypto_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 1.0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libcrypto >= 1.0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_crypto_CFLAGS=`$PKG_CONFIG --cflags "libcrypto >= 1.0.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$crypto_LIBS"; then
+    pkg_cv_crypto_LIBS="$crypto_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto >= 1.0.1\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libcrypto >= 1.0.1") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_crypto_LIBS=`$PKG_CONFIG --libs "libcrypto >= 1.0.1" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        crypto_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcrypto >= 1.0.1" 2>&1`
+        else
+	        crypto_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcrypto >= 1.0.1" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$crypto_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (libcrypto >= 1.0.1) were not met:
+
+$crypto_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables crypto_CFLAGS
+and crypto_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables crypto_CFLAGS
+and crypto_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	crypto_CFLAGS=$pkg_cv_crypto_CFLAGS
+	crypto_LIBS=$pkg_cv_crypto_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	CFLAGS="$CFLAGS $crypto_CFLAGS"
+        LIBS="$crypto_LIBS $LIBS"
+fi
+   else
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find libdl" >&5
+$as_echo "$as_me: WARNING: can't find libdl" >&2;}
+fi
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5
+$as_echo_n "checking for inflate in -lz... " >&6; }
+if ${ac_cv_lib_z_inflate+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inflate ();
+int
+main ()
+{
+return inflate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_inflate=yes
+else
+  ac_cv_lib_z_inflate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5
+$as_echo "$ac_cv_lib_z_inflate" >&6; }
+if test "x$ac_cv_lib_z_inflate" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+  LIBS="-lz $LIBS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find libz" >&5
+$as_echo "$as_me: WARNING: can't find libz" >&2;}
+fi
+
+   fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_EncryptInit" >&5
+$as_echo_n "checking for library containing EVP_EncryptInit... " >&6; }
+if ${ac_cv_search_EVP_EncryptInit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EVP_EncryptInit ();
+int
+main ()
+{
+return EVP_EncryptInit ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypto; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_EVP_EncryptInit=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_EVP_EncryptInit+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_EVP_EncryptInit+:} false; then :
+
+else
+  ac_cv_search_EVP_EncryptInit=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_EncryptInit" >&5
+$as_echo "$ac_cv_search_EVP_EncryptInit" >&6; }
+ac_res=$ac_cv_search_EVP_EncryptInit
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find openssl >= 1.0.1 crypto lib
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_aes_128_ctr" >&5
+$as_echo_n "checking for library containing EVP_aes_128_ctr... " >&6; }
+if ${ac_cv_search_EVP_aes_128_ctr+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EVP_aes_128_ctr ();
+int
+main ()
+{
+return EVP_aes_128_ctr ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypto; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_EVP_aes_128_ctr=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_EVP_aes_128_ctr+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_EVP_aes_128_ctr+:} false; then :
+
+else
+  ac_cv_search_EVP_aes_128_ctr=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_aes_128_ctr" >&5
+$as_echo "$ac_cv_search_EVP_aes_128_ctr" >&6; }
+ac_res=$ac_cv_search_EVP_aes_128_ctr
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find openssl >= 1.0.1 crypto lib
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_aes_128_gcm" >&5
+$as_echo_n "checking for library containing EVP_aes_128_gcm... " >&6; }
+if ${ac_cv_search_EVP_aes_128_gcm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char EVP_aes_128_gcm ();
+int
+main ()
+{
+return EVP_aes_128_gcm ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypto; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_EVP_aes_128_gcm=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_EVP_aes_128_gcm+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_EVP_aes_128_gcm+:} false; then :
+
+else
+  ac_cv_search_EVP_aes_128_gcm=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_aes_128_gcm" >&5
+$as_echo "$ac_cv_search_EVP_aes_128_gcm" >&6; }
+ac_res=$ac_cv_search_EVP_aes_128_gcm
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find openssl >= 1.0.1 crypto lib
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+
+$as_echo "#define GCM 1" >>confdefs.h
+
+
+$as_echo "#define OPENSSL 1" >>confdefs.h
+
+   AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o"
+   HMAC_OBJS=crypto/hash/hmac_ossl.o
+   USE_EXTERNAL_CRYPTO=1
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OPENSSL_cleanse is broken" >&5
+$as_echo_n "checking if OPENSSL_cleanse is broken... " >&6; }
+   if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+     #include <stdio.h>
+     #include <openssl/crypto.h>
+
+int
+main ()
+{
+
+     #define BUFFER_SIZE (16)
+     char buffer[BUFFER_SIZE];
+     int i;
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       buffer[i] = i & 0xff;
+     }
+     OPENSSL_cleanse(buffer, BUFFER_SIZE);
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       if (buffer[i]) {
+         printf("Buffer contents not zero at position %d (is %d)\n", i,
+             buffer[i]);
+         return 1;
+       }
+     }
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  openssl_cleanse_broken=no
+else
+
+     openssl_cleanse_broken=yes
+
+$as_echo "#define OPENSSL_CLEANSE_BROKEN 1" >>confdefs.h
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $openssl_cleanse_broken" >&5
+$as_echo "$openssl_cleanse_broken" >&6; }
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to leverage OpenSSL KDF algorithm" >&5
+$as_echo_n "checking whether to leverage OpenSSL KDF algorithm... " >&6; }
+   # Check whether --enable-openssl-kdf was given.
+if test "${enable_openssl_kdf+set}" = set; then :
+  enableval=$enable_openssl_kdf;
+else
+  enable_openssl_kdf=no
+fi
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_openssl_kdf" >&5
+$as_echo "$enable_openssl_kdf" >&6; }
+   if test "$enable_openssl_kdf" = "yes"; then
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kdf_srtp" >&5
+$as_echo_n "checking for library containing kdf_srtp... " >&6; }
+if ${ac_cv_search_kdf_srtp+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char kdf_srtp ();
+int
+main ()
+{
+return kdf_srtp ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' crypto; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_kdf_srtp=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_kdf_srtp+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_kdf_srtp+:} false; then :
+
+else
+  ac_cv_search_kdf_srtp=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kdf_srtp" >&5
+$as_echo "$ac_cv_search_kdf_srtp" >&6; }
+ac_res=$ac_cv_search_kdf_srtp
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find openssl KDF lib
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+
+$as_echo "#define OPENSSL_KDF 1" >>confdefs.h
+
+   fi
+elif test "$enable_nss" = "yes"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for user specified NSS directory" >&5
+$as_echo_n "checking for user specified NSS directory... " >&6; }
+
+# Check whether --with-nss-dir was given.
+if test "${with_nss_dir+set}" = set; then :
+  withval=$with_nss_dir; if test "x$PKG_CONFIG" != "x" && test -f $with_nss_dir/lib/pkgconfig/nss.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_nss_dir" >&5
+$as_echo "$with_nss_dir" >&6; }
+       elif test -d $with_nss_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_nss_dir/include"
+         CFLAGS="$CFLAGS -I$with_nss_dir/../public/nss"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_nss_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_nss_dir/lib"
+         fi
+         nss_skip_pkg_config=yes
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_nss_dir" >&5
+$as_echo "$with_nss_dir" >&6; }
+       else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: invalid" >&5
+$as_echo "invalid" >&6; }
+         { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Invalid NSS location: $with_nss_dir
+See \`config.log' for more details" "$LINENO" 5; }
+       fi
+       CRYPTO_LIBDIR=$with_nss_dir/lib
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+   if test "x$PKG_CONFIG" != "x" && test "$nss_skip_pkg_config" != "yes"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for nss" >&5
+$as_echo_n "checking for nss... " >&6; }
+
+if test -n "$nss_CFLAGS"; then
+    pkg_cv_nss_CFLAGS="$nss_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nss\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nss") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_nss_CFLAGS=`$PKG_CONFIG --cflags "nss" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$nss_LIBS"; then
+    pkg_cv_nss_LIBS="$nss_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nss\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "nss") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_nss_LIBS=`$PKG_CONFIG --libs "nss" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        nss_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "nss" 2>&1`
+        else
+	        nss_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "nss" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$nss_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (nss) were not met:
+
+$nss_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables nss_CFLAGS
+and nss_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables nss_CFLAGS
+and nss_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	nss_CFLAGS=$pkg_cv_nss_CFLAGS
+	nss_LIBS=$pkg_cv_nss_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	CFLAGS="$CFLAGS $nss_CFLAGS"
+         LIBS="$nss_LIBS $LIBS"
+fi
+   else
+     for ac_header in nss.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "nss.h" "ac_cv_header_nss_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_nss_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_NSS_H 1
+_ACEOF
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find useable NSS headers
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+done
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PR_GetError in -lnspr4" >&5
+$as_echo_n "checking for PR_GetError in -lnspr4... " >&6; }
+if ${ac_cv_lib_nspr4_PR_GetError+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnspr4  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char PR_GetError ();
+int
+main ()
+{
+return PR_GetError ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nspr4_PR_GetError=yes
+else
+  ac_cv_lib_nspr4_PR_GetError=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nspr4_PR_GetError" >&5
+$as_echo "$ac_cv_lib_nspr4_PR_GetError" >&6; }
+if test "x$ac_cv_lib_nspr4_PR_GetError" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSPR4 1
+_ACEOF
+
+  LIBS="-lnspr4 $LIBS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find libnspr4" >&5
+$as_echo "$as_me: WARNING: can't find libnspr4" >&2;}
+fi
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NSS_NoDB_Init in -lnss3" >&5
+$as_echo_n "checking for NSS_NoDB_Init in -lnss3... " >&6; }
+if ${ac_cv_lib_nss3_NSS_NoDB_Init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnss3  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char NSS_NoDB_Init ();
+int
+main ()
+{
+return NSS_NoDB_Init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nss3_NSS_NoDB_Init=yes
+else
+  ac_cv_lib_nss3_NSS_NoDB_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss3_NSS_NoDB_Init" >&5
+$as_echo "$ac_cv_lib_nss3_NSS_NoDB_Init" >&6; }
+if test "x$ac_cv_lib_nss3_NSS_NoDB_Init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSS3 1
+_ACEOF
+
+  LIBS="-lnss3 $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "can't find useable libnss3
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+   fi
+
+
+$as_echo "#define GCM 1" >>confdefs.h
+
+
+$as_echo "#define NSS 1" >>confdefs.h
+
+   AES_ICM_OBJS="crypto/cipher/aes_icm_nss.o crypto/cipher/aes_gcm_nss.o"
+
+   # TODO(RLB): Use NSS for HMAC
+   HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
+
+   # TODO(RLB): Use NSS for KDF
+
+   USE_EXTERNAL_CRYPTO=1
+
+else
+   AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o"
+   HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
+fi
+
+
+
+
+PCAP_LIB=""
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_create in -lpcap" >&5
+$as_echo_n "checking for pcap_create in -lpcap... " >&6; }
+if ${ac_cv_lib_pcap_pcap_create+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpcap  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pcap_create ();
+int
+main ()
+{
+return pcap_create ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pcap_pcap_create=yes
+else
+  ac_cv_lib_pcap_pcap_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcap_pcap_create" >&5
+$as_echo "$ac_cv_lib_pcap_pcap_create" >&6; }
+if test "x$ac_cv_lib_pcap_pcap_create" = xyes; then :
+  PCAP_LIB="-lpcap"
+
+$as_echo "#define HAVE_PCAP 1" >>confdefs.h
+
+   HAVE_PCAP=1
 
 fi
 
-# Check whether --enable-generic-aesicm or --disable-generic-aesicm was given.
-if test "${enable_generic_aesicm+set}" = set; then
-  enableval="$enable_generic_aesicm"
-  GENERIC_AESICM=0
-else
-  GENERIC_AESICM=1
-fi;
 
-if test $GENERIC_AESICM = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define GENERIC_AESICM 1
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcap_create in -lwpcap" >&5
+$as_echo_n "checking for pcap_create in -lwpcap... " >&6; }
+if ${ac_cv_lib_wpcap_pcap_create+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwpcap  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pcap_create ();
+int
+main ()
+{
+return pcap_create ();
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_wpcap_pcap_create=yes
+else
+  ac_cv_lib_wpcap_pcap_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wpcap_pcap_create" >&5
+$as_echo "$ac_cv_lib_wpcap_pcap_create" >&6; }
+if test "x$ac_cv_lib_wpcap_pcap_create" = xyes; then :
+  PCAP_LIB="-lwpcap"
+
+$as_echo "#define HAVE_PCAP 1" >>confdefs.h
+
+   HAVE_PCAP=1
 
 fi
 
-# Check whether --enable-syslog or --disable-syslog was given.
-if test "${enable_syslog+set}" = set; then
-  enableval="$enable_syslog"
-  USE_SYSLOG=1
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to redirect logging to stdout" >&5
+$as_echo_n "checking whether to redirect logging to stdout... " >&6; }
+# Check whether --enable-log-stdout was given.
+if test "${enable_log_stdout+set}" = set; then :
+  enableval=$enable_log_stdout;
 else
-  USE_SYSLOG=0
-fi;
-
-if test $USE_SYSLOG = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define USE_SYSLOG 1
-_ACEOF
-
+  enable_log_stdout=no
 fi
 
-# Check whether --enable-stdout or --disable-stdout was given.
-if test "${enable_stdout+set}" = set; then
-  enableval="$enable_stdout"
-  ERR_STDOUT=0
-else
-  ERR_STDOUT=1
-fi;
+if test "$enable_log_stdout" = "yes"; then
 
-if test $ERR_STDOUT = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define ERR_REPORTING_STDOUT 1
-_ACEOF
+$as_echo "#define ERR_REPORTING_STDOUT 1" >>confdefs.h
 
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_log_stdout" >&5
+$as_echo "$enable_log_stdout" >&6; }
 
-# Check whether --enable-console or --disable-console was given.
-if test "${enable_console+set}" = set; then
-  enableval="$enable_console"
-  ERR_FILE=1
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking wheather to use a file for logging" >&5
+$as_echo_n "checking wheather to use a file for logging... " >&6; }
+
+# Check whether --with-log-file was given.
+if test "${with_log_file+set}" = set; then :
+  withval=$with_log_file; case x$with_log_file in #(
+  x) :
+    valid_with_log_file="no" ;; #(
+  xyes) :
+    valid_with_log_file="no" ;; #(
+  *) :
+    valid_with_error_file="yes" ;;
+esac
+   if test "$valid_with_log_file" = "no"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: invalid" >&5
+$as_echo "invalid" >&6; }
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Invalid value for --with-log-file: \"$with_log_file\"
+See \`config.log' for more details" "$LINENO" 5; }
 else
-  ERR_FILE=0
-fi;
 
-if test $ERR_FILE = 1; then
-   cat >>confdefs.h <<\_ACEOF
-#define ERR_REPORTING_FILE "/dev/console"
+cat >>confdefs.h <<_ACEOF
+#define ERR_REPORTING_FILE "$with_log_file"
 _ACEOF
 
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: using log file: \"$with_log_file\"" >&5
+$as_echo "using log file: \"$with_log_file\"" >&6; }
 fi
-# Check whether --enable-gdoi or --disable-gdoi was given.
-if test "${enable_gdoi+set}" = set; then
-  enableval="$enable_gdoi"
-  GDOI=1
 else
-  GDOI=0
-fi;
-
-if test $GDOI = 1; then
-   echo "$as_me:$LINENO: checking for GDOI key management" >&5
-echo $ECHO_N "checking for GDOI key management... $ECHO_C" >&6
-   echo "$as_me:$LINENO: result: ?" >&5
-echo "${ECHO_T}?" >&6
-   cat >>confdefs.h <<\_ACEOF
-#define SRTP_GDOI 1
-_ACEOF
-
-   GDOI_OBJS=gdoi/srtp+gdoi.o
-
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-          ac_config_headers="$ac_config_headers include/config.h:config_in.h"
+
+if test "$enable_log_stdout" = "yes" && test "x$with_log_file" != "x"; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Can only use one of --enable-log-stdout and --with-log-file; they are mutually exclusive
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra C compiler flags" >&5
+$as_echo_n "checking for extra C compiler flags... " >&6; }
+if test "x$EXTRA_CFLAGS" != "x"; then :
+  if test "x$CFLAGS" = "x"; then :
+  CFLAGS="$EXTRA_CFLAGS"
+else
+  CFLAGS="$CFLAGS $EXTRA_CFLAGS"
+fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXTRA_CFLAGS" >&5
+$as_echo "$EXTRA_CFLAGS" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ac_config_headers="$ac_config_headers crypto/include/config.h:config_in.h"
 
 
-          ac_config_files="$ac_config_files Makefile"
+ac_config_files="$ac_config_files Makefile crypto/Makefile doc/Makefile fuzzer/Makefile libsrtp2.pc"
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -4705,39 +6493,70 @@
 
 # The following way of writing the cache mishandles newlines in values,
 # but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
+# So, we kill variables containing newlines.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
-{
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
   (set) 2>&1 |
-    case `(ac_space=' '; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
-      # `set' does not quote correctly, so add quotes (double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \).
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
       sed -n \
-        "s/'/'\\\\''/g;
-    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;;
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
     *)
       # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n \
-        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
       ;;
-    esac;
-} |
+    esac |
+    sort
+) |
   sed '
+     /^ac_cv_env_/b end
      t clear
-     : clear
+     :clear
      s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
      t end
-     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
-  if test -w $cache_file; then
-    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
-    cat confcache >$cache_file
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
   else
-    echo "not updating unwritable cache $cache_file"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -4746,32 +6565,19 @@
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[ 	]*VPATH[ 	]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ 	]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[ 	]*$//;
-}'
-fi
-
 DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
-  ac_i=`echo "$ac_i" |
-         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
-  # 2. Add them.
-  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -4779,12 +6585,15 @@
 
 
 
-: ${CONFIG_STATUS=./config.status}
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
 # Generated by $as_me.
 # Run this file to recreate the current configuration.
@@ -4794,80 +6603,253 @@
 debug=false
 ac_cs_recheck=false
 ac_cs_silent=false
+
 SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
-fi
-
-# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
-  as_unset=unset
+  setopt NO_GLOB_SUBST
 else
-  as_unset=false
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
 fi
 
 
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    $as_unset $as_var
-  fi
-done
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
 
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
 else
   as_expr=false
 fi
 
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
   as_basename=basename
 else
   as_basename=false
 fi
 
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
 
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
 
-
-# PATH needs CR, and LINENO needs CR and PATH.
 # Avoid depending upon Character Ranges.
 as_cr_letters='abcdefghijklmnopqrstuvwxyz'
 as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -4875,180 +6857,133 @@
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
-	 /*)
-	   if ("$as_dir/$as_base" -c '
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
-    sed '
-      N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
-      t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
-    ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
-    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
-  # Exit status is that of the last command.
-  exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
 rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
-    as_ln_s='cp -p'
-  else
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
     as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
   fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
 
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
 if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
+  test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
-as_executable_p="test -f"
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
 # Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
 exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.  Logging --version etc. is OK.
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
-
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.57.  Invocation command line was
+# values after options handling.
+ac_log="
+This file was extended by libsrtp2 $as_me 2.3.0-pre, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -5056,44 +6991,45 @@
   CONFIG_COMMANDS = $CONFIG_COMMANDS
   $ $0 $@
 
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
 _ACEOF
 
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 # Files that config.status was made for.
-if test -n "$ac_config_files"; then
-  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
 
-if test -n "$ac_config_headers"; then
-  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
+_ACEOF
 
-if test -n "$ac_config_links"; then
-  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_commands"; then
-  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
 
-Usage: $0 [OPTIONS] [FILE]...
+Usage: $0 [OPTION]... [TAG]...
 
   -h, --help       print this help, then exit
-  -V, --version    print version number, then exit
-  -q, --quiet      do not print progress messages
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
-  --file=FILE[:TEMPLATE]
+      --file=FILE[:TEMPLATE]
                    instantiate the configuration file FILE
-  --header=FILE[:TEMPLATE]
+      --header=FILE[:TEMPLATE]
                    instantiate the configuration header FILE
 
 Configuration files:
@@ -5102,84 +7038,90 @@
 Configuration headers:
 $config_headers
 
-Report bugs to <bug-autoconf@gnu.org>."
+Report bugs to <https://github.com/cisco/libsrtp/issues>."
+
 _ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.57,
-  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+libsrtp2 config.status 2.3.0-pre
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
 
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value.  By we need to know if files were specified by the user.
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
 ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
-    ac_option=`expr "x$1" : 'x\([^=]*\)='`
-    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
-  -*)
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
     ac_option=$1
     ac_optarg=$2
     ac_shift=shift
     ;;
-  *) # This is not an option, so the user has probably given explicit
-     # arguments.
-     ac_option=$1
-     ac_need_defaults=false;;
   esac
 
   case $ac_option in
   # Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
-  --version | --vers* | -V )
-    echo "$ac_cs_version"; exit 0 ;;
-  --he | --h)
-    # Conflict between --help and --header
-    { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
-   { (exit 1); exit 1; }; };;
-  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit 0 ;;
-  --debug | --d* | -d )
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
-    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
   --header | --heade | --head | --hea )
     $ac_shift
-    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
-   { (exit 1); exit 1; }; } ;;
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
 
-  *) ac_config_targets="$ac_config_targets $1" ;;
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
 
   esac
   shift
@@ -5193,31 +7135,49 @@
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
 fi
 
 _ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
 
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
 
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 
-
-
-cat >>$CONFIG_STATUS <<\_ACEOF
+# Handling of arguments.
 for ac_config_target in $ac_config_targets
 do
-  case "$ac_config_target" in
-  # Handling of arguments.
-  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-  "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h:config_in.h" ;;
-  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
-   { (exit 1); exit 1; }; };;
+  case $ac_config_target in
+    "crypto/include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS crypto/include/config.h:config_in.h" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "crypto/Makefile") CONFIG_FILES="$CONFIG_FILES crypto/Makefile" ;;
+    "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+    "fuzzer/Makefile") CONFIG_FILES="$CONFIG_FILES fuzzer/Makefile" ;;
+    "libsrtp2.pc") CONFIG_FILES="$CONFIG_FILES libsrtp2.pc" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
+
 # If the user did not use the arguments to specify the items to instantiate,
 # then the envvar interface is used.  Set only those that are not.
 # We use the long form for the default assignment because of an extremely
@@ -5228,528 +7188,550 @@
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
+# simply because there is no reason against having it here, and in addition,
 # creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
-  trap '{ (exit 1); exit 1; }' 1 2 13 15
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
 }
-
 # Create a (secure) tmp directory for tmp files.
 
 {
-  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
 }  ||
 {
-  tmp=./confstat$$-$RANDOM
-  (umask 077 && mkdir $tmp)
-} ||
-{
-   echo "$me: cannot create a temporary directory in ." >&2
-   { (exit 1); exit 1; }
-}
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
-_ACEOF
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
 
-cat >>$CONFIG_STATUS <<_ACEOF
 
-#
-# CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
-  # Protect against being on the right side of a sed subst in config.status.
-  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
-   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s,@SHELL@,$SHELL,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s,@exec_prefix@,$exec_prefix,;t t
-s,@prefix@,$prefix,;t t
-s,@program_transform_name@,$program_transform_name,;t t
-s,@bindir@,$bindir,;t t
-s,@sbindir@,$sbindir,;t t
-s,@libexecdir@,$libexecdir,;t t
-s,@datadir@,$datadir,;t t
-s,@sysconfdir@,$sysconfdir,;t t
-s,@sharedstatedir@,$sharedstatedir,;t t
-s,@localstatedir@,$localstatedir,;t t
-s,@libdir@,$libdir,;t t
-s,@includedir@,$includedir,;t t
-s,@oldincludedir@,$oldincludedir,;t t
-s,@infodir@,$infodir,;t t
-s,@mandir@,$mandir,;t t
-s,@build_alias@,$build_alias,;t t
-s,@host_alias@,$host_alias,;t t
-s,@target_alias@,$target_alias,;t t
-s,@DEFS@,$DEFS,;t t
-s,@ECHO_C@,$ECHO_C,;t t
-s,@ECHO_N@,$ECHO_N,;t t
-s,@ECHO_T@,$ECHO_T,;t t
-s,@LIBS@,$LIBS,;t t
-s,@RANLIB@,$RANLIB,;t t
-s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@RNG_OBJS@,$RNG_OBJS,;t t
-s,@CPP@,$CPP,;t t
-s,@EGREP@,$EGREP,;t t
-s,@LIBOBJS@,$LIBOBJS,;t t
-s,@build@,$build,;t t
-s,@build_cpu@,$build_cpu,;t t
-s,@build_vendor@,$build_vendor,;t t
-s,@build_os@,$build_os,;t t
-s,@host@,$host,;t t
-s,@host_cpu@,$host_cpu,;t t
-s,@host_vendor@,$host_vendor,;t t
-s,@host_os@,$host_os,;t t
-s,@EXE@,$EXE,;t t
-s,@GDOI_OBJS@,$GDOI_OBJS,;t t
-s,@LTLIBOBJS@,$LTLIBOBJS,;t t
-CEOF
-
-_ACEOF
-
-  cat >>$CONFIG_STATUS <<\_ACEOF
-  # Split the substitutions into bite-sized pieces for seds with
-  # small command number limits, like on Digital OSF/1 and HP-UX.
-  ac_max_sed_lines=48
-  ac_sed_frag=1 # Number of current file.
-  ac_beg=1 # First line for current file.
-  ac_end=$ac_max_sed_lines # Line after last line for current file.
-  ac_more_lines=:
-  ac_sed_cmds=
-  while $ac_more_lines; do
-    if test $ac_beg -gt 1; then
-      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    else
-      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    fi
-    if test ! -s $tmp/subs.frag; then
-      ac_more_lines=false
-    else
-      # The purpose of the label and of the branching condition is to
-      # speed up the sed processing (if there are no `@' at all, there
-      # is no need to browse any of the substitutions).
-      # These are the two extra sed commands mentioned above.
-      (echo ':t
-  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
-      if test -z "$ac_sed_cmds"; then
-  	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
-      else
-  	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
-      fi
-      ac_sed_frag=`expr $ac_sed_frag + 1`
-      ac_beg=$ac_end
-      ac_end=`expr $ac_end + $ac_max_sed_lines`
-    fi
-  done
-  if test -z "$ac_sed_cmds"; then
-    ac_sed_cmds=cat
-  fi
-fi # test -n "$CONFIG_FILES"
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case $ac_file in
-  - | *:- | *:-:* ) # input from stdin
-        cat >$tmp/stdin
-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  * )   ac_file_in=$ac_file.in ;;
-  esac
-
-  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
-  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$ac_file" : 'X\(//\)[^/]' \| \
-         X"$ac_file" : 'X\(//\)$' \| \
-         X"$ac_file" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-  { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
-    as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$as_dir" : 'X\(//\)[^/]' \| \
-         X"$as_dir" : 'X\(//\)$' \| \
-         X"$as_dir" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
-   { (exit 1); exit 1; }; }; }
-
-  ac_builddir=.
-
-if test "$ac_dir" != .; then
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
 else
-  ac_dir_suffix= ac_top_builddir=
+  ac_cs_awk_cr=$ac_cr
 fi
 
-case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
-    ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
-
-
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
-  # Let's still pretend it is `configure' which instantiates (i.e., don't
-  # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated by config.status.  */
-  if test x"$ac_file" = x-; then
-    configure_input=
-  else
-    configure_input="$ac_file.  "
-  fi
-  configure_input=$configure_input"Generated from `echo $ac_file_in |
-                                     sed 's,.*/,,'` by configure."
-
-  # First look for the input files in the build tree, otherwise in the
-  # src tree.
-  ac_file_inputs=`IFS=:
-    for f in $ac_file_in; do
-      case $f in
-      -) echo $tmp/stdin ;;
-      [\\/$]*)
-         # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-         echo $f;;
-      *) # Relative
-         if test -f "$f"; then
-           # Build tree
-           echo $f
-         elif test -f "$srcdir/$f"; then
-           # Source tree
-           echo $srcdir/$f
-         else
-           # /dev/null tree
-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-         fi;;
-      esac
-    done` || { (exit 1); exit 1; }
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s,@configure_input@,$configure_input,;t t
-s,@srcdir@,$ac_srcdir,;t t
-s,@abs_srcdir@,$ac_abs_srcdir,;t t
-s,@top_srcdir@,$ac_top_srcdir,;t t
-s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s,@builddir@,$ac_builddir,;t t
-s,@abs_builddir@,$ac_abs_builddir,;t t
-s,@top_builddir@,$ac_top_builddir,;t t
-s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
-  rm -f $tmp/stdin
-  if test x"$ac_file" != x-; then
-    mv $tmp/out $ac_file
-  else
-    cat $tmp/out
-    rm -f $tmp/out
-  fi
 
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
 done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
 
-#
-# CONFIG_HEADER section.
-#
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
 
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s,^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
-ac_dB='[ 	].*$,\1#\2'
-ac_dC=' '
-ac_dD=',;t'
-# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_uA='s,^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
-ac_uB='$,\1#\2define\3'
-ac_uC=' '
-ac_uD=',;t'
+  print line
+}
 
-for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case $ac_file in
-  - | *:- | *:-:* ) # input from stdin
-        cat >$tmp/stdin
-        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  * )   ac_file_in=$ac_file.in ;;
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
   esac
 
-  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-
-  # First look for the input files in the build tree, otherwise in the
-  # src tree.
-  ac_file_inputs=`IFS=:
-    for f in $ac_file_in; do
-      case $f in
-      -) echo $tmp/stdin ;;
-      [\\/$]*)
-         # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-         echo $f;;
-      *) # Relative
-         if test -f "$f"; then
-           # Build tree
-           echo $f
-         elif test -f "$srcdir/$f"; then
-           # Source tree
-           echo $srcdir/$f
-         else
-           # /dev/null tree
-           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-         fi;;
-      esac
-    done` || { (exit 1); exit 1; }
-  # Remove the trailing spaces.
-  sed 's/[ 	]*$//' $ac_file_inputs >$tmp/in
-
-_ACEOF
-
-# Transform confdefs.h into two sed scripts, `conftest.defines' and
-# `conftest.undefs', that substitutes the proper values into
-# config.h.in to produce config.h.  The first handles `#define'
-# templates, and the second `#undef' templates.
-# And first: Protect against being on the right side of a sed subst in
-# config.status.  Protect against being in an unquoted here document
-# in config.status.
-rm -f conftest.defines conftest.undefs
-# Using a here document instead of a string reduces the quoting nightmare.
-# Putting comments in sed scripts is not portable.
-#
-# `end' is used to avoid that the second main sed command (meant for
-# 0-ary CPP macros) applies to n-ary macro definitions.
-# See the Autoconf documentation for `clear'.
-cat >confdef2sed.sed <<\_ACEOF
-s/[\\&,]/\\&/g
-s,[\\$`],\\&,g
-t clear
-: clear
-s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	(][^ 	(]*\)\(([^)]*)\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
-t end
-s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	][^ 	]*\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
-: end
-_ACEOF
-# If some macros were called several times there might be several times
-# the same #defines, which is useless.  Nevertheless, we may not want to
-# sort them, since we want the *last* AC-DEFINE to be honored.
-uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
-sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
-rm -f confdef2sed.sed
-
-# This sed command replaces #undef with comments.  This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >>conftest.undefs <<\_ACEOF
-s,^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
-_ACEOF
-
-# Break up conftest.defines because some shells have a limit on the size
-# of here documents, and old seds have small limits too (100 cmds).
-echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
-echo '  if grep "^[ 	]*#[ 	]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
-echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
-echo '  :' >>$CONFIG_STATUS
-rm -f conftest.tail
-while grep . conftest.defines >/dev/null
-do
-  # Write a limited-size here document to $tmp/defines.sed.
-  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
-  # Speed up: don't consider the non `#define' lines.
-  echo '/^[ 	]*#[ 	]*define/!b' >>$CONFIG_STATUS
-  # Work around the forget-to-reset-the-flag bug.
-  echo 't clr' >>$CONFIG_STATUS
-  echo ': clr' >>$CONFIG_STATUS
-  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
-  echo 'CEOF
-  sed -f $tmp/defines.sed $tmp/in >$tmp/out
-  rm -f $tmp/in
-  mv $tmp/out $tmp/in
-' >>$CONFIG_STATUS
-  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
-  rm -f conftest.defines
-  mv conftest.tail conftest.defines
-done
-rm -f conftest.defines
-echo '  fi # grep' >>$CONFIG_STATUS
-echo >>$CONFIG_STATUS
-
-# Break up conftest.undefs because some shells have a limit on the size
-# of here documents, and old seds have small limits too (100 cmds).
-echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
-rm -f conftest.tail
-while grep . conftest.undefs >/dev/null
-do
-  # Write a limited-size here document to $tmp/undefs.sed.
-  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
-  # Speed up: don't consider the non `#undef'
-  echo '/^[ 	]*#[ 	]*undef/!b' >>$CONFIG_STATUS
-  # Work around the forget-to-reset-the-flag bug.
-  echo 't clr' >>$CONFIG_STATUS
-  echo ': clr' >>$CONFIG_STATUS
-  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
-  echo 'CEOF
-  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
-  rm -f $tmp/in
-  mv $tmp/out $tmp/in
-' >>$CONFIG_STATUS
-  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
-  rm -f conftest.undefs
-  mv conftest.tail conftest.undefs
-done
-rm -f conftest.undefs
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-  # Let's still pretend it is `configure' which instantiates (i.e., don't
-  # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated by config.status.  */
-  if test x"$ac_file" = x-; then
-    echo "/* Generated by configure.  */" >$tmp/config.h
-  else
-    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
-  fi
-  cat $tmp/in >>$tmp/config.h
-  rm -f $tmp/in
-  if test x"$ac_file" != x-; then
-    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
-      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
-echo "$as_me: $ac_file is unchanged" >&6;}
-    else
-      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+  ac_dir=`$as_dirname -- "$ac_file" ||
 $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$ac_file" : 'X\(//\)[^/]' \| \
-         X"$ac_file" : 'X\(//\)$' \| \
-         X"$ac_file" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-      { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
-    as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-         X"$as_dir" : 'X\(//\)[^/]' \| \
-         X"$as_dir" : 'X\(//\)$' \| \
-         X"$as_dir" : 'X\(/\)' \| \
-         .     : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
-   { (exit 1); exit 1; }; }; }
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
 
-      rm -f $ac_file
-      mv $tmp/config.h $ac_file
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    cat $tmp/config.h
-    rm -f $tmp/config.h
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
   fi
-done
-_ACEOF
+ ;;
 
-cat >>$CONFIG_STATUS <<\_ACEOF
 
-{ (exit 0); exit 0; }
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
 _ACEOF
-chmod +x $CONFIG_STATUS
 ac_clean_files=$ac_clean_files_save
 
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
 
 # configure is writing to config.log, and then calls config.status.
 # config.status does its own redirection, appending to config.log.
@@ -5769,8 +7751,21 @@
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || { (exit 1); exit 1; }
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
-
+# This is needed when building outside the source dir.
+as_dir=crypto/cipher; as_fn_mkdir_p
+as_dir=crypto/hash; as_fn_mkdir_p
+as_dir=crypto/kernel; as_fn_mkdir_p
+as_dir=crypto/math; as_fn_mkdir_p
+as_dir=crypto/replay; as_fn_mkdir_p
+as_dir=crypto/test; as_fn_mkdir_p
+as_dir=doc; as_fn_mkdir_p
+as_dir=srtp; as_fn_mkdir_p
+as_dir=test; as_fn_mkdir_p
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..b91449b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,426 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([libsrtp2], [2.3.0-pre], [https://github.com/cisco/libsrtp/issues])
+
+dnl Must come before AC_PROG_CC
+EMPTY_CFLAGS="no"
+if test "x$CFLAGS" = "x"; then
+   dnl Default value for CFLAGS if not specified.
+   EMPTY_CFLAGS="yes"
+fi
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AC_ARG_VAR(
+  [EXTRA_CFLAGS],
+  [C compiler flags appended to the regular C compiler flags instead of overriding them])
+AM_PROG_AR
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_SED
+
+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])
+    ;;
+  * )
+    AC_DEFINE([CPU_RISC], [1], [Define if building for a RISC machine (assume slow byte access).])
+    ;;
+esac
+
+dnl Check if we are on a Windows platform.
+case $host_os in
+  *cygwin*|*mingw* )
+    EXE=.exe
+    ;;
+  * )
+    EXE=""
+    ;;
+esac
+AC_SUBST([EXE])   # define executable suffix; this is needed for `make clean'
+
+dnl Checks for supported compiler flags.
+supported_cflags=""
+if test "$EMPTY_CFLAGS" = "no"; then
+  supported_cflags="$CFLAGS"
+fi
+
+dnl For accurate detection, we need warnings as errors.
+dnl I.e. Clang will issue a warning about unsupported flags.
+dnl For the compilation to fail, those warnings needs to be upgraded to errors.
+dnl This will be removed again once the tests are complete (see below).
+WERROR=""
+for w in -Werror -errwarn; do
+  if test "x$WERROR" = "x"; then
+    AC_MSG_CHECKING([whether ${CC-c} accepts $w])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$w"], [CFLAGS="$CFLAGS $w"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [WERROR="$w"
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  fi
+done
+
+dnl Note that -fPIC is not explicitly added to LDFLAGS.
+dnl Since the compiler is used as the link driver, CFLAGS will be part of the
+dnl link line as well and the linker will get the flag from there.
+dnl Adding it to LDFLAGS explicitly would duplicate the flag on the link line,
+dnl but otherwise do no harm.
+AC_MSG_CHECKING([whether ${CC-c} accepts -fPIC])
+save_cflags="$CFLAGS"
+AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="-fPIC"], [CFLAGS="$CFLAGS -fPIC"])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+  [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="-fPIC"], [supported_cflags="$supported_cflags -fPIC"])
+   AC_MSG_RESULT([yes])],
+  [CFLAGS="$save_cflags"
+   AC_MSG_RESULT([no])])
+
+if test "$EMPTY_CFLAGS" = "yes"; then
+  for f in -Wall -pedantic -Wstrict-prototypes; do
+    AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  done
+
+  OOPT=""
+  for f in -O4 -O3; do
+    if test "x$OOPT" = "x"; then
+      AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+      save_cflags="$CFLAGS"
+      AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+        [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+         OOPT="$f"
+         AC_MSG_RESULT([yes])],
+        [CFLAGS="$save_cflags"
+         AC_MSG_RESULT([no])])
+    fi
+  done
+
+  for f in -fexpensive-optimizations -funroll-loops; do
+    AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+    save_cflags="$CFLAGS"
+    AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$f"], [CFLAGS="$CFLAGS $f"])
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+      [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+       AC_MSG_RESULT([yes])],
+      [CFLAGS="$save_cflags"
+       AC_MSG_RESULT([no])])
+  done
+fi
+
+dnl When turning off warnigns, we're expecting unrecognized command line option errors if they're not
+dnl supported. However, the -Wno-<warning> form isn't consulted unless a warning is triggered.
+dnl At least that's the case for GCC. So to check which warnings we can turn off, we need to check
+dnl if they can be turned on, thereby forcing GCC to take the argument into account right away.
+for f in -Wno-language-extension-token; do
+  AC_MSG_CHECKING([whether ${CC-c} accepts $f])
+  save_cflags="$CFLAGS"
+  testf=$(echo "$f" | $SED 's|-Wno-\(.*\)|-W\1|g')
+  AS_IF([test "x$CFLAGS" = "x"], [CFLAGS="$testf"], [CFLAGS="$CFLAGS $testf"])
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])],
+    [AS_IF([test "x$supported_cflags" = "x"], [supported_cflags="$f"], [supported_cflags="$supported_cflags $f"])
+     AC_MSG_RESULT([yes])],
+    [CFLAGS="$save_cflags"
+     AC_MSG_RESULT([no])])
+done
+
+dnl Remowing -Werror again
+CFLAGS="$supported_cflags"
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(
+    [unistd.h byteswap.h stdint.h sys/uio.h inttypes.h sys/types.h machine/types.h sys/int_types.h],
+    [], [], [AC_INCLUDES_DEFAULT])
+
+dnl socket() and friends
+AC_CHECK_HEADERS([sys/socket.h netinet/in.h arpa/inet.h], [], [], [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS(
+    [windows.h],
+    [AC_CHECK_HEADERS([winsock2.h], [], [], [AC_INCLUDES_DEFAULT])],
+    [], [AC_INCLUDES_DEFAULT])
+
+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_LINK_IFELSE(
+    [AC_LANG_SOURCE([
+#include <winsock2.h>
+int main(void)
+{
+    int fd = socket(0, 0, 0);
+    if (fd < 0)
+      return -1;
+    else
+      return 0;
+}
+    ])],
+    [ac_cv_func_socket=yes
+     AC_MSG_RESULT([yes])],
+    [LIBS="$SAVELIBS"
+     AC_MSG_RESULT([no])])
+fi
+
+AC_MSG_CHECKING([whether to enable debug logging in all modules])
+AC_ARG_ENABLE([debug-logging],
+  [AS_HELP_STRING([--enable-debug-logging], [Enable debug logging in all modules])],
+  [], enable_debug_logging=no)
+if test "$enable_debug_logging" = "yes"; then
+   AC_DEFINE([ENABLE_DEBUG_LOGGING], [1], [Define to enabled debug logging for all mudules.])
+fi
+AC_MSG_RESULT([$enable_debug_logging])
+
+PKG_PROG_PKG_CONFIG
+AS_IF([test "x$PKG_CONFIG" != "x"], [PKG_CONFIG="$PKG_CONFIG --static"])
+
+AC_MSG_CHECKING([whether to leverage OpenSSL crypto])
+AC_ARG_ENABLE([openssl],
+  [AS_HELP_STRING([--enable-openssl], [compile in OpenSSL crypto engine])],
+  [], [enable_openssl=no])
+AC_MSG_RESULT([$enable_openssl])
+
+AC_MSG_CHECKING([whether to leverage NSS crypto])
+AC_ARG_ENABLE([nss],
+  [AS_HELP_STRING([--enable-nss], [compile in NSS crypto engine])],
+  [], [enable_nss=no])
+AC_MSG_RESULT([$enable_nss])
+
+if test "$enable_openssl" = "yes"; then
+   AC_MSG_CHECKING([for user specified OpenSSL directory])
+   AC_ARG_WITH([openssl-dir],
+      [AS_HELP_STRING([--with-openssl-dir], [Location of OpenSSL installation])],
+      [if test "x$PKG_CONFIG" != "x" && test -f $with_openssl_dir/lib/pkgconfig/libcrypto.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_openssl_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         AC_MSG_RESULT([$with_openssl_dir])
+       elif test -d $with_openssl_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_openssl_dir/include"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_openssl_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_openssl_dir/lib"
+         fi
+         AC_MSG_RESULT([$with_openssl_dir])
+       else
+         AC_MSG_RESULT([invalid])
+         AC_MSG_FAILURE([Invalid OpenSSL location: $with_openssl_dir])
+       fi],
+      [AC_MSG_RESULT([no])])
+
+   if test "x$PKG_CONFIG" != "x"; then
+     PKG_CHECK_MODULES([crypto], [libcrypto >= 1.0.1],
+       [CFLAGS="$CFLAGS $crypto_CFLAGS"
+        LIBS="$crypto_LIBS $LIBS"])
+   else
+     AC_CHECK_LIB([dl], [dlopen], [], [AC_MSG_WARN([can't find libdl])])
+     AC_CHECK_LIB([z], [inflate], [], [AC_MSG_WARN([can't find libz])])
+   fi
+
+   AC_SEARCH_LIBS([EVP_EncryptInit], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+   AC_SEARCH_LIBS([EVP_aes_128_ctr], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+   AC_SEARCH_LIBS([EVP_aes_128_gcm], [crypto],
+     [], [AC_MSG_FAILURE([can't find openssl >= 1.0.1 crypto lib])])
+
+   AC_DEFINE([GCM], [1], [Define this to use AES-GCM.])
+   AC_DEFINE([OPENSSL], [1], [Define this to use OpenSSL crypto.])
+   AES_ICM_OBJS="crypto/cipher/aes_icm_ossl.o crypto/cipher/aes_gcm_ossl.o"
+   HMAC_OBJS=crypto/hash/hmac_ossl.o
+   AC_SUBST([USE_EXTERNAL_CRYPTO], [1])
+
+   AC_MSG_CHECKING([if OPENSSL_cleanse is broken])
+   AC_RUN_IFELSE([AC_LANG_PROGRAM([
+     #include <stdio.h>
+     #include <openssl/crypto.h>
+   ], [
+     #define BUFFER_SIZE (16)
+     char buffer[[BUFFER_SIZE]];
+     int i;
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       buffer[[i]] = i & 0xff;
+     }
+     OPENSSL_cleanse(buffer, BUFFER_SIZE);
+     for (i = 0; i < BUFFER_SIZE; i++) {
+       if (buffer[[i]]) {
+         printf("Buffer contents not zero at position %d (is %d)\n", i,
+             buffer[[i]]);
+         return 1;
+       }
+     }
+   ])], [openssl_cleanse_broken=no], [
+     openssl_cleanse_broken=yes
+     AC_DEFINE([OPENSSL_CLEANSE_BROKEN], [1], [Define this if OPENSSL_cleanse is broken.])
+   ])
+   AC_MSG_RESULT([$openssl_cleanse_broken])
+
+   AC_MSG_CHECKING([whether to leverage OpenSSL KDF algorithm])
+   AC_ARG_ENABLE([openssl-kdf],
+      [AS_HELP_STRING([--enable-openssl-kdf], [Use OpenSSL KDF algorithm])],
+      [], [enable_openssl_kdf=no])
+   AC_MSG_RESULT([$enable_openssl_kdf])
+   if test "$enable_openssl_kdf" = "yes"; then
+     AC_SEARCH_LIBS([kdf_srtp], [crypto],
+       [], [AC_MSG_FAILURE([can't find openssl KDF lib])])
+     AC_DEFINE([OPENSSL_KDF], [1], [Define this to use OpenSSL KDF for SRTP.])
+   fi
+elif test "$enable_nss" = "yes"; then
+   AC_MSG_CHECKING([for user specified NSS directory])
+   AC_ARG_WITH([nss-dir],
+      [AS_HELP_STRING([--with-nss-dir], [Location of NSS installation])],
+      [if test "x$PKG_CONFIG" != "x" && test -f $with_nss_dir/lib/pkgconfig/nss.pc; then
+         if test "x$PKG_CONFIG_PATH" = "x"; then
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig"
+         else
+           export PKG_CONFIG_PATH="$with_nss_dir/lib/pkgconfig:$PKG_CONFIG_PATH"
+         fi
+         AC_MSG_RESULT([$with_nss_dir])
+       elif test -d $with_nss_dir/lib; then
+         CFLAGS="$CFLAGS -I$with_nss_dir/include"
+         CFLAGS="$CFLAGS -I$with_nss_dir/../public/nss"
+         if test "x$LDFLAGS" = "x"; then
+           LDFLAGS="-L$with_nss_dir/lib"
+         else
+           LDFLAGS="$LDFLAGS -L$with_nss_dir/lib"
+         fi
+         nss_skip_pkg_config=yes
+         AC_MSG_RESULT([$with_nss_dir])
+       else
+         AC_MSG_RESULT([invalid])
+         AC_MSG_FAILURE([Invalid NSS location: $with_nss_dir])
+       fi
+       AC_SUBST([CRYPTO_LIBDIR], [$with_nss_dir/lib])],
+      [AC_MSG_RESULT([no])])
+
+   if test "x$PKG_CONFIG" != "x" && test "$nss_skip_pkg_config" != "yes"; then
+     PKG_CHECK_MODULES([nss], [nss],
+       [CFLAGS="$CFLAGS $nss_CFLAGS"
+         LIBS="$nss_LIBS $LIBS"])
+   else
+     AC_CHECK_HEADERS(
+       [nss.h],
+       [], [AC_MSG_FAILURE([can't find useable NSS headers])],
+       [AC_INCLUDES_DEFAULT])
+     AC_CHECK_LIB(
+       [nspr4], [PR_GetError],
+       [], [AC_MSG_WARN([can't find libnspr4])])
+     AC_CHECK_LIB(
+       [nss3], [NSS_NoDB_Init],
+       [], [AC_MSG_FAILURE([can't find useable libnss3])])
+   fi
+
+   AC_DEFINE([GCM], [1], [Define this to use AES-GCM.])
+   AC_DEFINE([NSS], [1], [Define this to use NSS crypto.])
+   AES_ICM_OBJS="crypto/cipher/aes_icm_nss.o crypto/cipher/aes_gcm_nss.o"
+
+   # TODO(RLB): Use NSS for HMAC
+   HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
+
+   # TODO(RLB): Use NSS for KDF
+
+   AC_SUBST([USE_EXTERNAL_CRYPTO], [1])
+else
+   AES_ICM_OBJS="crypto/cipher/aes_icm.o crypto/cipher/aes.o"
+   HMAC_OBJS="crypto/hash/hmac.o crypto/hash/sha1.o"
+fi
+AC_SUBST([AES_ICM_OBJS])
+AC_SUBST([HMAC_OBJS])
+
+dnl Checking for PCAP
+
+PCAP_LIB=""
+AC_CHECK_LIB([pcap], [pcap_create],
+  [PCAP_LIB="-lpcap"
+   AC_DEFINE([HAVE_PCAP], [1], [Define to 1 if you have the `pcap' library (-lpcap)])
+   AC_SUBST([HAVE_PCAP], [1])])
+   
+AC_CHECK_LIB([wpcap], [pcap_create],
+  [PCAP_LIB="-lwpcap"
+   AC_DEFINE([HAVE_PCAP], [1], [Define to 1 if you have the `winpcap' library (-lwpcap)])
+   AC_SUBST([HAVE_PCAP], [1])])
+AC_SUBST([PCAP_LIB])
+   
+AC_MSG_CHECKING([whether to redirect logging to stdout])
+AC_ARG_ENABLE([log-stdout],
+  [AS_HELP_STRING([--enable-log-stdout], [redirecting logging to stdout])],
+  [], [enable_log_stdout=no])
+if test "$enable_log_stdout" = "yes"; then
+   AC_DEFINE([ERR_REPORTING_STDOUT], [1], [Define to redirect logging to stdout.])
+fi
+AC_MSG_RESULT([$enable_log_stdout])
+
+AC_MSG_CHECKING([wheather to use a file for logging])
+AC_ARG_WITH([log-file],
+  [AS_HELP_STRING([--with-log-file], [Use file for logging])],
+  [AS_CASE([x$with_log_file],
+     [x], [valid_with_log_file="no"],
+     [xyes], [valid_with_log_file="no"],
+     [valid_with_error_file="yes"])
+   AS_IF([test "$valid_with_log_file" = "no"],
+     [AC_MSG_RESULT([invalid])
+      AC_MSG_FAILURE([Invalid value for --with-log-file: "$with_log_file"])],
+     [AC_DEFINE_UNQUOTED([ERR_REPORTING_FILE], ["$with_log_file"], [Logging statments will be writen to this file.])
+      AC_MSG_RESULT([using log file: "$with_log_file"])])],
+  [AC_MSG_RESULT([no])])
+
+AS_IF(
+  [test "$enable_log_stdout" = "yes" && test "x$with_log_file" != "x"],
+  [AC_MSG_FAILURE([Can only use one of --enable-log-stdout and --with-log-file; they are mutually exclusive])])
+
+dnl Appending EXTRA_CFLAGS, if given
+AC_MSG_CHECKING([for extra C compiler flags])
+AS_IF([test "x$EXTRA_CFLAGS" != "x"],
+   [AS_IF([test "x$CFLAGS" = "x"],
+      [CFLAGS="$EXTRA_CFLAGS"], [CFLAGS="$CFLAGS $EXTRA_CFLAGS"])
+    AC_MSG_RESULT([$EXTRA_CFLAGS])],
+   [AC_MSG_RESULT(no)])
+
+AC_CONFIG_HEADER([crypto/include/config.h:config_in.h])
+
+AC_CONFIG_FILES([Makefile crypto/Makefile doc/Makefile fuzzer/Makefile libsrtp2.pc])
+AC_OUTPUT
+
+# This is needed when building outside the source dir.
+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/test])
+AS_MKDIR_P([doc])
+AS_MKDIR_P([srtp])
+AS_MKDIR_P([test])
diff --git a/configure.in b/configure.in
deleted file mode 100644
index 730bc23..0000000
--- a/configure.in
+++ /dev/null
@@ -1,115 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(srtp)
-
-dnl Checks for programs.
-AC_PROG_RANLIB
-AC_PROG_CC
-
-dnl Checks for libraries.
-AC_CHECK_LIB(socket, socket)
-AC_CHECK_LIB(srtp, srtp_init)
-
-
-dnl Check for /dev/urandom
-AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=1, DEV_URANDOM=0) 
-if test $DEV_URANDOM = 1; then 
-   AC_DEFINE(DEV_URANDOM)
-   RNG_OBJS=crypto/rng/rand_source.c
-   AC_SUBST(RNG_OBJS)                              
-fi
-
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(stdlib.h)
-AC_CHECK_HEADERS(unistd.h)
-AC_CHECK_HEADERS(stdint.h)
-AC_CHECK_HEADERS(sys/uio.h)
-AC_CHECK_HEADERS(machine/types.h)
-AC_CHECK_HEADERS(sys/int_types.h)
-
-AC_CHECK_HEADERS(syslog.h)
-
-AC_CHECK_TYPE(uint16_t)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_SIZE_T
-
-dnl Checks for library functions.
-AC_FUNC_MEMCMP
-AC_CHECK_FUNCS(socket strerror inet_aton)
-
-dnl Check the byte order
-AC_C_BIGENDIAN
-
-AC_CANONICAL_HOST
-
-if test $host_cpu = x86; then	
-   echo "x86 cpu found" # should use inline assembly
-fi
-
-dnl check host_cpu type, set defines appropriately
-case $host_cpu in
-     i*86 )
-	AC_DEFINE(CPU_CISC);;
-	* )
-	AC_DEFINE(CPU_RISC);;
-esac	
-
-dnl Check if we're on a cygwin (GNU on MSWin) platform, set HAVE_MS_TYPES
-
-case $host_os in
-  *cygwin* ) 
-	      AC_DEFINE(HAVE_MS_TYPES, 1)
-	      EXE=.exe;;
-         * )  EXE="";;
-esac
-
-AC_SUBST(EXE)   # define executable suffix; this is needed for `make clean'
-
-AC_ARG_ENABLE(debug, debug (compile in dynamic debugging system), USE_DEBUG=0, USE_DEBUG=1)
-
-if test $USE_DEBUG = 1; then
-   AC_DEFINE(ENABLE_DEBUGGING)
-fi
-
-AC_ARG_ENABLE(generic-aesicm, generic-aesicm (compile in changes for ismacryp), GENERIC_AESICM=0, GENERIC_AESICM=1)
-
-if test $GENERIC_AESICM = 1; then
-   AC_DEFINE(GENERIC_AESICM)
-fi
-
-AC_ARG_ENABLE(syslog, syslog (use syslog for error reporting), USE_SYSLOG=1, USE_SYSLOG=0)
-
-if test $USE_SYSLOG = 1; then
-   AC_DEFINE(USE_SYSLOG)
-fi
-
-AC_ARG_ENABLE(stdout, stdout (use stdout for error reporting), ERR_STDOUT=0, ERR_STDOUT=1)
-
-if test $ERR_STDOUT = 1; then
-   AC_DEFINE(ERR_REPORTING_STDOUT, 1)
-fi
-
-AC_ARG_ENABLE(console, console (use /dev/console for error reporting), ERR_FILE=1, ERR_FILE=0)
-
-if test $ERR_FILE = 1; then
-   AC_DEFINE(ERR_REPORTING_FILE, "/dev/console")
-fi
-AC_ARG_ENABLE(gdoi, gdoi (GDOI key management), GDOI=1, GDOI=0)
-
-if test $GDOI = 1; then 
-   AC_MSG_CHECKING(for GDOI key management)
-   AC_MSG_RESULT(?)
-   AC_DEFINE(SRTP_GDOI)
-   GDOI_OBJS=gdoi/srtp+gdoi.o
-   AC_SUBST(GDOI_OBJS)                              
-fi
-
-AC_CONFIG_HEADER(include/config.h:config_in.h)
-
-AC_OUTPUT(Makefile)
-
-
diff --git a/crypto/Makefile b/crypto/Makefile
deleted file mode 100644
index 5540e3b..0000000
--- a/crypto/Makefile
+++ /dev/null
@@ -1,119 +0,0 @@
-# Makefile for libcryptokernel.a
-#
-# David A. McGrew
-# Cisco Systems, Inc.
-
-CFLAGS = -Wall -g
-INCDIR = -I. -I./include  
-LIBS   = -lcryptomodule
-LIBDIR = -L. 
-
-ifdef ARCH
-  CDEFS += -D$(ARCH)=1
-endif
-
-ifdef sysname
-  CDEFS += -D$(sysname)=1
-endif
-
-.PHONY: dummy all runtest clean superclean
-
-dummy : all runtest 
-
-# data values used to test the aes_calc application
-
-k=000102030405060708090a0b0c0d0e0f
-p=00112233445566778899aabbccddeeff
-c=69c4e0d86a7b0430d8cdb78070b4c55a
-
-runtest: $(testapp)
-	@echo "running libcryptomodule test applications..."
-	test `test/aes_calc $k $p` = $c
-	test/cipher_driver -v >/dev/null
-	test/datatypes_driver -v >/dev/null
-	test/stat_driver >/dev/null
-	test/sha1_driver -v >/dev/null
-	test/kernel_driver -v >/dev/null
-	test/rand_gen -n 256 >/dev/null
-	@echo "libcryptomodule test applications passed."
-
-# libcryptomodule.a (the crypto engine) 
-
-ciphers = cipher/cipher.o cipher/null_cipher.o      \
-          cipher/aes.o cipher/aes_icm.o             \
-          cipher/aes_cbc.o
-
-hashes  = hash/null_auth.o hash/sha1.o \
-          hash/hmac.o hash/auth.o
-
-math    = math/datatypes.o math/stat.o
-
-rng     = rng/rand_source.o rng/prng.o rng/ctr_prng.o
-
-err     = kernel/err.o
-
-kernel  = kernel/crypto_kernel.o  kernel/alloc.o   \
-          kernel/key.o $(rng) $(err)
-
-xfm     = ae_xfm/xfm.o
-
-cryptobj =  $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)
-
-# the rule for making object files and test apps
-
-%.o: %.c
-	$(CC) -c $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ 
-
-%: %.c libcryptomodule.a 
-	$(CC) $(CDEFS) $(CFLAGS) $(INCDIR) $< -o $@ $(LIBDIR) $(LIBS)
-
-ifndef AR
-  AR=ar
-endif
-
-ifndef RANLIB
-  RANLIB=ranlib
-endif
-
-# and the crypto module library itself
-
-libcryptomodule.a: $(cryptobj) 
-	$(AR) cr libcryptomodule.a $(cryptobj) 
-	$(RANLIB) libcryptomodule.a
-
-# test applications 
-
-testapp = test/cipher_driver test/datatypes_driver \
-          test/stat_driver test/sha1_driver test/kernel_driver      \
-          test/aes_calc test/rand_gen 
-
-all: libcryptomodule.a $(testapp)
-
-test: libcryptomodule.a $(testapp)
-	@echo "running libcryptomodule test applications..."
-	test/kernel_driver$(EXE) -v >/dev/null
-	test/cipher_driver$(EXE) -v >/dev/null
-	@echo "libcryptomodule test applications passed." 
-
-# housekeeping functions
-
-clean:
-	rm -f libcryptomodule.a
-	rm -f $(testapp) *.o */*.o 
-	for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
-	rm -f `find . -name "*.[ch]~*~"`
-	rm -rf latex
-
-superclean: clean
-	rm -f *core TAGS ktrace.out
-
-
-# the target 'package' builds a compressed tar archive of the source code
-
-distname = crypto-$(shell cat VERSION)
-
-package: superclean
-	cd ..; tar cvzf $(distname).tgz crypto/
-
-
-# EOF
diff --git a/crypto/Makefile.in b/crypto/Makefile.in
new file mode 100644
index 0000000..44f29ad
--- /dev/null
+++ b/crypto/Makefile.in
@@ -0,0 +1,119 @@
+# Makefile for crypto test suite
+#
+# David A. McGrew
+# Cisco Systems, Inc.
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+CC	= @CC@
+INCDIR	= -Iinclude -I$(srcdir)/include -I$(top_srcdir)/include
+DEFS	= @DEFS@
+CPPFLAGS= @CPPFLAGS@
+CFLAGS	= @CFLAGS@
+LIBS	= @LIBS@
+LDFLAGS	= @LDFLAGS@ -L. -L..
+COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
+CRYPTOLIB = -lsrtp2
+CRYPTO_LIBDIR = @CRYPTO_LIBDIR@
+
+RANLIB	= @RANLIB@
+
+# Specify how tests should find shared libraries on macOS and Linux
+#
+# macOS purges DYLD_LIBRARY_PATH when spawning subprocesses, so it's
+# not possible to pass this in from the outside; we have to specify
+# it for any subprocesses we call. No support for dynamic linked
+# tests on Windows.
+ifneq ($(strip $(CRYPTO_LIBDIR)),)
+	ifneq ($(OS),Windows_NT)
+		UNAME_S = $(shell uname -s)
+		ifeq ($(UNAME_S),Linux)
+			FIND_LIBRARIES = LD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+		endif
+		ifeq ($(UNAME_S),Darwin)
+			FIND_LIBRARIES = DYLD_LIBRARY_PATH=$(CRYPTO_LIBDIR)
+		endif
+	endif
+endif
+
+# EXE defines the suffix on executables - it's .exe for cygwin, and
+# null on linux, bsd, and OS X and other OSes.  we define this so that
+# `make clean` will work on the cygwin platform
+EXE = @EXE@
+# Random source.
+USE_EXTERNAL_CRYPTO = @USE_EXTERNAL_CRYPTO@
+
+ifdef ARCH
+  DEFS += -D$(ARCH)=1
+endif
+
+ifdef sysname
+  DEFS += -D$(sysname)=1
+endif
+
+.PHONY: dummy all runtest clean superclean
+
+dummy : all runtest
+
+# test applications
+ifneq (1, $(USE_EXTERNAL_CRYPTO))
+AES_CALC = test/aes_calc$(EXE)
+endif
+
+testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
+	  test/stat_driver$(EXE) test/sha1_driver$(EXE) \
+	  test/kernel_driver$(EXE) $(AES_CALC) \
+	  test/env$(EXE)
+
+# data values used to test the aes_calc application for AES-128
+k128=000102030405060708090a0b0c0d0e0f
+p128=00112233445566778899aabbccddeeff
+c128=69c4e0d86a7b0430d8cdb78070b4c55a
+
+
+# data values used to test the aes_calc application for AES-256
+k256=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+p256=00112233445566778899aabbccddeeff
+c256=8ea2b7ca516745bfeafc49904b496089
+
+
+runtest: $(testapp)
+	$(FIND_LIBRARIES) test/env$(EXE) # print out information on the build environment
+	@echo "running crypto test applications..."
+ifneq (1, $(USE_EXTERNAL_CRYPTO))
+	$(FIND_LIBRARIES) test `test/aes_calc $(k128) $(p128)` = $(c128)
+	$(FIND_LIBRARIES) test `test/aes_calc $(k256) $(p256)` = $(c256)
+endif
+	$(FIND_LIBRARIES) test/cipher_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/datatypes_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/stat_driver$(EXE) >/dev/null
+	$(FIND_LIBRARIES) test/sha1_driver$(EXE) -v >/dev/null
+	$(FIND_LIBRARIES) test/kernel_driver$(EXE) -v >/dev/null
+	@echo "crypto test applications passed."
+
+
+# the rule for making object files and test apps
+
+%.o: %.c
+	$(COMPILE) -c $< -o $@
+
+%$(EXE): %.c $(srcdir)/../test/getopt_s.c
+	$(COMPILE) $(LDFLAGS) $< $(srcdir)/../test/getopt_s.c -o $@ $(CRYPTOLIB) $(LIBS)
+
+all: $(testapp)
+
+# housekeeping functions
+
+clean:
+	rm -f $(testapp) *.o */*.o
+	for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
+	rm -f `find . -name "*.[ch]~*~"`
+	rm -rf latex
+
+superclean: clean
+	rm -f *core TAGS ktrace.out
+
+# EOF
diff --git a/crypto/VERSION b/crypto/VERSION
deleted file mode 100644
index 3eefcb9..0000000
--- a/crypto/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.0.0
diff --git a/crypto/ae_xfm/xfm.c b/crypto/ae_xfm/xfm.c
deleted file mode 100644
index 144b832..0000000
--- a/crypto/ae_xfm/xfm.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * xfm.c
- *
- * Crypto transform implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-#include "cryptoalg.h"
-#include "aes_cbc.h"
-#include "hmac.h"
-#include "crypto_kernel.h"   /* for crypto_get_random() */
-
-#define KEY_LEN     16
-#define ENC_KEY_LEN 16
-#define MAC_KEY_LEN 16
-#define IV_LEN      16
-#define TAG_LEN     12
-#define MAX_EXPAND  27
-
-err_status_t
-aes_128_cbc_hmac_sha1_96_func(void *key,            
-			      void *clear,          
-			      unsigned clear_len,       
-			      void *iv,             
-			      void *opaque,         
-			      unsigned *opaque_len, 
-			      void *auth_tag) {
-  aes_cbc_ctx_t aes_ctx;
-  hmac_ctx_t hmac_ctx;
-  unsigned char enc_key[ENC_KEY_LEN];
-  unsigned char mac_key[MAC_KEY_LEN];
-  err_status_t status;
-
-  /* check if we're doing authentication only */
-  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
-      
-      /* perform authentication only */
-
-  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
-    
-    /*
-     * bad parameter - we expect either all three pointers to be NULL,
-     * or none of those pointers to be NULL 
-     */
-    return err_status_fail;
-
-  } else {
-
-    /* derive encryption and authentication keys from the input key */
-    status = hmac_init(&hmac_ctx, key, KEY_LEN);
-    if (status) return status;
-    status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
-    if (status) return status;
-
-    status = hmac_init(&hmac_ctx, key, KEY_LEN);
-    if (status) return status;
-    status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
-    if (status) return status;
-
-
-    /* perform encryption and authentication */
-
-    /* set aes key */
-    status = aes_cbc_context_init(&aes_ctx, key, 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, 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, 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, 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 {
-
-    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);
-    for (i=0; i < IV_LEN; i++)
-      init_vec[i] = i + (i * 16);
-    printf("iv:                %s\n", 
-	   octet_string_hex_string(iv, IV_LEN));
-    printf("plaintext:         %s\n", 
-	   octet_string_hex_string(opaque, *opaque_len));
-    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;
-    printf("protected data len: %d\n", *opaque_len);
-    printf("protected data:    %s\n", 
-	   octet_string_hex_string(opaque, *opaque_len));
-
-  }
-
-  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 {
-
-    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));
-    auth_tag = opaque;
-    auth_tag += (*opaque_len - NULL_TAG_LEN);
-    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));
-    *opaque_len -= NULL_TAG_LEN;
-    printf("plaintext len:  %d\n", *opaque_len);
-    printf("plaintext:  %s\n", 
-	   octet_string_hex_string(opaque, *opaque_len));
-  }
-
-  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:
-    return 0;
-  }
-  return 0;
-}
diff --git a/crypto/cipher/aes.c b/crypto/cipher/aes.c
index 4cbead0..c9cd774 100644
--- a/crypto/cipher/aes.c
+++ b/crypto/cipher/aes.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,12 +43,15 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include "aes.h"
 #include "err.h"
 
-/* 
- * 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
@@ -59,2110 +62,2128 @@
  * optimization on a different platform
  */
 
-#if (WORDS_BIGENDIAN == 0) /* assume little endian */
-
-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, 
+#ifndef WORDS_BIGENDIAN
+/* 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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
-
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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 */
 
-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
  */
-
-octet_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 */
 
-octet_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
+#ifndef CPU_RISC
+/* 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 */
 
-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
+#ifdef CPU_RISC
+/* 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 */
 
-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 */
 
-/*
- * gf2_8_shift(x) returns the result of the GF(2^8) 'multiply by x' 
- * operation, using the field representation from AES.  This function
- * is used in the AES key expansion routine.
- */
+static void aes_128_expand_encryption_key(const uint8_t *key,
+                                          srtp_aes_expanded_key_t *expanded_key)
+{
+    int i;
+    uint8_t rc;
 
-inline gf2_8
-gf2_8_shift(gf2_8 input) {
-  if ((input & 128) == 0)
-    return input << 1;
-  else
-    return (input << 1) ^ gf2_8_field_polynomial; 
+    /* initialize round constant */
+    rc = 1;
+
+    expanded_key->num_rounds = 10;
+
+    v128_copy_octet_string(&expanded_key->round[0], key);
+
+#if 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];
+
+        /* set remaining 32 bit words to the exor of the one previous with
+         * the one four words previous */
+
+        expanded_key->round[i].v32[1] =
+            expanded_key->round[i].v32[0] ^ expanded_key->round[i - 1].v32[1];
+
+        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(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);
+    }
 }
 
-inline void
-aes_expand_encryption_key(const v128_t 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;
-  
-  expanded_key[0].v32[0] = key.v32[0];
-  expanded_key[0].v32[1] = key.v32[1];
-  expanded_key[0].v32[2] = key.v32[2];
-  expanded_key[0].v32[3] = key.v32[3];
+    /* initialize round constant */
+    rc = 1;
 
-  /* loop over round keys */
-  for (i=1; i < 11; i++) {
+    expanded_key->num_rounds = 14;
 
-    /* munge first word of round key */
-    expanded_key[i].octet[0] = aes_sbox[expanded_key[i-1].octet[13]] ^ rc;
-    expanded_key[i].octet[1] = aes_sbox[expanded_key[i-1].octet[14]];
-    expanded_key[i].octet[2] = aes_sbox[expanded_key[i-1].octet[15]];
-    expanded_key[i].octet[3] = aes_sbox[expanded_key[i-1].octet[12]];
+    v128_copy_octet_string(&expanded_key->round[0], key);
+    v128_copy_octet_string(&expanded_key->round[1], key + 16);
 
-    expanded_key[i].v32[0] ^=  expanded_key[i-1].v32[0];
-    
-    /* set remaining 32 bit words to the exor of the one previous with
-     * the one four words previous */
-    
-    expanded_key[i].v32[1] =
-      expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1];
-    
-    expanded_key[i].v32[2] =
-      expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2];
-    
-    expanded_key[i].v32[3] =
-      expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3];
+#if 0
+    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
 
-    /* modify round constant */
-    rc = gf2_8_shift(rc);
+    /* 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
+    }
 }
 
-inline void
-aes_expand_decryption_key(const v128_t key, 
-			  aes_expanded_key_t expanded_key) {
-  int i;
+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;
+    }
+}
 
-  aes_expand_encryption_key(key, expanded_key);
+srtp_err_status_t srtp_aes_expand_decryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key)
+{
+    int i;
+    srtp_err_status_t status;
+    int num_rounds = expanded_key->num_rounds;
 
-  /* invert the order of the round keys */
-  for (i=0; i < 5; i++) {
-    v128_t tmp;
-    v128_copy(&tmp, &expanded_key[10-i]);
-    v128_copy(&expanded_key[10-i], &expanded_key[i]);
-    v128_copy(&expanded_key[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 < 10; i++) {
-#if CPU_RISC
-    uint32_t tmp;
+    status = srtp_aes_expand_encryption_key(key, key_len, expanded_key);
+    if (status) {
+        return status;
+    }
 
-    tmp = expanded_key[i].v32[0];
-    expanded_key[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];
+    /* 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);
+    }
 
-    tmp = expanded_key[i].v32[1];
-    expanded_key[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];
+    /*
+     * 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;
 
-    tmp = expanded_key[i].v32[2];
-    expanded_key[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];
+#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[i].v32[3];
-    expanded_key[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[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[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[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[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[i].octet[0]]] 
-       ^ U1[aes_sbox[expanded_key[i].octet[1]]] 
-       ^ U2[aes_sbox[expanded_key[i].octet[2]]] 
-       ^ U3[aes_sbox[expanded_key[i].octet[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[i].octet[4]]] 
-       ^ U1[aes_sbox[expanded_key[i].octet[5]]] 
-       ^ U2[aes_sbox[expanded_key[i].octet[6]]] 
-       ^ U3[aes_sbox[expanded_key[i].octet[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[i].octet[8]]] 
-       ^ U1[aes_sbox[expanded_key[i].octet[9]]] 
-       ^ U2[aes_sbox[expanded_key[i].octet[10]]] 
-       ^ U3[aes_sbox[expanded_key[i].octet[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[i].octet[12]]] 
-       ^ U1[aes_sbox[expanded_key[i].octet[13]]] 
-       ^ U2[aes_sbox[expanded_key[i].octet[14]]] 
-       ^ U3[aes_sbox[expanded_key[i].octet[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[i].v32[0] = c0;
-    expanded_key[i].v32[1] = c1;
-    expanded_key[i].v32[2] = c2;
-    expanded_key[i].v32[3] = c3;
-        
-#endif     
-  }
+        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
+    }
+
+    return srtp_err_status_ok;
 }
 
-#if CPU_CISC
+#ifdef CPU_CISC
 
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-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->octet[0]] ^ T1[state->octet[5]]
-    ^ T2[state->octet[10]] ^ T3[state->octet[15]];
-  
-  column1 = T0[state->octet[4]] ^ T1[state->octet[9]]
-    ^ T2[state->octet[14]] ^ T3[state->octet[3]];
+    column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
+              T3[state->v8[3]];
 
-  column2 = T0[state->octet[8]] ^ T1[state->octet[13]]
-    ^ T2[state->octet[2]] ^ T3[state->octet[7]];
+    column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
+              T3[state->v8[7]];
 
-  column3 = T0[state->octet[12]] ^ T1[state->octet[1]]
-    ^ T2[state->octet[6]] ^ T3[state->octet[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;
 
-inline void
-aes_inv_round(v128_t *state, const v128_t round_key) {
-  unsigned long 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->octet[0]] ^ U1[state->octet[13]]
-    ^ U2[state->octet[10]] ^ U3[state->octet[7]];
-  
-  column1 = U0[state->octet[4]] ^ U1[state->octet[1]]
-    ^ U2[state->octet[14]] ^ U3[state->octet[11]];
+    column1 = U0[state->v8[4]] ^ U1[state->v8[1]] ^ U2[state->v8[14]] ^
+              U3[state->v8[11]];
 
-  column2 = U0[state->octet[8]] ^ U1[state->octet[5]]
-    ^ U2[state->octet[2]] ^ U3[state->octet[15]];
+    column2 = U0[state->v8[8]] ^ U1[state->v8[5]] ^ U2[state->v8[2]] ^
+              U3[state->v8[15]];
 
-  column3 = U0[state->octet[12]] ^ U1[state->octet[9]]
-    ^ U2[state->octet[6]] ^ U3[state->octet[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];
 }
 
-inline void
-aes_final_round(v128_t *state, v128_t round_key) {
-  octet_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->octet[0] = aes_sbox[state->octet[0]];
-  state->octet[4] = aes_sbox[state->octet[4]];
-  state->octet[8] = aes_sbox[state->octet[8]];
-  state->octet[12] = aes_sbox[state->octet[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->octet[1]];
-  state->octet[1] = aes_sbox[state->octet[5]];
-  state->octet[5] = aes_sbox[state->octet[9]];
-  state->octet[9] = aes_sbox[state->octet[13]];
-  state->octet[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->octet[10]];
-  state->octet[10] = aes_sbox[state->octet[2]];
-  state->octet[2] = tmp;
-  tmp = aes_sbox[state->octet[14]];
-  state->octet[14] = aes_sbox[state->octet[6]];
-  state->octet[6] = tmp; 
-  
-  /* fourth row - shift three left */
-  tmp = aes_sbox[state->octet[15]];
-  state->octet[15] = aes_sbox[state->octet[11]];
-  state->octet[11] = aes_sbox[state->octet[7]];
-  state->octet[7] = aes_sbox[state->octet[3]];
-  state->octet[3] = 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;
 
-  v128_xor_eq(state, &round_key);
+    /* 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);
 }
 
-inline void
-aes_inv_final_round(v128_t *state, v128_t round_key) {
-  octet_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->octet[0] = aes_inv_sbox[state->octet[0]];
-  state->octet[4] = aes_inv_sbox[state->octet[4]];
-  state->octet[8] = aes_inv_sbox[state->octet[8]];
-  state->octet[12] = aes_inv_sbox[state->octet[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->octet[13]];
-  state->octet[13] = aes_inv_sbox[state->octet[9]];
-  state->octet[9] = aes_inv_sbox[state->octet[5]];
-  state->octet[5] = aes_inv_sbox[state->octet[1]];
-  state->octet[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->octet[2]];
-  state->octet[2] = aes_inv_sbox[state->octet[10]];
-  state->octet[10] = tmp;
-  tmp = aes_inv_sbox[state->octet[6]];
-  state->octet[6] = aes_inv_sbox[state->octet[14]];
-  state->octet[14] = tmp; 
-  
-  /* fourth row - shift three right */
-  tmp = aes_inv_sbox[state->octet[3]];
-  state->octet[3] = aes_inv_sbox[state->octet[7]];
-  state->octet[7] = aes_inv_sbox[state->octet[11]];
-  state->octet[11] = aes_inv_sbox[state->octet[15]];
-  state->octet[15] = 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;
 
-  v128_xor_eq(state, &round_key);
+    /* 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);
 }
 
-
 #elif CPU_RISC
 
-#if !WORDS_BIGENDIAN
-#error "only big-endian RISC is supported, please choose CPU_CISC in config.h"
-#endif
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-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];
 
-  /* compute the columns of the output square in terms of the octets
-     of state, using the tables T0, T1, T2, T3 */
+    column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff] ^
+              T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
 
-  column0 = T0[state->v32[0] >> 24] ^ T1[(state->v32[1] >> 16) & 0xff]
-    ^ T2[(state->v32[2] >> 8) & 0xff] ^ T3[state->v32[3] & 0xff];
-  
-  column1 = T0[state->v32[1] >> 24] ^ T1[(state->v32[2] >> 16) & 0xff]
-    ^ T2[(state->v32[3] >> 8) & 0xff] ^ T3[state->v32[0] & 0xff];
+    column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff] ^
+              T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
 
-  column2 = T0[state->v32[2] >> 24] ^ T1[(state->v32[3] >> 16) & 0xff]
-    ^ T2[(state->v32[0] >> 8) & 0xff] ^ T3[state->v32[1] & 0xff];
+    column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff] ^
+              T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
+#else
+    column0 = T0[state->v32[0] & 0xff] ^ T1[(state->v32[1] >> 8) & 0xff] ^
+              T2[(state->v32[2] >> 16) & 0xff] ^ T3[state->v32[3] >> 24];
 
-  column3 = T0[state->v32[3] >> 24] ^ T1[(state->v32[0] >> 16) & 0xff]
-    ^ T2[(state->v32[1] >> 8) & 0xff] ^ T3[state->v32[2] & 0xff];
+    column1 = T0[state->v32[1] & 0xff] ^ T1[(state->v32[2] >> 8) & 0xff] ^
+              T2[(state->v32[3] >> 16) & 0xff] ^ T3[state->v32[0] >> 24];
 
-  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] & 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 */
+
+    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];
 }
 
-inline void
-aes_inv_round(v128_t *state, const v128_t round_key) {
-  unsigned long 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->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];
+#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];
 
-  column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff]
-    ^ U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 0xff];
+    column1 = U0[state->v32[1] >> 24] ^ U1[(state->v32[0] >> 16) & 0xff] ^
+              U2[(state->v32[3] >> 8) & 0xff] ^ U3[state->v32[2] & 0xff];
 
-  column3 = U0[state->v32[3] >> 24] ^ U1[(state->v32[2] >> 16) & 0xff]
-    ^ U2[(state->v32[1] >> 8) & 0xff] ^ U3[state->v32[0] & 0xff];
+    column2 = U0[state->v32[2] >> 24] ^ U1[(state->v32[1] >> 16) & 0xff] ^
+              U2[(state->v32[0] >> 8) & 0xff] ^ U3[state->v32[3] & 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];
-  
+    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];
 }
 
-inline void
-aes_final_round(v128_t *state, 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];
+#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];
 
-  tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[0]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[1];
+    tmp1 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[1]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[2];
+    tmp2 = (T4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-  tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000)
-       ^ (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
-       ^ (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)
-       ^ (T4[(state->v32[2]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[3];
+    tmp3 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+#else
+    tmp0 = (T4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[0]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-  state->v32[0] = tmp0;
-  state->v32[1] = tmp1;
-  state->v32[2] = tmp2;
-  state->v32[3] = tmp3;
+    tmp1 = (T4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
+    tmp2 = (T4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (T4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (T4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (T4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
+
+    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;
 }
 
-inline void
-aes_inv_final_round(v128_t *state, v128_t round_key) {
-  uint32_t tmp0, tmp1, tmp2, tmp3;
+static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t tmp0, tmp1, tmp2, tmp3;
 
-  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];
+#ifdef WORDS_BIGENDIAN
+    /* clang-format off */
+    tmp0 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[0];
 
-  tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[2]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[1];
+    tmp1 = (U4[(state->v32[1] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[3] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
-  tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[3]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[2];
+    tmp2 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
 
-  tmp3 = (U4[(state->v32[3] >> 24)]        & 0xff000000)
-       ^ (U4[(state->v32[2] >> 16) & 0xff] & 0x00ff0000)
-       ^ (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00)
-       ^ (U4[(state->v32[0]      ) & 0xff] & 0x000000ff)
-       ^ round_key.v32[3];
+    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];
 
-  state->v32[0] = tmp0;
-  state->v32[1] = tmp1;
-  state->v32[2] = tmp2;
-  state->v32[3] = tmp3;
+    tmp1 = (U4[(state->v32[2] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[3] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[0] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[1]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[1];
 
+    tmp2 = (U4[(state->v32[3] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[0] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[1] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[2]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[2];
+
+    tmp3 = (U4[(state->v32[0] >> 24)]        & 0xff000000) ^
+           (U4[(state->v32[1] >> 16) & 0xff] & 0x00ff0000) ^
+           (U4[(state->v32[2] >>  8) & 0xff] & 0x0000ff00) ^
+           (U4[(state->v32[3]      ) & 0xff] & 0x000000ff) ^
+           round_key->v32[3];
+/* clang-format on */
+#endif /* WORDS_BIGENDIAN */
+
+    state->v32[0] = tmp0;
+    state->v32[1] = tmp1;
+    state->v32[2] = tmp2;
+    state->v32[3] = tmp3;
 }
 
-#elif CPU_16  /* assume 16-bit word size on processor */
+#elif CPU_16 /* assume 16-bit word size on processor */
 
-inline void
-aes_round(v128_t *state, const v128_t round_key) {
-  unsigned long 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 */
+static inline void aes_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
+    /* compute the columns of the output square in terms of the octets
+       of state, using the tables T0, T1, T2, T3 */
 
-  column0 = T0[state->octet[0]] ^ T1[state->octet[5]]
-    ^ T2[state->octet[10]] ^ T3[state->octet[15]];
-  
-  column1 = T0[state->octet[4]] ^ T1[state->octet[9]]
-    ^ T2[state->octet[14]] ^ T3[state->octet[3]];
+    column0 = T0[state->v8[0]] ^ T1[state->v8[5]] ^ T2[state->v8[10]] ^
+              T3[state->v8[15]];
 
-  column2 = T0[state->octet[8]] ^ T1[state->octet[13]]
-    ^ T2[state->octet[2]] ^ T3[state->octet[7]];
+    column1 = T0[state->v8[4]] ^ T1[state->v8[9]] ^ T2[state->v8[14]] ^
+              T3[state->v8[3]];
 
-  column3 = T0[state->octet[12]] ^ T1[state->octet[1]]
-    ^ T2[state->octet[6]] ^ T3[state->octet[11]];
+    column2 = T0[state->v8[8]] ^ T1[state->v8[13]] ^ T2[state->v8[2]] ^
+              T3[state->v8[7]];
 
-  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];
-  
+    column3 = T0[state->v8[12]] ^ T1[state->v8[1]] ^ T2[state->v8[6]] ^
+              T3[state->v8[11]];
+
+    state->v32[0] = column0 ^ round_key->v32[0];
+    state->v32[1] = column1 ^ round_key->v32[1];
+    state->v32[2] = column2 ^ round_key->v32[2];
+    state->v32[3] = column3 ^ round_key->v32[3];
 }
 
+static inline void aes_inv_round(v128_t *state, const v128_t *round_key)
+{
+    uint32_t column0, column1, column2, column3;
 
-inline void
-aes_inv_round(v128_t *state, const v128_t round_key) {
-  unsigned long 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[5]] ^ U2[state->v8[10]] ^
+              U3[state->v8[15]];
 
-  column0 = U0[state->octet[0]] ^ U1[state->octet[5]]
-    ^ U2[state->octet[10]] ^ U3[state->octet[15]];
-  
-  column1 = U0[state->octet[4]] ^ U1[state->octet[9]]
-    ^ U2[state->octet[14]] ^ U3[state->octet[3]];
+    column1 = U0[state->v8[4]] ^ U1[state->v8[9]] ^ U2[state->v8[14]] ^
+              U3[state->v8[3]];
 
-  column2 = U0[state->octet[8]] ^ U1[state->octet[13]]
-    ^ U2[state->octet[2]] ^ U3[state->octet[7]];
+    column2 = U0[state->v8[8]] ^ U1[state->v8[13]] ^ U2[state->v8[2]] ^
+              U3[state->v8[7]];
 
-  column3 = U0[state->octet[12]] ^ U1[state->octet[1]]
-    ^ U2[state->octet[6]] ^ U3[state->octet[11]];
+    column3 = U0[state->v8[12]] ^ U1[state->v8[1]] ^ U2[state->v8[6]] ^
+              U3[state->v8[11]];
 
-  state->v32[0] = column0 ^ round_key.v32[0];
-  state->v32[1] = column1 ^ round_key.v32[1];
-  state->v32[2] = column2 ^ round_key.v32[2];
-  state->v32[3] = column3 ^ round_key.v32[3];
-  
+    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];
 }
 
-inline void
-aes_final_round(v128_t *state, v128_t round_key) {
-  octet_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->octet[0] = aes_sbox[state->octet[0]];
-  state->octet[4] = aes_sbox[state->octet[4]];
-  state->octet[8] = aes_sbox[state->octet[8]];
-  state->octet[12] = aes_sbox[state->octet[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->octet[1]];
-  state->octet[1] = aes_sbox[state->octet[5]];
-  state->octet[5] = aes_sbox[state->octet[9]];
-  state->octet[9] = aes_sbox[state->octet[13]];
-  state->octet[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->octet[10]];
-  state->octet[10] = aes_sbox[state->octet[2]];
-  state->octet[2] = tmp;
-  tmp = aes_sbox[state->octet[14]];
-  state->octet[14] = aes_sbox[state->octet[6]];
-  state->octet[6] = tmp; 
-  
-  /* fourth row - shift three left */
-  tmp = aes_sbox[state->octet[15]];
-  state->octet[15] = aes_sbox[state->octet[11]];
-  state->octet[11] = aes_sbox[state->octet[7]];
-  state->octet[7] = aes_sbox[state->octet[3]];
-  state->octet[3] = 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;
 
-  v128_xor_eq(state, &round_key);
+    /* 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);
 }
 
-inline void
-aes_inv_final_round(v128_t *state, v128_t round_key) {
-  octet_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->octet[0] = aes_inv_sbox[state->octet[0]];
-  state->octet[4] = aes_inv_sbox[state->octet[4]];
-  state->octet[8] = aes_inv_sbox[state->octet[8]];
-  state->octet[12] = aes_inv_sbox[state->octet[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 left */
-  tmp = aes_inv_sbox[state->octet[1]];
-  state->octet[1] = aes_inv_sbox[state->octet[5]];
-  state->octet[5] = aes_inv_sbox[state->octet[9]];
-  state->octet[9] = aes_inv_sbox[state->octet[13]];
-  state->octet[13] = tmp;
+    /* 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->octet[10]];
-  state->octet[10] = aes_inv_sbox[state->octet[2]];
-  state->octet[2] = tmp;
-  tmp = aes_inv_sbox[state->octet[14]];
-  state->octet[14] = aes_inv_sbox[state->octet[6]];
-  state->octet[6] = tmp; 
-  
-  /* fourth row - shift three left */
-  tmp = aes_inv_sbox[state->octet[15]];
-  state->octet[15] = aes_inv_sbox[state->octet[11]];
-  state->octet[11] = aes_inv_sbox[state->octet[7]];
-  state->octet[7] = aes_inv_sbox[state->octet[3]];
-  state->octet[3] = 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;
 
-  v128_xor_eq(state, &round_key);
+    /* 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);
 }
 
-#endif  /* CPU type */
+#endif /* CPU type */
 
-inline void
-aes_add_in_subkey(v128_t *state, v128_t round_key) {
-  state->v32[0] ^= round_key.v32[0];
-  state->v32[1] ^= round_key.v32[1];
-  state->v32[2] ^= round_key.v32[2];
-  state->v32[3] ^= round_key.v32[3];    
+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_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]);
 
-#if THIS_ASM_CODE_WORKS /* DAM - fix this! */
-
-/*
- *     T0      starts at 0x804e600
- *     T1      starts at 0x804ea00
- *     T2      starts at 0x804ee00
- *     T3      starts at 0x804f200
- *
- * Interface:
- *
- *     ebp     pointer to the stack
- *		0x8(%ebp)	pointer to message
- *		0xc(%ebp)	pointer to key
- *	eax	pointer to data (loaded with 0x8(%ebp))
- *	ebx 	temp used for address computation
- *	ecx	column0
- *	edx	column1
- *	esi	column2
- *	edi	column3
- */
-
-#define ROUND(ADD0,ADD1,ADD2,ADD3)      \
-asm ("mov    (%eax),%eax");             \
-asm ("movzx  %al, %ebx");               \
-asm ("mov    T0(,%ebx,4),%ecx");        \
-asm ("movzx  %ah,%ebx");		\
-asm ("mov    T1(,%ebx,4),%edi");        \
-asm ("bswap  %eax");			\
-asm ("movzx  %ah,%ebx");                \
-asm ("mov    T2(,%ebx,4),%esi");        \
-asm ("movzx  %al,%ebx");                \
-asm ("mov    T3(,%ebx,4),%edx");        \
-asm ("mov    0x8(%ebp),%eax");          \
-asm ("mov    0x4(%eax),%eax");          \
-asm ("movzx  %al, %ebx");               \
-asm ("xor    T0(,%ebx,4),%edx");        \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T1(,%ebx,4),%ecx");        \
-asm ("bswap  %eax");                    \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T2(,%ebx,4),%edi");        \
-asm ("movzx  %al,%ebx");                \
-asm ("xor    T3(,%ebx,4),%esi");        \
-asm ("mov    0x8(%ebp),%eax");          \
-asm ("mov    0x8(%eax),%eax");          \
-asm ("movzx  %al, %ebx");               \
-asm ("xor    T0(,%ebx,4),%esi");        \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T1(,%ebx,4),%edx");        \
-asm ("bswap  %eax");                    \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T2(,%ebx,4),%ecx");        \
-asm ("movzx  %al,%ebx");                \
-asm ("xor    T3(,%ebx,4),%edi");        \
-asm ("mov    0x8(%ebp),%eax");          \
-asm ("mov    0xc(%eax),%eax");          \
-asm ("movzx  %al, %ebx");               \
-asm ("xor    T0(,%ebx,4),%edi");        \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T1(,%ebx,4),%esi");        \
-asm ("bswap  %eax");                    \
-asm ("movzx  %ah,%ebx");                \
-asm ("xor    T2(,%ebx,4),%edx");        \
-asm ("movzx  %al,%ebx");                \
-asm ("xor    T3(,%ebx,4),%ecx");        \
-asm ("mov    0x8(%ebp),%eax");          \
-asm ("mov    0xc(%ebp),%ebx");          \
-asm ("xor    "#ADD0"(%ebx),%ecx");      \
-asm ("mov    %ecx,(%eax)");             \
-asm ("xor    "#ADD1"(%ebx),%edx");      \
-asm ("mov    %edx,0x4(%eax)");          \
-asm ("xor    "#ADD2"(%ebx),%esi");      \
-asm ("mov    %esi,0x8(%eax)");          \
-asm ("xor    "#ADD3"(%ebx),%edi");      \
-asm ("mov    %edi,0xc(%eax)");
-
-void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
-  extern uint32_t T0[256], T1[256], T2[256], T3[256], T4[256]; 
-
-  
-  asm ("sub    $0x5c,%esp");
-  asm ("push   %edi");
-  asm ("push   %esi");
-  asm ("push   %ebx");
-  asm ("mov    0x8(%ebp),%ecx");
-  asm ("mov    (%ecx),%eax");
-  asm ("mov    0x4(%ecx),%edx");
-  asm ("mov    0xc(%ebp),%ecx");
-  asm ("xor    (%ecx),%eax");
-  asm ("xor    0x4(%ecx),%edx");
-  asm ("mov    0x8(%ebp),%ecx");
-  asm ("mov    %eax,(%ecx)");
-  asm ("mov    %edx,0x4(%ecx)");
-  asm ("mov    0x8(%ebp),%eax");
-  asm ("mov    0x8(%eax),%ebx");
-  asm ("mov    0xc(%eax),%esi");
-  asm ("mov    0xc(%ebp),%eax");
-  asm ("xor    0x8(%eax),%ebx");
-  asm ("xor    0xc(%eax),%esi");
-  asm ("mov    0x8(%ebp),%eax");
-  asm ("mov    %ebx,0x8(%eax)");
-  asm ("mov    %esi,0xc(%eax)");
-  // Initialize column0, 1, 2, & 3 (ROUND assumes them loaded)
-  asm ("mov    (%eax),%ecx");
-  asm ("mov    0x4(%eax),%edx");
-  asm ("mov    0x8(%eax),%esi");
-  asm ("mov    0xc(%eax),%edi");
-  //
-  // ROUND 1
-  //
-  ROUND(0x10,0x14,0x18,0x1c)
-    //
-    // ROUND 2
-    //
-    ROUND(0x20,0x24,0x28,0x2c)
-    //
-    // ROUND 3
-    //
-    ROUND(0x30,0x34,0x38,0x3c)
-    //
-    // ROUND 4
-    //
-    ROUND(0x40,0x44,0x48,0x4c)
-    //
-    // ROUND 5
-    //
-    ROUND(0x50,0x54,0x58,0x5c)
-    //
-    // ROUND 6
-    //
-    ROUND(0x60,0x64,0x68,0x6c)
-    //
-    // ROUND 7
-    //
-    ROUND(0x70,0x74,0x78,0x7c)
-    // 
-    // ROUND 8
-    //
-    ROUND(0x80,0x84,0x88,0x8c)
-    //
-    // ROUND 9
-    //
-    ROUND(0x90,0x94,0x98,0x9c)
-    asm ("mov    0xc(%ebp),%eax");
-  asm ("mov    0x8(%ebp),%esi");
-  //
-  // LAST ROUND (10)
-  //
-  asm ("mov    0xa0(%eax),%edx");
-  asm ("mov    %edx,0xfffffff0(%ebp)");
-  asm ("mov    0xa4(%eax),%edx");
-  asm ("mov    %edx,0xfffffff4(%ebp)");
-  asm ("mov    0xa8(%eax),%edx");
-  asm ("mov    %edx,0xfffffff8(%ebp)");
-  asm ("mov    0xac(%eax),%edx");
-  asm ("mov    %edx,0xfffffffc(%ebp)");
-  asm ("movzbl (%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,(%esi)");
-  asm ("movzbl 0x4(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x4(%esi)");
-  asm ("movzbl 0x8(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x8(%esi)");
-  asm ("movzbl 0xc(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0xc(%esi)");
-  asm ("movzbl 0x1(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%cl");
-  asm ("movzbl 0x5(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x1(%esi)");
-  asm ("movzbl 0x9(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x5(%esi)");
-  asm ("movzbl 0xd(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x9(%esi)");
-  asm ("mov    %cl,0xd(%esi)");
-  asm ("movzbl 0xa(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%cl");
-  asm ("movzbl 0x2(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0xa(%esi)");
-  asm ("mov    %cl,0x2(%esi)");
-  asm ("movzbl 0xe(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%cl");
-  asm ("movzbl 0x6(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0xe(%esi)");
-  asm ("mov    %cl,0x6(%esi)");
-  asm ("movzbl 0xf(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%cl");
-  asm ("movzbl 0xb(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0xf(%esi)");
-  asm ("movzbl 0x7(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0xb(%esi)");
-  asm ("movzbl 0x3(%esi),%edx");
-  asm ("mov    aes_sbox(%edx),%dl");
-  asm ("mov    %dl,0x7(%esi)");
-  asm ("mov    %cl,0x3(%esi)");
-  asm ("mov    0x8(%ebp),%eax");
-  asm ("mov    (%eax),%ebx");
-  asm ("mov    0x4(%eax),%esi");
-  asm ("xor    0xfffffff0(%ebp),%ebx");
-  asm ("xor    0xfffffff4(%ebp),%esi");
-  asm ("mov    %ebx,(%eax)");
-  asm ("mov    %esi,0x4(%eax)");
-  asm ("mov    0x8(%ebp),%eax");
-  asm ("mov    0x8(%eax),%ebx");
-  asm ("mov    0xc(%eax),%esi");
-  asm ("xor    0xfffffff8(%ebp),%ebx");
-  asm ("xor    0xfffffffc(%ebp),%esi");
-  asm ("mov    %ebx,0x8(%eax)");
-  asm ("mov    %esi,0xc(%eax)");
-  asm ("pop    %ebx");
-  asm ("pop    %esi");
-  asm ("pop    %edi");
-  asm ("add    $0x5c,%esp");
+    /* 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]);
+    }
 }
-
-#else /* unknown CPU type */
-
-void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
-
-  /* add in the subkey */
-  /* v128_xor_eq(plaintext, &exp_key[0]); */
-  aes_add_in_subkey(plaintext, exp_key[0]);
-
-  /* now do nine rounds */
-  aes_round(plaintext, exp_key[1]);
-  aes_round(plaintext, exp_key[2]);
-  aes_round(plaintext, exp_key[3]);
-  aes_round(plaintext, exp_key[4]);
-  aes_round(plaintext, exp_key[5]);
-  aes_round(plaintext, exp_key[6]);
-  aes_round(plaintext, exp_key[7]);
-  aes_round(plaintext, exp_key[8]);  
-  aes_round(plaintext, exp_key[9]);
-  /* the last round is different */
- 
- aes_final_round(plaintext, exp_key[10]);  
-
- }
-
-void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
-  
-  /* add in the subkey */
-  /* v128_xor_eq(plaintext, &exp_key[10]); */
-  aes_add_in_subkey(plaintext, exp_key[0]);
-
-  /* now do nine rounds */
-  aes_inv_round(plaintext, exp_key[1]);
-  aes_inv_round(plaintext, exp_key[2]);
-  aes_inv_round(plaintext, exp_key[3]);
-  aes_inv_round(plaintext, exp_key[4]);
-  aes_inv_round(plaintext, exp_key[5]);
-  aes_inv_round(plaintext, exp_key[6]);
-  aes_inv_round(plaintext, exp_key[7]);
-  aes_inv_round(plaintext, exp_key[8]);  
-  aes_inv_round(plaintext, exp_key[9]);
-  /* the last round is different */
-  aes_inv_final_round(plaintext, exp_key[10]);  
-
-}
-
-#endif /* THIS_ASM_CODE_WORKS */
-
diff --git a/crypto/cipher/aes_cbc.c b/crypto/cipher/aes_cbc.c
deleted file mode 100644
index 0c69f48..0000000
--- a/crypto/cipher/aes_cbc.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * aes_cbc.c
- *
- * AES Cipher Block Chaining Mode
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#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)
-    return err_status_bad_param;
-  
-  /* allocate memory a cipher of type aes_icm */
-  tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
-  pointer = 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((octet_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 octet_t *key, 
-		     cipher_direction_t dir) {
-  v128_t tmp_key;
-
-  /* set tmp_key (for alignment) */
-  v128_copy_octet_string(&tmp_key, key);
-
-  debug_print(mod_aes_cbc, 
-	      "key:  %s", v128_hex_string(&tmp_key)); 
-
-  /* expand key for the appropriate direction */
-  switch (dir) {
-  case (direction_encrypt):
-    aes_expand_encryption_key(tmp_key, c->expanded_key);
-    break;
-  case (direction_decrypt):
-    aes_expand_decryption_key(tmp_key, c->expanded_key);
-    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; */
-  octet_t *input = iv;
- 
-  /* set state and 'previous' block to iv */
-  for (i=0; i < 16; i++) 
-    c->previous.octet[i] = c->state.octet[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.octet[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.octet[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;
-  octet_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.octet[i] = c->previous.octet[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.octet[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.octet[i] ^ previous.octet[i];
-      previous.octet[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 A; 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.
- *
- */
-
-
-octet_t aes_cbc_test_case_0_key[16] = {
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
-};
-
-octet_t aes_cbc_test_case_0_plaintext[64] =  {
-  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff 
-};
-
-octet_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
-
-};
-
-octet_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
- */
-
-octet_t aes_cbc_test_case_1_key[16] = {
-  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
-  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
-};
-
-octet_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
-};
-
-octet_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
-};
-
-octet_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 */
-};
-
-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_0,
-  (debug_module_t *)            &mod_aes_cbc
-};
-
-
diff --git a/crypto/cipher/aes_gcm_nss.c b/crypto/cipher/aes_gcm_nss.c
new file mode 100644
index 0000000..54547cd
--- /dev/null
+++ b/crypto/cipher/aes_gcm_nss.c
@@ -0,0 +1,609 @@
+/*
+ * aes_gcm_nss.c
+ *
+ * AES Galois Counter Mode
+ *
+ * Richard L. Barnes
+ * Cisco Systems, Inc.
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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_gcm.h"
+#include "alloc.h"
+#include "err.h" /* for srtp_debug */
+#include "crypto_types.h"
+#include "cipher_types.h"
+#include <secerr.h>
+#include <nspr.h>
+
+srtp_debug_module_t srtp_mod_aes_gcm = {
+    0,            /* debugging is off by default */
+    "aes gcm nss" /* printable module name       */
+};
+
+/*
+ * For now we only support 8 and 16 octet tags.  The spec allows for
+ * optional 12 byte tag, which may be supported in the future.
+ */
+#define GCM_IV_LEN 12
+#define GCM_AUTH_TAG_LEN 16
+#define GCM_AUTH_TAG_LEN_8 8
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 28 or 44 for
+ * AES-128-GCM or AES-256-GCM respectively.  Note that the
+ * key length includes the 14 byte salt value that is used when
+ * initializing the KDF.
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_alloc(srtp_cipher_t **c,
+                                                int key_len,
+                                                int tlen)
+{
+    srtp_aes_gcm_ctx_t *gcm;
+    NSSInitContext *nss;
+
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d",
+                key_len);
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
+
+    /*
+     * Verify the key_len is valid for one of: AES-128/256
+     */
+    if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
+        return (srtp_err_status_bad_param);
+    }
+
+    if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
+        return (srtp_err_status_bad_param);
+    }
+
+    /* Initialize NSS equiv of NSS_NoDB_Init(NULL) */
+    nss = NSS_InitContext("", "", "", "", NULL,
+                          NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
+                              NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
+                              NSS_INIT_OPTIMIZESPACE);
+    if (!nss) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* allocate memory a cipher of type aes_gcm */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        NSS_ShutdownContext(nss);
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
+    if (gcm == NULL) {
+        NSS_ShutdownContext(nss);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm->nss = nss;
+
+    /* set pointers */
+    (*c)->state = gcm;
+
+    /* setup cipher attributes */
+    switch (key_len) {
+    case SRTP_AES_GCM_128_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_128;
+        (*c)->algorithm = SRTP_AES_GCM_128;
+        gcm->key_size = SRTP_AES_128_KEY_LEN;
+        gcm->tag_size = tlen;
+        gcm->params.ulTagBits = 8 * tlen;
+        break;
+    case SRTP_AES_GCM_256_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_256;
+        (*c)->algorithm = SRTP_AES_GCM_256;
+        gcm->key_size = SRTP_AES_256_KEY_LEN;
+        gcm->tag_size = tlen;
+        gcm->params.ulTagBits = 8 * tlen;
+        break;
+    default:
+        /* this should never hit, but to be sure... */
+        return (srtp_err_status_bad_param);
+    }
+
+    /* set key size and tag size*/
+    (*c)->key_len = key_len;
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function deallocates a GCM session
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_gcm_ctx_t *ctx;
+
+    ctx = (srtp_aes_gcm_ctx_t *)c->state;
+    if (ctx) {
+        /* release NSS resources */
+        if (ctx->key) {
+            PK11_FreeSymKey(ctx->key);
+        }
+
+        if (ctx->nss) {
+            NSS_ShutdownContext(ctx->nss);
+            ctx->nss = NULL;
+        }
+
+        /* zeroize the key material */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_nss_context_init(...) initializes the aes_gcm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_context_init(void *cv,
+                                                       const uint8_t *key)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    c->dir = srtp_direction_any;
+
+    debug_print(srtp_mod_aes_gcm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+
+    if (c->key) {
+        PK11_FreeSymKey(c->key);
+        c->key = NULL;
+    }
+
+    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_AES_GCM, NULL);
+    if (!slot) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    SECItem key_item = { siBuffer, (unsigned char *)key, c->key_size };
+    c->key = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
+                               CKA_ENCRYPT, &key_item, NULL);
+    PK11_FreeSlot(slot);
+
+    if (!c->key) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_nss_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_set_iv(
+    void *cv,
+    uint8_t *iv,
+    srtp_cipher_direction_t direction)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    if (direction != srtp_direction_encrypt &&
+        direction != srtp_direction_decrypt) {
+        return (srtp_err_status_bad_param);
+    }
+    c->dir = direction;
+
+    debug_print(srtp_mod_aes_gcm, "setting iv: %s",
+                srtp_octet_string_hex_string(iv, GCM_IV_LEN));
+
+    memcpy(c->iv, iv, GCM_IV_LEN);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function processes the AAD
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	aad	Additional data to process for AEAD cipher suites
+ *	aad_len	length of aad buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_set_aad(void *cv,
+                                                  const uint8_t *aad,
+                                                  uint32_t aad_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
+                srtp_octet_string_hex_string(aad, aad_len));
+
+    if (aad_len + c->aad_size > MAX_AD_SIZE) {
+        return srtp_err_status_bad_param;
+    }
+
+    memcpy(c->aad + c->aad_size, aad, aad_len);
+    c->aad_size += aad_len;
+
+    return (srtp_err_status_ok);
+}
+
+static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv,
+                                                    int encrypt,
+                                                    unsigned char *buf,
+                                                    unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    c->params.pIv = c->iv;
+    c->params.ulIvLen = GCM_IV_LEN;
+    c->params.pAAD = c->aad;
+    c->params.ulAADLen = c->aad_size;
+
+    // Reset AAD
+    c->aad_size = 0;
+
+    int rv;
+    SECItem param = { siBuffer, (unsigned char *)&c->params,
+                      sizeof(CK_GCM_PARAMS) };
+    if (encrypt) {
+        rv = PK11_Encrypt(c->key, CKM_AES_GCM, &param, buf, enc_len,
+                          *enc_len + 16, buf, *enc_len);
+    } else {
+        rv = PK11_Decrypt(c->key, CKM_AES_GCM, &param, buf, enc_len, *enc_len,
+                          buf, *enc_len);
+    }
+
+    srtp_err_status_t status = (srtp_err_status_ok);
+    if (rv != SECSuccess) {
+        status = (srtp_err_status_cipher_fail);
+    }
+
+    return status;
+}
+
+/*
+ * This function encrypts a buffer using AES GCM mode
+ *
+ * XXX(rlb@ipv.sx): We're required to break off and cache the tag
+ * here, because the get_tag() method is separate and the tests expect
+ * encrypt() not to change the size of the plaintext.  It might be
+ * good to update the calling API so that this is cleaner.
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_encrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    // When we get a non-NULL buffer, we know that the caller is
+    // prepared to also take the tag.  When we get a NULL buffer,
+    // even though there's no data, we need to give NSS a buffer
+    // where it can write the tag.  We can't just use c->tag because
+    // memcpy has undefined behavior on overlapping ranges.
+    unsigned char tagbuf[16];
+    unsigned char *non_null_buf = buf;
+    if (!non_null_buf && (*enc_len == 0)) {
+        non_null_buf = tagbuf;
+    } else if (!non_null_buf) {
+        return srtp_err_status_bad_param;
+    }
+
+    srtp_err_status_t status =
+        srtp_aes_gcm_nss_do_crypto(cv, 1, non_null_buf, enc_len);
+    if (status != srtp_err_status_ok) {
+        return status;
+    }
+
+    memcpy(c->tag, non_null_buf + (*enc_len - c->tag_size), c->tag_size);
+    *enc_len -= c->tag_size;
+    return srtp_err_status_ok;
+}
+
+/*
+ * This function calculates and returns the GCM tag for a given context.
+ * This should be called after encrypting the data.  The *len value
+ * is increased by the tag size.  The caller must ensure that *buf has
+ * enough room to accept the appended tag.
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_get_tag(void *cv,
+                                                  uint8_t *buf,
+                                                  uint32_t *len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    *len = c->tag_size;
+    memcpy(buf, c->tag, c->tag_size);
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function decrypts a buffer using AES GCM mode
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_nss_decrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_err_status_t status = srtp_aes_gcm_nss_do_crypto(cv, 0, buf, enc_len);
+    if (status != srtp_err_status_ok) {
+        int err = PR_GetError();
+        if (err == SEC_ERROR_BAD_DATA) {
+            status = srtp_err_status_auth_fail;
+        }
+    }
+
+    return status;
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_gcm_128_nss_description[] = "AES-128 GCM using NSS";
+static const char srtp_aes_gcm_256_nss_description[] = "AES-256 GCM using NSS";
+
+/*
+ * KAT values for AES self-test.  These
+ * values we're derived from independent test code
+ * using OpenSSL.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_key[SRTP_AES_GCM_128_KEY_LEN_WSALT] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x09, 0x0a, 0x0b, 0x0c,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] =  {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_aad[20] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+    0x3d, 0x58, 0xe0, 0x91,
+    /* the last 16 bytes are the tag */
+    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_0a           /* pointer to next testcase */
+};
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_key[SRTP_AES_GCM_256_KEY_LEN_WSALT] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
+    0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x09, 0x0a, 0x0b, 0x0c,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] =  {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_aad[20] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
+    0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
+    0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
+    0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
+    0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
+    0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
+    0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
+    0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
+    0x09, 0xc9, 0x86, 0xc1,
+    /* the last 16 bytes are the tag */
+    0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
+    0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_1a           /* pointer to next testcase */
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+/* clang-format off */
+const srtp_cipher_type_t srtp_aes_gcm_128 = {
+    srtp_aes_gcm_nss_alloc,
+    srtp_aes_gcm_nss_dealloc,
+    srtp_aes_gcm_nss_context_init,
+    srtp_aes_gcm_nss_set_aad,
+    srtp_aes_gcm_nss_encrypt,
+    srtp_aes_gcm_nss_decrypt,
+    srtp_aes_gcm_nss_set_iv,
+    srtp_aes_gcm_nss_get_tag,
+    srtp_aes_gcm_128_nss_description,
+    &srtp_aes_gcm_test_case_0,
+    SRTP_AES_GCM_128
+};
+/* clang-format on */
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+/* clang-format off */
+const srtp_cipher_type_t srtp_aes_gcm_256 = {
+    srtp_aes_gcm_nss_alloc,
+    srtp_aes_gcm_nss_dealloc,
+    srtp_aes_gcm_nss_context_init,
+    srtp_aes_gcm_nss_set_aad,
+    srtp_aes_gcm_nss_encrypt,
+    srtp_aes_gcm_nss_decrypt,
+    srtp_aes_gcm_nss_set_iv,
+    srtp_aes_gcm_nss_get_tag,
+    srtp_aes_gcm_256_nss_description,
+    &srtp_aes_gcm_test_case_1,
+    SRTP_AES_GCM_256
+};
+/* clang-format on */
diff --git a/crypto/cipher/aes_gcm_ossl.c b/crypto/cipher/aes_gcm_ossl.c
new file mode 100644
index 0000000..90d5e3b
--- /dev/null
+++ b/crypto/cipher/aes_gcm_ossl.c
@@ -0,0 +1,583 @@
+/*
+ * aes_gcm_ossl.c
+ *
+ * AES Galois Counter Mode
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 <openssl/evp.h>
+#include "aes_gcm.h"
+#include "alloc.h"
+#include "err.h" /* for srtp_debug */
+#include "crypto_types.h"
+#include "cipher_types.h"
+
+srtp_debug_module_t srtp_mod_aes_gcm = {
+    0,        /* debugging is off by default */
+    "aes gcm" /* printable module name       */
+};
+
+/*
+ * For now we only support 8 and 16 octet tags.  The spec allows for
+ * optional 12 byte tag, which may be supported in the future.
+ */
+#define GCM_AUTH_TAG_LEN 16
+#define GCM_AUTH_TAG_LEN_8 8
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 28 or 44 for
+ * AES-128-GCM or AES-256-GCM respectively.  Note that the
+ * key length includes the 14 byte salt value that is used when
+ * initializing the KDF.
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_alloc(srtp_cipher_t **c,
+                                                    int key_len,
+                                                    int tlen)
+{
+    srtp_aes_gcm_ctx_t *gcm;
+
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d",
+                key_len);
+    debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
+
+    /*
+     * Verify the key_len is valid for one of: AES-128/256
+     */
+    if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
+        return (srtp_err_status_bad_param);
+    }
+
+    if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
+        return (srtp_err_status_bad_param);
+    }
+
+    /* allocate memory a cipher of type aes_gcm */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
+    if (gcm == NULL) {
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return (srtp_err_status_alloc_fail);
+    }
+
+    gcm->ctx = EVP_CIPHER_CTX_new();
+    if (gcm->ctx == NULL) {
+        srtp_crypto_free(gcm);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    /* set pointers */
+    (*c)->state = gcm;
+
+    /* setup cipher attributes */
+    switch (key_len) {
+    case SRTP_AES_GCM_128_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_128;
+        (*c)->algorithm = SRTP_AES_GCM_128;
+        gcm->key_size = SRTP_AES_128_KEY_LEN;
+        gcm->tag_len = tlen;
+        break;
+    case SRTP_AES_GCM_256_KEY_LEN_WSALT:
+        (*c)->type = &srtp_aes_gcm_256;
+        (*c)->algorithm = SRTP_AES_GCM_256;
+        gcm->key_size = SRTP_AES_256_KEY_LEN;
+        gcm->tag_len = tlen;
+        break;
+    }
+
+    /* set key size        */
+    (*c)->key_len = key_len;
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function deallocates a GCM session
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_gcm_ctx_t *ctx;
+
+    ctx = (srtp_aes_gcm_ctx_t *)c->state;
+    if (ctx) {
+        EVP_CIPHER_CTX_free(ctx->ctx);
+        /* zeroize the key material */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv,
+                                                           const uint8_t *key)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    const EVP_CIPHER *evp;
+
+    c->dir = srtp_direction_any;
+
+    debug_print(srtp_mod_aes_gcm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+
+    switch (c->key_size) {
+    case SRTP_AES_256_KEY_LEN:
+        evp = EVP_aes_256_gcm();
+        break;
+    case SRTP_AES_128_KEY_LEN:
+        evp = EVP_aes_128_gcm();
+        break;
+    default:
+        return (srtp_err_status_bad_param);
+        break;
+    }
+
+    EVP_CIPHER_CTX_cleanup(c->ctx);
+    if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) {
+        return (srtp_err_status_init_fail);
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_set_iv(
+    void *cv,
+    uint8_t *iv,
+    srtp_cipher_direction_t direction)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+
+    if (direction != srtp_direction_encrypt &&
+        direction != srtp_direction_decrypt) {
+        return (srtp_err_status_bad_param);
+    }
+    c->dir = direction;
+
+    debug_print(srtp_mod_aes_gcm, "setting iv: %s",
+                srtp_octet_string_hex_string(iv, 12));
+
+    if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) {
+        return (srtp_err_status_init_fail);
+    }
+
+    if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL, iv,
+                           (c->dir == srtp_direction_encrypt ? 1 : 0))) {
+        return (srtp_err_status_init_fail);
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function processes the AAD
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	aad	Additional data to process for AEAD cipher suites
+ *	aad_len	length of aad buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_set_aad(void *cv,
+                                                      const uint8_t *aad,
+                                                      uint32_t aad_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    int rv;
+
+    debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
+                srtp_octet_string_hex_string(aad, aad_len));
+
+    /*
+     * Set dummy tag, OpenSSL requires the Tag to be set before
+     * processing AAD
+     */
+
+    /*
+     * OpenSSL never write to address pointed by the last parameter of
+     * EVP_CIPHER_CTX_ctrl while EVP_CTRL_GCM_SET_TAG (in reality,
+     * OpenSSL copy its content to the context), so we can make
+     * aad read-only in this function and all its wrappers.
+     */
+    unsigned char dummy_tag[GCM_AUTH_TAG_LEN];
+    memset(dummy_tag, 0x0, GCM_AUTH_TAG_LEN);
+    EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, &dummy_tag);
+
+    rv = EVP_Cipher(c->ctx, NULL, aad, aad_len);
+    if (rv != aad_len) {
+        return (srtp_err_status_algo_fail);
+    } else {
+        return (srtp_err_status_ok);
+    }
+}
+
+/*
+ * This function encrypts a buffer using AES GCM mode
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_encrypt(void *cv,
+                                                      unsigned char *buf,
+                                                      unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
+        return (srtp_err_status_bad_param);
+    }
+
+    /*
+     * Encrypt the data
+     */
+    EVP_Cipher(c->ctx, buf, buf, *enc_len);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function calculates and returns the GCM tag for a given context.
+ * This should be called after encrypting the data.  The *len value
+ * is increased by the tag size.  The caller must ensure that *buf has
+ * enough room to accept the appended tag.
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_get_tag(void *cv,
+                                                      uint8_t *buf,
+                                                      uint32_t *len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    /*
+     * Calculate the tag
+     */
+    EVP_Cipher(c->ctx, NULL, NULL, 0);
+
+    /*
+     * Retreive the tag
+     */
+    EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf);
+
+    /*
+     * Increase encryption length by desired tag size
+     */
+    *len = c->tag_len;
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * This function decrypts a buffer using AES GCM mode
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv,
+                                                      unsigned char *buf,
+                                                      unsigned int *enc_len)
+{
+    srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
+    if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) {
+        return (srtp_err_status_bad_param);
+    }
+
+    /*
+     * Set the tag before decrypting
+     */
+    EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len,
+                        buf + (*enc_len - c->tag_len));
+    EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len);
+
+    /*
+     * Check the tag
+     */
+    if (EVP_Cipher(c->ctx, NULL, NULL, 0)) {
+        return (srtp_err_status_auth_fail);
+    }
+
+    /*
+     * Reduce the buffer size by the tag length since the tag
+     * is not part of the original payload
+     */
+    *enc_len -= c->tag_len;
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_gcm_128_openssl_description[] =
+    "AES-128 GCM using openssl";
+static const char srtp_aes_gcm_256_openssl_description[] =
+    "AES-256 GCM using openssl";
+
+/*
+ * KAT values for AES self-test.  These
+ * values we're derived from independent test code
+ * using OpenSSL.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_key[SRTP_AES_GCM_128_KEY_LEN_WSALT] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x09, 0x0a, 0x0b, 0x0c,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] =  {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_aad[20] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+    0x3d, 0x58, 0xe0, 0x91,
+    /* the last 16 bytes are the tag */
+    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
+    SRTP_AES_GCM_128_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_0_key,        /* key                      */
+    srtp_aes_gcm_test_case_0_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_0_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_0_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_0a           /* pointer to next testcase */
+};
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_key[SRTP_AES_GCM_256_KEY_LEN_WSALT] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
+    0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x09, 0x0a, 0x0b, 0x0c,
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] =  {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_aad[20] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
+    0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
+    0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
+    0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
+    0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
+    0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
+    0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
+    0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
+    0x09, 0xc9, 0x86, 0xc1,
+    /* the last 16 bytes are the tag */
+    0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
+    0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    68,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN_8,                  /* */
+    NULL                                 /* pointer to next testcase */
+};
+
+static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
+    SRTP_AES_GCM_256_KEY_LEN_WSALT,      /* octets in key            */
+    srtp_aes_gcm_test_case_1_key,        /* key                      */
+    srtp_aes_gcm_test_case_1_iv,         /* packet index             */
+    60,                                  /* octets in plaintext      */
+    srtp_aes_gcm_test_case_1_plaintext,  /* plaintext                */
+    76,                                  /* octets in ciphertext     */
+    srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext  + tag        */
+    20,                                  /* octets in AAD            */
+    srtp_aes_gcm_test_case_1_aad,        /* AAD                      */
+    GCM_AUTH_TAG_LEN,                    /* */
+    &srtp_aes_gcm_test_case_1a           /* pointer to next testcase */
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+const srtp_cipher_type_t srtp_aes_gcm_128 = {
+    srtp_aes_gcm_openssl_alloc,
+    srtp_aes_gcm_openssl_dealloc,
+    srtp_aes_gcm_openssl_context_init,
+    srtp_aes_gcm_openssl_set_aad,
+    srtp_aes_gcm_openssl_encrypt,
+    srtp_aes_gcm_openssl_decrypt,
+    srtp_aes_gcm_openssl_set_iv,
+    srtp_aes_gcm_openssl_get_tag,
+    srtp_aes_gcm_128_openssl_description,
+    &srtp_aes_gcm_test_case_0,
+    SRTP_AES_GCM_128
+};
+
+/*
+ * This is the vector function table for this crypto engine.
+ */
+const srtp_cipher_type_t srtp_aes_gcm_256 = {
+    srtp_aes_gcm_openssl_alloc,
+    srtp_aes_gcm_openssl_dealloc,
+    srtp_aes_gcm_openssl_context_init,
+    srtp_aes_gcm_openssl_set_aad,
+    srtp_aes_gcm_openssl_encrypt,
+    srtp_aes_gcm_openssl_decrypt,
+    srtp_aes_gcm_openssl_set_iv,
+    srtp_aes_gcm_openssl_get_tag,
+    srtp_aes_gcm_256_openssl_description,
+    &srtp_aes_gcm_test_case_1,
+    SRTP_AES_GCM_256
+};
diff --git a/crypto/cipher/aes_icm.c b/crypto/cipher/aes_icm.c
index 3cdef40..7551c75 100644
--- a/crypto/cipher/aes_icm.c
+++ b/crypto/cipher/aes_icm.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,15 +43,19 @@
  *
  */
 
+#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       */
 };
 
 /*
@@ -59,7 +63,7 @@
  *
  * 16 bits
  * <----->
- * +------+------+------+------+------+------+------+------+ 
+ * +------+------+------+------+------+------+------+------+
  * |           nonce           |    pakcet index    |  ctr |---+
  * +------+------+------+------+------+------+------+------+   |
  *                                                             |
@@ -70,16 +74,16 @@
  *                                                        +---------+
  *							  | 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
@@ -88,148 +92,138 @@
  *
  */
 
-err_status_t
-aes_icm_alloc(cipher_t **c, int key_len) {
-  extern cipher_type_t aes_icm;
-  uint8_t *pointer;
-  int tmp;
+static srtp_err_status_t srtp_aes_icm_alloc(srtp_cipher_t **c,
+                                            int key_len,
+                                            int tlen)
+{
+    srtp_aes_icm_ctx_t *icm;
 
-  debug_print(mod_aes_icm, 
-	      "allocating cipher with key length %d", key_len);
+    debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
+                key_len);
 
-#if GENERIC_AESICM
-  // 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 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.
-#else
-  if (key_len != 30)
-    return err_status_bad_param;
-#endif
-  /* allocate memory a cipher of type aes_icm */
-  tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
-  pointer = crypto_alloc(tmp);
-  if (pointer == NULL) 
-    return err_status_alloc_fail;
+    /*
+     * 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;
+    }
 
-  /* set pointers */
-  *c = (cipher_t *)pointer;
-  (*c)->type = &aes_icm;
-  (*c)->state = pointer + sizeof(cipher_t);
+    /* 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;
+    }
 
-  /* increment ref_count */
-  aes_icm.ref_count++;
+    icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
+    if (icm == NULL) {
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
 
-  /* set key size        */
-  (*c)->key_len = key_len;
+    /* set pointers */
+    (*c)->state = icm;
 
-  return err_status_ok;  
+    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 key size        */
+    icm->key_size = key_len;
+    (*c)->key_len = key_len;
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-aes_icm_dealloc(cipher_t *c) {
-  extern cipher_type_t aes_icm;
+static srtp_err_status_t srtp_aes_icm_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_icm_ctx_t *ctx;
 
-  /* zeroize entire state*/
-  octet_string_set_to_zero((octet_t *)c, 
-			   sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
+    if (c == NULL) {
+        return srtp_err_status_bad_param;
+    }
 
-  /* 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 octet_t *key) {
-  v128_t tmp_key;
+static srtp_err_status_t srtp_aes_icm_context_init(void *cv, const uint8_t *key)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    srtp_err_status_t status;
+    int base_key_len, copy_len;
 
-  /* set counter and initial values to 'offset' value */
-  /* FIX!!! this assumes the salt is at key + 16, and thus that the */
-  /* FIX!!! cipher key length is 16!  Also note this copies past the
-            end of the 'key' array by 2 bytes! */
-  v128_copy_octet_string(&c->counter, key + 16);
-  v128_copy_octet_string(&c->offset, key + 16);
+    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;
+    }
 
-  /* force last two octets of the offset to zero (for srtp compatibility) */
-  c->offset.octet[14] = c->offset.octet[15] = 0;
-  c->counter.octet[14] = c->counter.octet[15] = 0;
-  
-  /* set tmp_key (for alignment) */
-  v128_copy_octet_string(&tmp_key, key);
+    /*
+     * 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);
 
-  debug_print(mod_aes_icm, 
-	      "key:  %s", v128_hex_string(&tmp_key)); 
-  debug_print(mod_aes_icm, 
-	      "offset: %s", v128_hex_string(&c->offset)); 
+    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;
+    }
 
-  /* expand key */
-  aes_expand_encryption_key(tmp_key, c->expanded_key);
+    memcpy(&c->counter, key + base_key_len, copy_len);
+    memcpy(&c->offset, key + base_key_len, copy_len);
 
-  /* indicate that the keystream_buffer is empty */
-  c->bytes_in_buffer = 0;
+    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));
 
-  return err_status_ok;
-}
+    /* 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;
+    }
 
-/*
- * 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) {
-
-  int tail_num       = octet_num % 16;
-  uint64_t block_num = octet_num / 16;
-  
-
-  /* set counter value */
-  c->counter.v64[0] = c->offset.v64[0];
-  c->counter.v64[0] = c->offset.v64[0] ^ block_num;
-
-  debug_print(mod_aes_icm, 
-	      "set_octet: %s", v128_hex_string(&c->counter)); 
-
-  /* fill keystream buffer, if needed */
-  if (tail_num) {
-    v128_copy(&c->keystream_buffer, &c->counter);
-    aes_encrypt(&c->keystream_buffer, c->expanded_key);
-    c->bytes_in_buffer = 16;
-
-    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 = 16 - 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;
 }
 
 /*
@@ -237,60 +231,51 @@
  * the offset
  */
 
-err_status_t
-aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
-  v128_t *nonce = 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;
 
-  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)); 
+    /* set nonce (for alignment) */
+    v128_copy_octet_string(&nonce, iv);
 
-  /* indicate that the keystream_buffer is empty */
-  c->bytes_in_buffer = 0;
+    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
 
-  return err_status_ok;
+    v128_xor(&c->counter, &c->offset, &nonce);
+
+    debug_print(srtp_mod_aes_icm, "set_counter: %s",
+                v128_hex_string(&c->counter));
+
+    /* indicate that the keystream_buffer is empty */
+    c->bytes_in_buffer = 0;
+
+    return srtp_err_status_ok;
 }
 
-
-
 /*
  * 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
  */
-  
-inline void
-aes_icm_advance(aes_icm_ctx_t *c) {
+static void srtp_aes_icm_advance(srtp_aes_icm_ctx_t *c)
+{
+    /* fill buffer with new keystream */
+    v128_copy(&c->keystream_buffer, &c->counter);
+    srtp_aes_encrypt(&c->keystream_buffer, &c->expanded_key);
+    c->bytes_in_buffer = sizeof(v128_t);
 
-#if GENERIC_AESICM  
-  uint32_t temp;
-#endif
- 
-  /* fill buffer with new keystream */
-  v128_copy(&c->keystream_buffer, &c->counter);
-  aes_encrypt(&c->keystream_buffer, c->expanded_key);
-  c->bytes_in_buffer = 16;
+    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));
 
-  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 */
-  
-#if GENERIC_AESICM  
-  //alex's clock counter forward
-  temp = ntohl(c->counter.v32[3]);
-  c->counter.v32[3] = htonl(++temp);
-#else
-  if (!++(c->counter.octet[15])) 
-    ++(c->counter.octet[14]);
-#endif
+    /* clock counter forward */
+    if (!++(c->counter.v8[15])) {
+        ++(c->counter.v8[14]);
+    }
 }
 
 /*
@@ -303,182 +288,243 @@
  *  - 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(aes_icm_ctx_t *c,
-		unsigned char *buf, unsigned int *enc_len) {
-  unsigned int bytes_to_encr = *enc_len;
-  int i;
-  uint32_t *b;
+static srtp_err_status_t srtp_aes_icm_encrypt(void *cv,
+                                              unsigned char *buf,
+                                              unsigned int *enc_len)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    unsigned int bytes_to_encr = *enc_len;
+    unsigned int i;
+    uint32_t *b;
 
-  /* check that there's enough segment left */
-  if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
-    return err_status_terminus;
+    /* check that there's enough segment left*/
+    if ((bytes_to_encr + htons(c->counter.v16[7])) > 0xffff) {
+        return srtp_err_status_terminus;
+    }
 
- debug_print(mod_aes_icm, "block index: %d", 
-	     htons(c->counter.v16[7]));
-  
-  if (bytes_to_encr <= c->bytes_in_buffer) {
-    
-    /* deal with odd case of small bytes_to_encr */
-    for (i = (16 - c->bytes_in_buffer);
-	 i < (16 - c->bytes_in_buffer + bytes_to_encr); i++) 
-      *buf++ ^= c->keystream_buffer.octet[i];
+    debug_print(srtp_mod_aes_icm, "block index: %d", htons(c->counter.v16[7]));
+    if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
+        /* 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;
+        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=(16 - c->bytes_in_buffer); i < 16; i++) 
-      *buf++ ^= c->keystream_buffer.octet[i];
+    } 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;
+        bytes_to_encr -= c->bytes_in_buffer;
+        c->bytes_in_buffer = 0;
+    }
 
-  }
-  
-  /* now loop over entire 16-byte blocks of keystream */
-  for (i=0; i < (bytes_to_encr/16); i++) {
+    /* 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);
 
-    /* fill buffer with new keystream */
-    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 = (octet_t *)b;
-#else    
-    if ((((uint32_t) buf) & 0x03) != 0) {
-      *buf++ ^= c->keystream_buffer.octet[0];
-      *buf++ ^= c->keystream_buffer.octet[1];
-      *buf++ ^= c->keystream_buffer.octet[2];
-      *buf++ ^= c->keystream_buffer.octet[3];
-      *buf++ ^= c->keystream_buffer.octet[4];
-      *buf++ ^= c->keystream_buffer.octet[5];
-      *buf++ ^= c->keystream_buffer.octet[6];
-      *buf++ ^= c->keystream_buffer.octet[7];
-      *buf++ ^= c->keystream_buffer.octet[8];
-      *buf++ ^= c->keystream_buffer.octet[9];
-      *buf++ ^= c->keystream_buffer.octet[10];
-      *buf++ ^= c->keystream_buffer.octet[11];
-      *buf++ ^= c->keystream_buffer.octet[12];
-      *buf++ ^= c->keystream_buffer.octet[13];
-      *buf++ ^= c->keystream_buffer.octet[14];
-      *buf++ ^= c->keystream_buffer.octet[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 = (octet_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 */
+    }
 
-  }
-  
-  /* 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(c);
-    
-    for (i=0; i < (bytes_to_encr & 0xf); i++)
-      *buf++ ^= c->keystream_buffer.octet[i];
-    
-    /* reset the keystream buffer size to right value */
-    c->bytes_in_buffer = 16 - 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];
+        }
 
-  }
+        /* reset the keystream buffer size to right value */
+        c->bytes_in_buffer = sizeof(v128_t) - i;
+    } else {
+        /* no tail, so just reset the keystream buffer size to zero */
+        c->bytes_in_buffer = 0;
+    }
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-aes_icm_output(aes_icm_ctx_t *c, octet_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);
-}
+static const char srtp_aes_icm_128_description[] =
+    "AES-128 integer counter mode";
+static const char srtp_aes_icm_256_description[] =
+    "AES-256 integer counter mode";
 
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
+    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+    0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+/* clang-format on */
 
-char 
-aes_icm_description[] = "aes integer counter mode";
+/* 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 */
 
-octet_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_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
+    0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+    0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+    0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+    0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
+    SRTP_AES_ICM_128_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_128_test_case_0_key,        /* key                      */
+    srtp_aes_icm_128_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_128_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
 };
 
-octet_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 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 */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
+    0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+    0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+    0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+    0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
+    SRTP_AES_ICM_256_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_256_test_case_0_key,        /* key                      */
+    srtp_aes_icm_256_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_256_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL,                                    /* pointer to next testcase */
 };
 
-octet_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, 
-};
-
-octet_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
-};
-
-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 */
-};
-
- 
 /*
  * 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_0,
-  (debug_module_t *)            &mod_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               /* */
+};
diff --git a/crypto/cipher/aes_icm_nss.c b/crypto/cipher/aes_icm_nss.c
new file mode 100644
index 0000000..d161b8f
--- /dev/null
+++ b/crypto/cipher/aes_icm_nss.c
@@ -0,0 +1,562 @@
+/*
+ * aes_icm_nss.c
+ *
+ * AES Integer Counter Mode
+ *
+ * Richard L. Barnes
+ * Cisco Systems, Inc.
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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_icm_ext.h"
+#include "crypto_types.h"
+#include "err.h" /* for srtp_debug */
+#include "alloc.h"
+#include "cipher_types.h"
+
+srtp_debug_module_t srtp_mod_aes_icm = {
+    0,            /* debugging is off by default */
+    "aes icm nss" /* printable module name       */
+};
+
+/*
+ * integer counter mode works as follows:
+ *
+ * 16 bits
+ * <----->
+ * +------+------+------+------+------+------+------+------+
+ * |           nonce           |    packet index    |  ctr |---+
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   v
+ * |                      salt                      |000000|->(+)
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ *                                                        +---------+
+ *                                                        | encrypt |
+ *                                                        +---------+
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   |
+ * |                    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)
+ *
+ */
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 30, 38, or 46 for
+ * AES-128, AES-192, and AES-256 respectively.  Note, this key_len
+ * value is inflated, as it also accounts for the 112 bit salt
+ * value.  The tlen argument is for the AEAD tag length, which
+ * isn't used in counter mode.
+ */
+static srtp_err_status_t srtp_aes_icm_nss_alloc(srtp_cipher_t **c,
+                                                int key_len,
+                                                int tlen)
+{
+    srtp_aes_icm_ctx_t *icm;
+    NSSInitContext *nss;
+
+    debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
+                key_len);
+
+    /*
+     * Verify the key_len is valid for one of: AES-128/192/256
+     */
+    if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* Initialize NSS equiv of NSS_NoDB_Init(NULL) */
+    nss = NSS_InitContext("", "", "", "", NULL,
+                          NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
+                              NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
+                              NSS_INIT_OPTIMIZESPACE);
+    if (!nss) {
+        return (srtp_err_status_cipher_fail);
+    }
+
+    /* allocate memory a cipher of type aes_icm */
+    *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
+    if (*c == NULL) {
+        NSS_ShutdownContext(nss);
+        return srtp_err_status_alloc_fail;
+    }
+
+    icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
+    if (icm == NULL) {
+        NSS_ShutdownContext(nss);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    icm->key = NULL;
+    icm->ctx = NULL;
+    icm->nss = nss;
+
+    /* set pointers */
+    (*c)->state = icm;
+
+    /* setup cipher parameters */
+    switch (key_len) {
+    case SRTP_AES_ICM_128_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_128;
+        (*c)->type = &srtp_aes_icm_128;
+        icm->key_size = SRTP_AES_128_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_192_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_192;
+        (*c)->type = &srtp_aes_icm_192;
+        icm->key_size = SRTP_AES_192_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_256_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_256;
+        (*c)->type = &srtp_aes_icm_256;
+        icm->key_size = SRTP_AES_256_KEY_LEN;
+        break;
+    }
+
+    /* set key size        */
+    (*c)->key_len = key_len;
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * This function deallocates an instance of this engine
+ */
+static srtp_err_status_t srtp_aes_icm_nss_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_icm_ctx_t *ctx;
+
+    ctx = (srtp_aes_icm_ctx_t *)c->state;
+    if (ctx) {
+        /* free any PK11 values that have been created */
+        if (ctx->key) {
+            PK11_FreeSymKey(ctx->key);
+            ctx->key = NULL;
+        }
+
+        if (ctx->ctx) {
+            PK11_DestroyContext(ctx->ctx, PR_TRUE);
+            ctx->ctx = NULL;
+        }
+
+        if (ctx->nss) {
+            NSS_ShutdownContext(ctx->nss);
+            ctx->nss = NULL;
+        }
+
+        /* zeroize everything */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_icm_nss_context_init(...) initializes the aes_icm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ *
+ * the salt is unpredictable (but not necessarily secret) data which
+ * randomizes the starting point in the keystream
+ */
+static srtp_err_status_t srtp_aes_icm_nss_context_init(void *cv,
+                                                       const uint8_t *key)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+
+    /*
+     * set counter and initial values to 'offset' value, being careful not to
+     * go past the end of the key buffer
+     */
+    v128_set_to_zero(&c->counter);
+    v128_set_to_zero(&c->offset);
+    memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
+    memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
+
+    /* force last two octets of the offset to zero (for srtp compatibility) */
+    c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
+    c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
+
+    debug_print(srtp_mod_aes_icm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+    debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
+
+    if (c->key) {
+        PK11_FreeSymKey(c->key);
+        c->key = NULL;
+    }
+
+    PK11SlotInfo *slot = PK11_GetBestSlot(CKM_AES_CTR, NULL);
+    if (!slot) {
+        return srtp_err_status_bad_param;
+    }
+
+    SECItem keyItem = { siBuffer, (unsigned char *)key, c->key_size };
+    c->key = PK11_ImportSymKey(slot, CKM_AES_CTR, PK11_OriginUnwrap,
+                               CKA_ENCRYPT, &keyItem, NULL);
+    PK11_FreeSlot(slot);
+
+    if (!c->key) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    return (srtp_err_status_ok);
+}
+
+/*
+ * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
+ * the offset
+ */
+static srtp_err_status_t srtp_aes_icm_nss_set_iv(void *cv,
+                                                 uint8_t *iv,
+                                                 srtp_cipher_direction_t dir)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    v128_t nonce;
+
+    /* set nonce (for alignment) */
+    v128_copy_octet_string(&nonce, iv);
+
+    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
+
+    v128_xor(&c->counter, &c->offset, &nonce);
+
+    debug_print(srtp_mod_aes_icm, "set_counter: %s",
+                v128_hex_string(&c->counter));
+
+    /* set up the PK11 context now that we have all the info */
+    CK_AES_CTR_PARAMS param;
+    param.ulCounterBits = 16;
+    memcpy(param.cb, &c->counter, 16);
+
+    if (!c->key) {
+        return srtp_err_status_bad_param;
+    }
+
+    if (c->ctx) {
+        PK11_DestroyContext(c->ctx, PR_TRUE);
+    }
+
+    SECItem paramItem = { siBuffer, (unsigned char *)&param,
+                          sizeof(CK_AES_CTR_PARAMS) };
+    c->ctx = PK11_CreateContextBySymKey(CKM_AES_CTR, CKA_ENCRYPT, c->key,
+                                        &paramItem);
+    if (!c->ctx) {
+        return srtp_err_status_cipher_fail;
+    }
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * This function encrypts a buffer using AES CTR mode
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_icm_nss_encrypt(void *cv,
+                                                  unsigned char *buf,
+                                                  unsigned int *enc_len)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+
+    if (!c->ctx) {
+        return srtp_err_status_bad_param;
+    }
+
+    int rv =
+        PK11_CipherOp(c->ctx, buf, (int *)enc_len, *enc_len, buf, *enc_len);
+
+    srtp_err_status_t status = (srtp_err_status_ok);
+    if (rv != SECSuccess) {
+        status = (srtp_err_status_cipher_fail);
+    }
+
+    return status;
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_icm_128_nss_description[] =
+    "AES-128 counter mode using NSS";
+static const char srtp_aes_icm_192_nss_description[] =
+    "AES-192 counter mode using NSS";
+static const char srtp_aes_icm_256_nss_description[] =
+    "AES-256 counter mode using NSS";
+
+/*
+ * KAT values for AES self-test.  These
+ * values came from the legacy libsrtp code.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
+    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+    0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
+    0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+    0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+    0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+    0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
+    SRTP_AES_ICM_128_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_128_test_case_0_key,        /* key                      */
+    srtp_aes_icm_128_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_128_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-192-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_WSALT] = {
+    0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
+    0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
+    0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_192_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_ciphertext[32] = {
+    0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d,
+    0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
+    0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
+    0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
+    SRTP_AES_ICM_192_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_192_test_case_0_key,        /* key                      */
+    srtp_aes_icm_192_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_192_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-256-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
+    0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
+    0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
+    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 */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
+    0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+    0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+    0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+    0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
+    SRTP_AES_ICM_256_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_256_test_case_0_key,        /* key                      */
+    srtp_aes_icm_256_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_256_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_128 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_128_nss_description, /* */
+    &srtp_aes_icm_128_test_case_0,    /* */
+    SRTP_AES_ICM_128                  /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_192 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_192_nss_description, /* */
+    &srtp_aes_icm_192_test_case_0,    /* */
+    SRTP_AES_ICM_192                  /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_256 = {
+    srtp_aes_icm_nss_alloc,           /* */
+    srtp_aes_icm_nss_dealloc,         /* */
+    srtp_aes_icm_nss_context_init,    /* */
+    0,                                /* set_aad */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_encrypt,         /* */
+    srtp_aes_icm_nss_set_iv,          /* */
+    0,                                /* get_tag */
+    srtp_aes_icm_256_nss_description, /* */
+    &srtp_aes_icm_256_test_case_0,    /* */
+    SRTP_AES_ICM_256                  /* */
+};
diff --git a/crypto/cipher/aes_icm_ossl.c b/crypto/cipher/aes_icm_ossl.c
new file mode 100644
index 0000000..c2b729a
--- /dev/null
+++ b/crypto/cipher/aes_icm_ossl.c
@@ -0,0 +1,541 @@
+/*
+ * aes_icm_ossl.c
+ *
+ * AES Integer Counter Mode
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ * 2/24/2012:  This module was modified to use CiscoSSL for AES counter
+ *             mode.  Eddy Lem contributed the code to allow this.
+ *
+ * 12/20/2012: Added support for AES-192 and AES-256.
+ */
+
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 <openssl/evp.h>
+#include "aes_icm_ext.h"
+#include "crypto_types.h"
+#include "err.h" /* for srtp_debug */
+#include "alloc.h"
+#include "cipher_types.h"
+
+srtp_debug_module_t srtp_mod_aes_icm = {
+    0,             /* debugging is off by default */
+    "aes icm ossl" /* printable module name       */
+};
+
+/*
+ * integer counter mode works as follows:
+ *
+ * 16 bits
+ * <----->
+ * +------+------+------+------+------+------+------+------+
+ * |           nonce           |    packet index    |  ctr |---+
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   v
+ * |                      salt                      |000000|->(+)
+ * +------+------+------+------+------+------+------+------+   |
+ *                                                             |
+ *                                                        +---------+
+ *                                                        | encrypt |
+ *                                                        +---------+
+ *                                                             |
+ * +------+------+------+------+------+------+------+------+   |
+ * |                    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)
+ *
+ */
+
+/*
+ * This function allocates a new instance of this crypto engine.
+ * The key_len parameter should be one of 30, 38, or 46 for
+ * AES-128, AES-192, and AES-256 respectively.  Note, this key_len
+ * value is inflated, as it also accounts for the 112 bit salt
+ * value.  The tlen argument is for the AEAD tag length, which
+ * isn't used in counter mode.
+ */
+static srtp_err_status_t srtp_aes_icm_openssl_alloc(srtp_cipher_t **c,
+                                                    int key_len,
+                                                    int tlen)
+{
+    srtp_aes_icm_ctx_t *icm;
+
+    debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
+                key_len);
+
+    /*
+     * Verify the key_len is valid for one of: AES-128/192/256
+     */
+    if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
+        key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
+        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;
+    }
+
+    icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
+    if (icm == NULL) {
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    icm->ctx = EVP_CIPHER_CTX_new();
+    if (icm->ctx == NULL) {
+        srtp_crypto_free(icm);
+        srtp_crypto_free(*c);
+        *c = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+
+    /* set pointers */
+    (*c)->state = icm;
+
+    /* setup cipher parameters */
+    switch (key_len) {
+    case SRTP_AES_ICM_128_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_128;
+        (*c)->type = &srtp_aes_icm_128;
+        icm->key_size = SRTP_AES_128_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_192_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_192;
+        (*c)->type = &srtp_aes_icm_192;
+        icm->key_size = SRTP_AES_192_KEY_LEN;
+        break;
+    case SRTP_AES_ICM_256_KEY_LEN_WSALT:
+        (*c)->algorithm = SRTP_AES_ICM_256;
+        (*c)->type = &srtp_aes_icm_256;
+        icm->key_size = SRTP_AES_256_KEY_LEN;
+        break;
+    }
+
+    /* set key size        */
+    (*c)->key_len = key_len;
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * This function deallocates an instance of this engine
+ */
+static srtp_err_status_t srtp_aes_icm_openssl_dealloc(srtp_cipher_t *c)
+{
+    srtp_aes_icm_ctx_t *ctx;
+
+    if (c == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    /*
+     * Free the EVP context
+     */
+    ctx = (srtp_aes_icm_ctx_t *)c->state;
+    if (ctx != NULL) {
+        EVP_CIPHER_CTX_free(ctx->ctx);
+        /* zeroize the key material */
+        octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
+        srtp_crypto_free(ctx);
+    }
+
+    /* free memory */
+    srtp_crypto_free(c);
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * aes_icm_openssl_context_init(...) initializes the aes_icm_context
+ * using the value in key[].
+ *
+ * the key is the secret key
+ *
+ * the salt is unpredictable (but not necessarily secret) data which
+ * randomizes the starting point in the keystream
+ */
+static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv,
+                                                           const uint8_t *key)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    const EVP_CIPHER *evp;
+
+    /*
+     * set counter and initial values to 'offset' value, being careful not to
+     * go past the end of the key buffer
+     */
+    v128_set_to_zero(&c->counter);
+    v128_set_to_zero(&c->offset);
+    memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
+    memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
+
+    /* force last two octets of the offset to zero (for srtp compatibility) */
+    c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
+    c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
+
+    debug_print(srtp_mod_aes_icm, "key:  %s",
+                srtp_octet_string_hex_string(key, c->key_size));
+    debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
+
+    switch (c->key_size) {
+    case SRTP_AES_256_KEY_LEN:
+        evp = EVP_aes_256_ctr();
+        break;
+    case SRTP_AES_192_KEY_LEN:
+        evp = EVP_aes_192_ctr();
+        break;
+    case SRTP_AES_128_KEY_LEN:
+        evp = EVP_aes_128_ctr();
+        break;
+    default:
+        return srtp_err_status_bad_param;
+        break;
+    }
+
+    EVP_CIPHER_CTX_cleanup(c->ctx);
+    if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) {
+        return srtp_err_status_fail;
+    } else {
+        return srtp_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
+ */
+static srtp_err_status_t srtp_aes_icm_openssl_set_iv(
+    void *cv,
+    uint8_t *iv,
+    srtp_cipher_direction_t dir)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    v128_t nonce;
+
+    /* set nonce (for alignment) */
+    v128_copy_octet_string(&nonce, iv);
+
+    debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
+
+    v128_xor(&c->counter, &c->offset, &nonce);
+
+    debug_print(srtp_mod_aes_icm, "set_counter: %s",
+                v128_hex_string(&c->counter));
+
+    if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) {
+        return srtp_err_status_fail;
+    } else {
+        return srtp_err_status_ok;
+    }
+}
+
+/*
+ * This function encrypts a buffer using AES CTR mode
+ *
+ * Parameters:
+ *	c	Crypto context
+ *	buf	data to encrypt
+ *	enc_len	length of encrypt buffer
+ */
+static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv,
+                                                      unsigned char *buf,
+                                                      unsigned int *enc_len)
+{
+    srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
+    int len = 0;
+
+    debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
+
+    if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
+        return srtp_err_status_cipher_fail;
+    }
+    *enc_len = len;
+
+    if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
+        return srtp_err_status_cipher_fail;
+    }
+    *enc_len += len;
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * Name of this crypto engine
+ */
+static const char srtp_aes_icm_128_openssl_description[] =
+    "AES-128 counter mode using openssl";
+static const char srtp_aes_icm_192_openssl_description[] =
+    "AES-192 counter mode using openssl";
+static const char srtp_aes_icm_256_openssl_description[] =
+    "AES-256 counter mode using openssl";
+
+/*
+ * KAT values for AES self-test.  These
+ * values came from the legacy libsrtp code.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
+    0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+    0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
+    0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
+    0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
+    0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
+    0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
+    SRTP_AES_ICM_128_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_128_test_case_0_key,        /* key                      */
+    srtp_aes_icm_128_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_128_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-192-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_WSALT] = {
+    0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
+    0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
+    0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
+};
+/* clang-format on */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_192_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_192_test_case_0_ciphertext[32] = {
+    0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d,
+    0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
+    0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
+    0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
+    SRTP_AES_ICM_192_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_192_test_case_0_key,        /* key                      */
+    srtp_aes_icm_192_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_192_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * KAT values for AES-256-CTR self-test.  These
+ * values came from section 7 of RFC 6188.
+ */
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
+    0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
+    0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
+    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 */
+
+/* clang-format off */
+static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] =  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
+    0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
+    0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
+    0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
+    0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
+};
+/* clang-format on */
+
+static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
+    SRTP_AES_ICM_256_KEY_LEN_WSALT,          /* octets in key            */
+    srtp_aes_icm_256_test_case_0_key,        /* key                      */
+    srtp_aes_icm_256_test_case_0_nonce,      /* packet index             */
+    32,                                      /* octets in plaintext      */
+    srtp_aes_icm_256_test_case_0_plaintext,  /* plaintext                */
+    32,                                      /* octets in ciphertext     */
+    srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext               */
+    0,                                       /* */
+    NULL,                                    /* */
+    0,                                       /* */
+    NULL                                     /* pointer to next testcase */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_128 = {
+    srtp_aes_icm_openssl_alloc,           /* */
+    srtp_aes_icm_openssl_dealloc,         /* */
+    srtp_aes_icm_openssl_context_init,    /* */
+    0,                                    /* set_aad */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_set_iv,          /* */
+    0,                                    /* get_tag */
+    srtp_aes_icm_128_openssl_description, /* */
+    &srtp_aes_icm_128_test_case_0,        /* */
+    SRTP_AES_ICM_128                      /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_192 = {
+    srtp_aes_icm_openssl_alloc,           /* */
+    srtp_aes_icm_openssl_dealloc,         /* */
+    srtp_aes_icm_openssl_context_init,    /* */
+    0,                                    /* set_aad */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_set_iv,          /* */
+    0,                                    /* get_tag */
+    srtp_aes_icm_192_openssl_description, /* */
+    &srtp_aes_icm_192_test_case_0,        /* */
+    SRTP_AES_ICM_192                      /* */
+};
+
+/*
+ * This is the function table for this crypto engine.
+ * note: the encrypt function is identical to the decrypt function
+ */
+const srtp_cipher_type_t srtp_aes_icm_256 = {
+    srtp_aes_icm_openssl_alloc,           /* */
+    srtp_aes_icm_openssl_dealloc,         /* */
+    srtp_aes_icm_openssl_context_init,    /* */
+    0,                                    /* set_aad */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_encrypt,         /* */
+    srtp_aes_icm_openssl_set_iv,          /* */
+    0,                                    /* get_tag */
+    srtp_aes_icm_256_openssl_description, /* */
+    &srtp_aes_icm_256_test_case_0,        /* */
+    SRTP_AES_ICM_256                      /* */
+};
diff --git a/crypto/cipher/cipher.c b/crypto/cipher/cipher.c
index f09a1fe..354517d 100644
--- a/crypto/cipher/cipher.c
+++ b/crypto/cipher/cipher.c
@@ -5,30 +5,30 @@
  *
  * David A. 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
@@ -44,360 +44,621 @@
  *
  */
 
-#include "cipher.h"
-#include "rand_source.h"        /* used in invertibiltiy tests        */
-#include "alloc.h"              /* for crypto_alloc(), crypto_free()  */
-#include <time.h>               /* for clock()                        */
+#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 "cipher_priv.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, octet_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_self_test(ct) tests a cipher of type ct against test cases
- * provided in an array of values of key, salt, xtd_seq_num_t,
- * plaintext, and ciphertext that is known to be good
+/*
+ * A trivial platform independent random source.
+ * For use in test only.
  */
+void srtp_cipher_rand_for_tests(void *dest, uint32_t len)
+{
+    /* Generic C-library (rand()) version */
+    /* This is a random source of last resort */
+    uint8_t *dst = (uint8_t *)dest;
+    while (len) {
+        int val = rand();
+        /* rand() returns 0-32767 (ugh) */
+        /* Is this a good enough way to get random bytes?
+           It is if it passes FIPS-140... */
+        *dst++ = val & 0xff;
+        len--;
+    }
+}
+
+/*
+ * A trivial platform independent 32 bit random number.
+ * For use in test only.
+ */
+uint32_t srtp_cipher_rand_u32_for_tests(void)
+{
+    uint32_t r;
+    srtp_cipher_rand_for_tests(&r, sizeof(r));
+    return r;
+}
 
 #define SELF_TEST_BUF_OCTETS 128
-#define NUM_RAND_TESTS       128
-#define MAX_KEY_LEN          64
+#define NUM_RAND_TESTS 128
+#define MAX_KEY_LEN 64
+/*
+ * srtp_cipher_type_test(ct, test_data) tests a cipher of type ct against
+ * test cases provided in a list test_data of values of key, salt, iv,
+ * plaintext, and ciphertext that is known to be good
+ */
+srtp_err_status_t srtp_cipher_type_test(
+    const srtp_cipher_type_t *ct,
+    const srtp_cipher_test_case_t *test_data)
+{
+    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;
 
-err_status_t
-cipher_type_self_test(const cipher_type_t *ct) {
-  const cipher_test_case_t *test_case = ct->test_data;
-  cipher_t *c;
-  err_status_t status;
-  octet_t buffer[SELF_TEST_BUF_OCTETS];
-  octet_t buffer2[SELF_TEST_BUF_OCTETS];
-  unsigned int len;
-  int i, j, case_num = 0;
+    debug_print(srtp_mod_cipher, "running self-test for cipher %s",
+                ct->description);
 
-  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;
-
-  /*
-   * 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;
+    if (test_case == NULL) {
+        return srtp_err_status_cant_check;
     }
 
-    /* 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 != 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;
-    }
-    
     /*
-     * 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;
+        }
 
-    /* re-initialize cipher for decryption */
-    status = cipher_init(c, test_case->key, direction_decrypt);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
+        /*
+         * test the encrypt function
+         */
+        debug_print(srtp_mod_cipher, "testing encryption", NULL);
+
+        /* 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;
+        }
+
+        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));
+        }
+
+        /* 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));
+
+        /* 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;
+        }
+
+        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));
+
+        /* 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));
+
+            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;
     }
 
-    /* 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];
+    /* now run some random invertibility tests */
 
-    debug_print(mod_cipher, "ciphertext:    %s",
-		octet_string_hex_string(buffer,
-					test_case->plaintext_length_octets));
-
-    /* set the initialization vector */
-    status = cipher_set_iv(c, test_case->idx);
+    /* 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;
-    } 
-    
-    /* 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 plaintext with that in the test case */
-    if (len != 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) {
-
-      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));
-
-      cipher_dealloc(c);
-      return err_status_algo_fail;
+        return status;
     }
 
-    /* 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;
-  }
+    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];
 
-  /* now run some random invertibility tests */
+        /* choose a length at random (leaving room for IV and padding) */
+        length = srtp_cipher_rand_u32_for_tests() % (SELF_TEST_BUF_OCTETS - 64);
+        debug_print(srtp_mod_cipher, "random plaintext length %d\n", length);
+        srtp_cipher_rand_for_tests(buffer, length);
 
-  /* allocate cipher, using paramaters from the first test case */
-  test_case = ct->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++) {
-    int length, plaintext_len;
-    octet_t key[MAX_KEY_LEN];
-    octet_t  iv[MAX_KEY_LEN];
+        debug_print(srtp_mod_cipher, "plaintext:    %s",
+                    srtp_octet_string_hex_string(buffer, length));
 
-    /* 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;
+        /* copy plaintext into second buffer */
+        for (i = 0; (unsigned int)i < length; i++) {
+            buffer2[i] = buffer[i];
+        }
 
-    debug_print(mod_cipher, "plaintext:    %s",
-		octet_string_hex_string(buffer, length));
+        /* choose a key at random */
+        if (test_case->key_length_octets > MAX_KEY_LEN) {
+            srtp_cipher_dealloc(c);
+            return srtp_err_status_cant_check;
+        }
+        srtp_cipher_rand_for_tests(key, test_case->key_length_octets);
 
-    /* copy plaintext into second buffer */
-    for (i=0; 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 */
+        srtp_cipher_rand_for_tests(iv, MAX_KEY_LEN);
 
-   /* 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);
-    if (status) {
-      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 = 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;
+        }
     }
 
-    /* set initialization vector */
-    status = cipher_set_iv(c, test_case->idx);
+    status = srtp_cipher_dealloc(c);
     if (status) {
-      cipher_dealloc(c);
-      return status;
-    } 
-
-    /* encrypt buffer with cipher */
-    plaintext_len = length;
-    status = cipher_encrypt(c, buffer, &length);
-    if (status) {
-      cipher_dealloc(c);
-      return status;
+        return status;
     }
-    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);
-    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));    
-
-    /* compare the resulting plaintext with the original one */
-    if (length != 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;
-    }
-        
-  }
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
+/*
+ * srtp_cipher_type_self_test(ct) performs srtp_cipher_type_test on ct's
+ * internal list of test data.
+ */
+srtp_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.0 is returned
+ * if an error is encountered, the value 0 is returned
  */
+uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
+                                     int octets_in_buffer,
+                                     int num_trials)
+{
+    int i;
+    v128_t nonce;
+    clock_t timer;
+    unsigned char *enc_buf;
+    unsigned int len = octets_in_buffer;
 
-double
-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;
+    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;
 
-  enc_buf = crypto_alloc(octets_in_buffer);
-  if (enc_buf == NULL)
-    return 0.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;
+    srtp_crypto_free(enc_buf);
 
-  crypto_free(enc_buf);
-  
-  return (double) 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;
 }
diff --git a/crypto/cipher/null_cipher.c b/crypto/cipher/null_cipher.c
index b008d12..659add0 100644
--- a/crypto/cipher/null_cipher.c
+++ b/crypto/cipher/null_cipher.c
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -44,109 +44,110 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "datatypes.h"
 #include "null_cipher.h"
+#include "err.h" /* for srtp_debug */
 #include "alloc.h"
+#include "cipher_types.h"
 
-/* the null_cipher uses the cipher debug module  */
+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;
 
-extern debug_module_t mod_cipher;
+    debug_print(srtp_mod_cipher, "allocating cipher with key length %d",
+                key_len);
 
-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);
+    /* 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;
+    }
 
-  /* allocate memory a cipher of type null_cipher */
-  pointer = crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
-  if (pointer == NULL)
-    return err_status_alloc_fail;
+    /* set pointers */
+    (*c)->algorithm = SRTP_NULL_CIPHER;
+    (*c)->type = &srtp_null_cipher;
+    (*c)->state = (void *)0x1; /* The null cipher does not maintain state */
 
-  /* set pointers */
-  *c = (cipher_t *)pointer;
-  (*c)->type = &null_cipher;
-  (*c)->state = pointer + sizeof(cipher_t);
+    /* 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;
+static srtp_err_status_t srtp_null_cipher_dealloc(srtp_cipher_t *c)
+{
+    extern const srtp_cipher_type_t srtp_null_cipher;
 
-  /* zeroize entire state*/
-  octet_string_set_to_zero((octet_t *)c, 
-			   sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
+    /* zeroize entire state*/
+    octet_string_set_to_zero(c, sizeof(srtp_cipher_t));
 
-  /* free memory of type null_cipher */
-  crypto_free(c);
+    /* free memory of type null_cipher */
+    srtp_crypto_free(c);
 
-  /* decrement reference count */
-  null_cipher.ref_count--;
-  
-  return err_status_ok;
-  
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_cipher_init(null_cipher_ctx_t *ctx, const octet_t *key) {
+static srtp_err_status_t srtp_null_cipher_init(void *cv, const uint8_t *key)
+{
+    /* srtp_null_cipher_ctx_t *c = (srtp_null_cipher_ctx_t *)cv; */
 
-  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
+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              /* */
 };
-
diff --git a/crypto/hash/auth.c b/crypto/hash/auth.c
index fb6b7b1..f19327d 100644
--- a/crypto/hash/auth.c
+++ b/crypto/hash/auth.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,131 +43,145 @@
  *
  */
 
+#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_self_test() tests an auth function of type ct against
- * test cases provided in an array of values of key, data, and tag
+ * 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_self_test(const auth_type_t *at) {
-  auth_test_case_t *test_case = at->test_data;
-  auth_t *a;
-  err_status_t status;
-  octet_t tag[SELF_TEST_TAG_BUF_OCTETS];
-  int i, case_num = 0;
+srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
+                                      const srtp_auth_test_case_t *test_data)
+{
+    const srtp_auth_test_case_t *test_case = test_data;
+    srtp_auth_t *a;
+    srtp_err_status_t status;
+    uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
+    int i, case_num = 0;
 
-  debug_print(mod_auth, "running self-test for auth function %s", 
-	      at->description);
-  
-  /*
-   * check to make sure that we have at least one test case, and
-   * return an error if we don't - we need to be paranoid here
-   */
-  if (test_case == NULL)
-    return err_status_cant_check;
+    debug_print(srtp_mod_auth, "running self-test for auth function %s",
+                at->description);
 
-  /* loop over all test cases */  
-  while (test_case != NULL) {
-
-    /* check test case parameters */
-    if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)
-      return err_status_bad_param;
-    
-    /* allocate auth */
-    status = auth_type_alloc(at, &a, test_case->key_length_octets,
-			     test_case->tag_length_octets);
-    if (status)
-      return status;
-    
-    /* initialize auth */
-    status = auth_init(a, test_case->key);
-    if (status) {
-      auth_dealloc(a);
-      return status;
+    /*
+     * check to make sure that we have at least one test case, and
+     * return an error if we don't - we need to be paranoid here
+     */
+    if (test_case == NULL) {
+        return srtp_err_status_cant_check;
     }
 
-    /* zeroize tag then compute */
-    octet_string_set_to_zero(tag, test_case->tag_length_octets);
-    status = auth_compute(a, test_case->data,
-			  test_case->data_length_octets, tag);
-    if (status) {
-      auth_dealloc(a);
-      return status;
-    }
-    
-    debug_print(mod_auth, "key: %s",
-		octet_string_hex_string(test_case->key,
-					test_case->key_length_octets));
-    debug_print(mod_auth, "data: %s",
-		octet_string_hex_string(test_case->data,
-				   test_case->data_length_octets));
-    debug_print(mod_auth, "tag computed: %s",
-	   octet_string_hex_string(tag, test_case->tag_length_octets));
-    debug_print(mod_auth, "tag expected: %s",
-	   octet_string_hex_string(test_case->tag,
-				   test_case->tag_length_octets));
+    /* loop over all test cases */
+    while (test_case != NULL) {
+        /* check test case parameters */
+        if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS) {
+            return srtp_err_status_bad_param;
+        }
 
-    /* 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;
+        /* allocate auth */
+        status = srtp_auth_type_alloc(at, &a, test_case->key_length_octets,
+                                      test_case->tag_length_octets);
+        if (status) {
+            return status;
+        }
+
+        /* initialize auth */
+        status = srtp_auth_init(a, test_case->key);
+        if (status) {
+            srtp_auth_dealloc(a);
+            return status;
+        }
+
+        /* zeroize tag then compute */
+        octet_string_set_to_zero(tag, test_case->tag_length_octets);
+        status = srtp_auth_compute(a, test_case->data,
+                                   test_case->data_length_octets, tag);
+        if (status) {
+            srtp_auth_dealloc(a);
+            return status;
+        }
+
+        debug_print(srtp_mod_auth, "key: %s",
+                    srtp_octet_string_hex_string(test_case->key,
+                                                 test_case->key_length_octets));
+        debug_print(srtp_mod_auth, "data: %s",
+                    srtp_octet_string_hex_string(
+                        test_case->data, test_case->data_length_octets));
+        debug_print(
+            srtp_mod_auth, "tag computed: %s",
+            srtp_octet_string_hex_string(tag, test_case->tag_length_octets));
+        debug_print(srtp_mod_auth, "tag expected: %s",
+                    srtp_octet_string_hex_string(test_case->tag,
+                                                 test_case->tag_length_octets));
+
+        /* check the result */
+        status = srtp_err_status_ok;
+        for (i = 0; i < test_case->tag_length_octets; i++) {
+            if (tag[i] != test_case->tag[i]) {
+                status = srtp_err_status_algo_fail;
+                debug_print(srtp_mod_auth, "test case %d failed", case_num);
+                debug_print(srtp_mod_auth, "  (mismatch at octet %d)", i);
+            }
+        }
+        if (status) {
+            srtp_auth_dealloc(a);
+            return srtp_err_status_algo_fail;
+        }
+
+        /* deallocate the auth function */
+        status = srtp_auth_dealloc(a);
+        if (status) {
+            return status;
+        }
+
+        /*
+         * the auth function passed the test case, so move on to the next test
+         * case in the list; if NULL, we'll quit and return an OK
+         */
+        test_case = test_case->next_test_case;
+        ++case_num;
     }
-    
-    /* deallocate the auth function */
-    status = auth_dealloc(a);
-    if (status)
-      return status;
-    
-    /* 
-     * the auth function passed the test case, so move on to the next test
-     * case in the list; if NULL, we'll quit and return an OK
-     */   
-    test_case = test_case->next_test_case;
-    ++case_num;
-  }
-  
-  return err_status_ok;
+
+    return srtp_err_status_ok;
 }
 
+/*
+ * srtp_auth_type_self_test(at) performs srtp_auth_type_test on at's internal
+ * list of test data.
+ */
 
+srtp_err_status_t srtp_auth_type_self_test(const srtp_auth_type_t *at)
+{
+    return srtp_auth_type_test(at, at->test_data);
+}
diff --git a/crypto/hash/hmac.c b/crypto/hash/hmac.c
index 1b19898..6e91468 100644
--- a/crypto/hash/hmac.c
+++ b/crypto/hash/hmac.c
@@ -1,32 +1,32 @@
 /*
  * hmac.c
  *
- * implementation of hmac auth_type_t
+ * implementation of hmac srtp_auth_type_t
  *
  * David A. McGrew
  * Cisco Systems, Inc.
  */
 /*
- *	
- * Copyright(c) 2001-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
@@ -42,230 +42,242 @@
  *
  */
 
-#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   */
 };
 
+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;
 
-err_status_t
-hmac_alloc(auth_t **a, int key_len, int out_len) {
-  extern auth_type_t hmac;
-  uint8_t *pointer;
-  hmac_ctx_t *new_hmac_ctx;
+    debug_print(srtp_mod_hmac, "allocating auth func with key length %d",
+                key_len);
+    debug_print(srtp_mod_hmac, "                          tag length %d",
+                out_len);
 
-  debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
-  debug_print(mod_hmac, "                          tag length %d", out_len);
+    /*
+     * check key length - note that we don't support keys larger
+     * than 20 bytes yet
+     */
+    if (key_len > 20) {
+        return srtp_err_status_bad_param;
+    }
 
-  /*
-   * check key length - note that we don't support keys larger
-   * than 20 bytes yet
-   */
-  if (key_len > 20)
-    return err_status_bad_param;
+    /* check output length - should be less than 20 bytes */
+    if (out_len > 20) {
+        return 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 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;
+    }
 
-  /* allocate memory for auth and hmac_ctx_t structures */
-  pointer = crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
-  if (pointer == NULL)
-    return err_status_alloc_fail;
+    /* 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;
 
-  /* 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;
-  new_hmac_ctx = (hmac_ctx_t *)((*a)->state);
-
-  /* increment global count of all hmac uses */
-  hmac.ref_count++;
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-hmac_dealloc(auth_t *a) {
-  extern auth_type_t hmac;
-  
-  /* zeroize entire state*/
-  octet_string_set_to_zero((octet_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 */
-  crypto_free(a);
-  
-  /* decrement global count of all hmac uses */
-  hmac.ref_count--;
+    /* free memory */
+    srtp_crypto_free(a);
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-hmac_init(hmac_ctx_t *state, const octet_t *key, int key_len) {
-  int i;
+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];
 
-  /*
-   * 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 in the context by exoring the key
-   * into the appropriate constant values
-   */
-  for (i=0; i < key_len; i++) {    
-    state->ipad[i] = key[i] ^ 0x36;
-    state->opad[i] = key[i] ^ 0x5c;
-  }  
-  /* set the rest of ipad, opad to constant values */
-  for (   ; i < 64; i++) {    
-    ((octet_t *)state->ipad)[i] = 0x36;
-    ((octet_t *)state->opad)[i] = 0x5c;
-  }  
+    /*
+     * check key length - note that we don't support keys larger
+     * than 20 bytes yet
+     */
+    if (key_len > 20) {
+        return srtp_err_status_bad_param;
+    }
 
-  debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(state->ipad, 64));
-  
-  /* initialize sha1 context */
-  sha1_init(&state->ctx);
+    /*
+     * 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;
+    }
 
-  /* hash ipad ^ key */
-  sha1_update(&state->ctx, (octet_t *)state->ipad, 64);
+    debug_print(srtp_mod_hmac, "ipad: %s",
+                srtp_octet_string_hex_string(ipad, 64));
 
-  return err_status_ok;
+    /* 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_start(hmac_ctx_t *state) {
-    
-  /* initialize sha1 context */
-  sha1_init(&state->ctx);
+static srtp_err_status_t srtp_hmac_start(void *statev)
+{
+    srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
 
-  /* hash ipad ^ key */
-  sha1_update(&state->ctx, (octet_t *)state->ipad, 64);
+    memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-hmac_update(hmac_ctx_t *state, const octet_t *message, int msg_octets) {
+static srtp_err_status_t srtp_hmac_update(void *statev,
+                                          const uint8_t *message,
+                                          int msg_octets)
+{
+    srtp_hmac_ctx_t *state = (srtp_hmac_ctx_t *)statev;
 
-  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);
+    debug_print(srtp_mod_hmac, "input: %s",
+                srtp_octet_string_hex_string(message, msg_octets));
 
-  return err_status_ok;
+    /* hash message into sha1 context */
+    srtp_sha1_update(&state->ctx, message, msg_octets);
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-hmac_compute(hmac_ctx_t *state, const octet_t *message,
-	     int msg_octets, int tag_len, octet_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, 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;
+    }
 
-  /*
-   * 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((octet_t *)H, 20));
+    /* hash message, copy output into H */
+    srtp_hmac_update(state, message, msg_octets);
+    srtp_sha1_final(&state->ctx, H);
 
-  /* re-initialize hash context */
-  sha1_init(&state->ctx);
-  
-  /* hash opad ^ key  */
-  sha1_update(&state->ctx, (octet_t *)state->opad, 64);
+    /*
+     * 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));
 
-  /* hash the result of the inner hash */
-  sha1_update(&state->ctx, (octet_t *)H, 20);
-  
-  /* the result is returned in the array hash_value[] */
-  sha1_final(&state->ctx, hash_value);
+    /* re-initialize hash context */
+    srtp_sha1_init(&state->ctx);
 
-  /* copy hash_value to *result */
-  for (i=0; i < tag_len; i++)    
-    result[i] = ((octet_t *)hash_value)[i];
+    /* hash opad ^ key  */
+    srtp_sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
 
-  debug_print(mod_hmac, "output: %s", 
-	      octet_string_hex_string((octet_t *)hash_value, tag_len));
+    /* hash the result of the inner hash */
+    srtp_sha1_update(&state->ctx, (uint8_t *)H, 20);
 
-  return err_status_ok;
+    /* the result is returned in the array hash_value[] */
+    srtp_sha1_final(&state->ctx, hash_value);
+
+    /* copy hash_value to *result */
+    for (i = 0; i < tag_len; i++) {
+        result[i] = ((uint8_t *)hash_value)[i];
+    }
+
+    debug_print(srtp_mod_hmac, "output: %s",
+                srtp_octet_string_hex_string((uint8_t *)hash_value, tag_len));
+
+    return srtp_err_status_ok;
 }
 
-
 /* begin test case 0 */
-
-octet_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_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 */
 
-octet_t 
-hmac_test_case_0_data[8] = {
-  0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65   /* "Hi There" */
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_data[8] = {
+    0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
 };
+/* clang-format on */
 
-octet_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
+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          /* */
 };
-
diff --git a/crypto/hash/hmac_ossl.c b/crypto/hash/hmac_ossl.c
new file mode 100644
index 0000000..8146438
--- /dev/null
+++ b/crypto/hash/hmac_ossl.c
@@ -0,0 +1,273 @@
+/*
+ * hmac_ossl.c
+ *
+ * Implementation of hmac srtp_auth_type_t that leverages OpenSSL
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright(c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 "alloc.h"
+#include "err.h" /* for srtp_debug */
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#define SHA1_DIGEST_SIZE 20
+
+/* the debug module for authentiation */
+
+srtp_debug_module_t srtp_mod_hmac = {
+    0,                   /* debugging is off by default */
+    "hmac sha-1 openssl" /* printable name for module   */
+};
+
+static srtp_err_status_t srtp_hmac_alloc(srtp_auth_t **a,
+                                         int key_len,
+                                         int out_len)
+{
+    extern const srtp_auth_type_t srtp_hmac;
+
+    debug_print(srtp_mod_hmac, "allocating auth func with key length %d",
+                key_len);
+    debug_print(srtp_mod_hmac, "                          tag length %d",
+                out_len);
+
+    /* check output length - should be less than 20 bytes */
+    if (out_len > SHA1_DIGEST_SIZE) {
+        return srtp_err_status_bad_param;
+    }
+
+/* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated
+   using HMAC_CTX_new.  But this function doesn't exist in OpenSSL 1.0.x. */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
+    {
+        /* allocate memory for auth and HMAC_CTX structures */
+        uint8_t *pointer;
+        HMAC_CTX *new_hmac_ctx;
+        pointer = (uint8_t *)srtp_crypto_alloc(sizeof(HMAC_CTX) +
+                                               sizeof(srtp_auth_t));
+        if (pointer == NULL) {
+            return srtp_err_status_alloc_fail;
+        }
+        *a = (srtp_auth_t *)pointer;
+        (*a)->state = pointer + sizeof(srtp_auth_t);
+        new_hmac_ctx = (HMAC_CTX *)((*a)->state);
+
+        HMAC_CTX_init(new_hmac_ctx);
+    }
+
+#else
+    *a = (srtp_auth_t *)srtp_crypto_alloc(sizeof(srtp_auth_t));
+    if (*a == NULL) {
+        return srtp_err_status_alloc_fail;
+    }
+
+    (*a)->state = HMAC_CTX_new();
+    if ((*a)->state == NULL) {
+        srtp_crypto_free(*a);
+        *a = NULL;
+        return srtp_err_status_alloc_fail;
+    }
+#endif
+
+    /* set pointers */
+    (*a)->type = &srtp_hmac;
+    (*a)->out_len = out_len;
+    (*a)->key_len = key_len;
+    (*a)->prefix_len = 0;
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_hmac_dealloc(srtp_auth_t *a)
+{
+    HMAC_CTX *hmac_ctx;
+
+    hmac_ctx = (HMAC_CTX *)a->state;
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
+    HMAC_CTX_cleanup(hmac_ctx);
+
+    /* zeroize entire state*/
+    octet_string_set_to_zero(a, sizeof(HMAC_CTX) + sizeof(srtp_auth_t));
+
+#else
+    HMAC_CTX_free(hmac_ctx);
+
+    /* zeroize entire state*/
+    octet_string_set_to_zero(a, sizeof(srtp_auth_t));
+#endif
+
+    /* free memory */
+    srtp_crypto_free(a);
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_hmac_start(void *statev)
+{
+    HMAC_CTX *state = (HMAC_CTX *)statev;
+
+    if (HMAC_Init_ex(state, NULL, 0, NULL, NULL) == 0)
+        return srtp_err_status_auth_fail;
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_hmac_init(void *statev,
+                                        const uint8_t *key,
+                                        int key_len)
+{
+    HMAC_CTX *state = (HMAC_CTX *)statev;
+
+    if (HMAC_Init_ex(state, key, key_len, EVP_sha1(), NULL) == 0)
+        return srtp_err_status_auth_fail;
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_hmac_update(void *statev,
+                                          const uint8_t *message,
+                                          int msg_octets)
+{
+    HMAC_CTX *state = (HMAC_CTX *)statev;
+
+    debug_print(srtp_mod_hmac, "input: %s",
+                srtp_octet_string_hex_string(message, msg_octets));
+
+    if (HMAC_Update(state, message, msg_octets) == 0)
+        return srtp_err_status_auth_fail;
+
+    return srtp_err_status_ok;
+}
+
+static srtp_err_status_t srtp_hmac_compute(void *statev,
+                                           const uint8_t *message,
+                                           int msg_octets,
+                                           int tag_len,
+                                           uint8_t *result)
+{
+    HMAC_CTX *state = (HMAC_CTX *)statev;
+    uint8_t hash_value[SHA1_DIGEST_SIZE];
+    int i;
+    unsigned int len;
+
+    /* check tag length, return error if we can't provide the value expected */
+    if (tag_len > SHA1_DIGEST_SIZE) {
+        return srtp_err_status_bad_param;
+    }
+
+    /* hash message, copy output into H */
+    if (HMAC_Update(state, message, msg_octets) == 0)
+        return srtp_err_status_auth_fail;
+
+    if (HMAC_Final(state, hash_value, &len) == 0)
+        return srtp_err_status_auth_fail;
+
+    if (len < tag_len)
+        return srtp_err_status_auth_fail;
+
+    /* copy hash_value to *result */
+    for (i = 0; i < tag_len; i++) {
+        result[i] = hash_value[i];
+    }
+
+    debug_print(srtp_mod_hmac, "output: %s",
+                srtp_octet_string_hex_string(hash_value, tag_len));
+
+    return srtp_err_status_ok;
+}
+
+/* begin test case 0 */
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_key[SHA1_DIGEST_SIZE] = {
+    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+    0x0b, 0x0b, 0x0b, 0x0b
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_data[8] = {
+    0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
+};
+/* clang-format on */
+
+/* clang-format off */
+static const uint8_t srtp_hmac_test_case_0_tag[SHA1_DIGEST_SIZE] = {
+    0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
+    0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
+    0xf1, 0x46, 0xbe, 0x00
+};
+/* clang-format on */
+
+static const srtp_auth_test_case_t srtp_hmac_test_case_0 = {
+    sizeof(srtp_hmac_test_case_0_key),  /* octets in key            */
+    srtp_hmac_test_case_0_key,          /* key                      */
+    sizeof(srtp_hmac_test_case_0_data), /* octets in data           */
+    srtp_hmac_test_case_0_data,         /* data                     */
+    sizeof(srtp_hmac_test_case_0_tag),  /* octets in tag            */
+    srtp_hmac_test_case_0_tag,          /* tag                      */
+    NULL                                /* pointer to next testcase */
+};
+
+/* end test case 0 */
+
+static const char srtp_hmac_description[] =
+    "hmac sha-1 authentication function";
+
+/*
+ * srtp_auth_type_t hmac is the hmac metaobject
+ */
+
+const srtp_auth_type_t srtp_hmac = {
+    srtp_hmac_alloc,        /* */
+    srtp_hmac_dealloc,      /* */
+    srtp_hmac_init,         /* */
+    srtp_hmac_compute,      /* */
+    srtp_hmac_update,       /* */
+    srtp_hmac_start,        /* */
+    srtp_hmac_description,  /* */
+    &srtp_hmac_test_case_0, /* */
+    SRTP_HMAC_SHA1          /* */
+};
diff --git a/crypto/hash/null_auth.c b/crypto/hash/null_auth.c
index 939e84b..5194417 100644
--- a/crypto/hash/null_auth.c
+++ b/crypto/hash/null_auth.c
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -44,117 +44,125 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include "null_auth.h" 
+#include "null_auth.h"
+#include "err.h" /* for srtp_debug */
 #include "alloc.h"
+#include "cipher_types.h"
 
-/* null_auth uses the auth debug module */
+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;
 
-extern debug_module_t mod_auth;
+    debug_print(srtp_mod_auth, "allocating auth func with key length %d",
+                key_len);
+    debug_print(srtp_mod_auth, "                          tag length %d",
+                out_len);
 
-err_status_t
-null_auth_alloc(auth_t **a, int key_len, int out_len) {
-  extern auth_type_t null_auth;
-  uint8_t *pointer;
+    /* 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;
+    }
 
-  debug_print(mod_auth, "allocating auth func with key length %d", key_len);
-  debug_print(mod_auth, "                          tag length %d", out_len);
+    /* set pointers */
+    *a = (srtp_auth_t *)pointer;
+    (*a)->type = &srtp_null_auth;
+    (*a)->state = pointer + sizeof(srtp_auth_t);
+    (*a)->out_len = out_len;
+    (*a)->prefix_len = out_len;
+    (*a)->key_len = key_len;
 
-  /* allocate memory for auth and null_auth_ctx_t structures */
-  pointer = crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));
-  if (pointer == NULL)
-    return err_status_alloc_fail;
-
-  /* set pointers */
-  *a = (auth_t *)pointer;
-  (*a)->type = &null_auth;
-  (*a)->state = pointer + sizeof (auth_t);  
-  (*a)->out_len = out_len;
-  (*a)->prefix_len = out_len;
-  (*a)->key_len = key_len;
-
-  /* increment global count of all null_auth uses */
-  null_auth.ref_count++;
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_auth_dealloc(auth_t *a) {
-  extern auth_type_t null_auth;
-  
-  /* zeroize entire state*/
-  octet_string_set_to_zero((octet_t *)a, 
-			   sizeof(null_auth_ctx_t) + sizeof(auth_t));
+static srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a)
+{
+    extern const srtp_auth_type_t srtp_null_auth;
 
-  /* free memory */
-  crypto_free(a);
-  
-  /* decrement global count of all null_auth uses */
-  null_auth.ref_count--;
+    /* zeroize entire state*/
+    octet_string_set_to_zero(a, sizeof(srtp_null_auth_ctx_t) +
+                                    sizeof(srtp_auth_t));
 
-  return err_status_ok;
+    /* free memory */
+    srtp_crypto_free(a);
+
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_auth_init(null_auth_ctx_t *state, const octet_t *key, int key_len) {
+static srtp_err_status_t srtp_null_auth_init(void *statev,
+                                             const uint8_t *key,
+                                             int key_len)
+{
+    /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
+    /* accept any length of key, and do nothing */
 
-  /* accept any length of key, and do nothing */
-  
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_auth_compute(null_auth_ctx_t *state, octet_t *message,
-		   int msg_octets, int tag_len, octet_t *result) {
+static srtp_err_status_t srtp_null_auth_compute(void *statev,
+                                                const uint8_t *message,
+                                                int msg_octets,
+                                                int tag_len,
+                                                uint8_t *result)
+{
+    /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_auth_update(null_auth_ctx_t *state, octet_t *message,
-		   int msg_octets) {
+static srtp_err_status_t srtp_null_auth_update(void *statev,
+                                               const uint8_t *message,
+                                               int msg_octets)
+{
+    /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-null_auth_start(null_auth_ctx_t *state) {
-  return err_status_ok;
+static srtp_err_status_t srtp_null_auth_start(void *statev)
+{
+    /* srtp_null_auth_ctx_t *state = (srtp_null_auth_ctx_t *)statev; */
+
+    return srtp_err_status_ok;
 }
 
 /*
- * auth_type_t - defines description, test case, and null_auth
+ * srtp_auth_type_t - defines description, test case, and null_auth
  * metaobject
  */
 
 /* begin test case 0 */
 
-auth_test_case_t
-null_auth_test_case_0 = {
-  0,                                       /* octets in key            */
-  NULL,                                    /* key                      */
-  0,                                       /* octets in data           */ 
-  NULL,                                    /* data                     */
-  0,                                       /* octets in tag            */
-  NULL,                                    /* tag                      */
-  NULL                                     /* pointer to next testcase */
+static const srtp_auth_test_case_t srtp_null_auth_test_case_0 = {
+    0,    /* octets in key            */
+    NULL, /* key                      */
+    0,    /* octets in data           */
+    NULL, /* data                     */
+    0,    /* octets in tag            */
+    NULL, /* tag                      */
+    NULL  /* pointer to next testcase */
 };
 
 /* end test case 0 */
 
-char null_auth_description[] = "null authentication function";
+static const char srtp_null_auth_description[] = "null authentication function";
 
-auth_type_t
-null_auth  = {
-  (auth_alloc_func)      null_auth_alloc,
-  (auth_dealloc_func)    null_auth_dealloc,
-  (auth_init_func)       null_auth_init,
-  (auth_compute_func)    null_auth_compute,
-  (auth_update_func)     null_auth_update,
-  (auth_start_func)      null_auth_start,
-  (char *)               null_auth_description,
-  (int)                  0,  /* instance count */
-  (auth_test_case_t *)   &null_auth_test_case_0
+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               /* */
 };
-
diff --git a/crypto/hash/sha1.c b/crypto/hash/sha1.c
index 59905e7..afd6381 100644
--- a/crypto/hash/sha1.c
+++ b/crypto/hash/sha1.c
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -44,49 +44,49 @@
  *
  */
 
+#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       */
 };
 
-#define bswap_32(x) ntohl(x)
-
 /* 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 octet_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)
  *
@@ -97,310 +97,378 @@
  *  (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 */
-    
-  W[0]  = bswap_32(M[0]);
-  W[1]  = bswap_32(M[1]);
-  W[2]  = bswap_32(M[2]);
-  W[3]  = bswap_32(M[3]);
-  W[4]  = bswap_32(M[4]);
-  W[5]  = bswap_32(M[5]);
-  W[6]  = bswap_32(M[6]);
-  W[7]  = bswap_32(M[7]);
-  W[8]  = bswap_32(M[8]);
-  W[9]  = bswap_32(M[9]);
-  W[10] = bswap_32(M[10]);
-  W[11] = bswap_32(M[11]);
-  W[12] = bswap_32(M[12]);
-  W[13] = bswap_32(M[13]);
-  W[14] = bswap_32(M[14]);
-  W[15] = bswap_32(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);
+    /* copy/xor message into array */
 
-  /* 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);      
-  }
+    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);
 
-  A = H0; B = H1; C = H2; D = H3; E = H4;
-
-  for (t=0; t < 20; t++) {
-    TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
-    E = D; D = C; C = S30(B); B = A; A = TEMP;
-  }
-  for (   ; t < 40; t++) {
-    TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
-    E = D; D = C; C = S30(B); B = A; A = TEMP;
-  }
-  for (   ; t < 60; t++) {
-    TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
-    E = D; D = C; C = S30(B); B = A; A = TEMP;
-  }
-  for (   ; t < 80; t++) {
-    TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
-    E = D; D = C; C = S30(B); B = A; A = TEMP;
-  }
-
-  hash_value[0] = H0 + A;
-  hash_value[1] = H1 + B;
-  hash_value[2] = H2 + C;
-  hash_value[3] = H3 + D;
-  hash_value[4] = H4 + E;
-
-  return;
-}
-
-void
-sha1_init(sha1_ctx_t *ctx) {
- 
-  /* initialize state vector */
-  ctx->H[0] = 0x67452301;
-  ctx->H[1] = 0xefcdab89;
-  ctx->H[2] = 0x98badcfe;
-  ctx->H[3] = 0x10325476;
-  ctx->H[4] = 0xc3d2e1f0;
-
-  /* indicate that message buffer is empty */
-  ctx->octets_in_buffer = 0;
-
-  /* reset message bit-count to zero */
-  ctx->num_bits_in_msg = 0;
-
-}
-
-void
-sha1_update(sha1_ctx_t *ctx, const octet_t *msg, int octets_in_msg) {
-  int i;
-  octet_t *buf = (octet_t *)ctx->M;
-
-  /* update message bit-count */
-  ctx->num_bits_in_msg += octets_in_msg * 8;
-
-  /* loop over 16-word blocks of M */
-  while (octets_in_msg > 0) {
-    
-    if (octets_in_msg + ctx->octets_in_buffer >= 64) {
-
-      /* 
-       * copy words of M into msg buffer until that buffer is full,
-       * converting them into host byte order as needed
-       */
-      octets_in_msg -= (64 - ctx->octets_in_buffer);
-      for (i=ctx->octets_in_buffer; i < 64; i++) 
-	buf[i] = *msg++;
-      ctx->octets_in_buffer = 0;
-
-      /* process a whole block */
-
-      debug_print(mod_sha1, "(update) running sha1_core()", NULL);
-
-      sha1_core(ctx->M, ctx->H);
-
-    } else {
-
-      debug_print(mod_sha1, "(update) not running sha1_core()", NULL);
-
-      for (i=ctx->octets_in_buffer; 
-	   i < (ctx->octets_in_buffer + octets_in_msg); i++)
-	buf[i] = *msg++;
-      ctx->octets_in_buffer += octets_in_msg;
-      octets_in_msg = 0;
+    /* process the remainder of the array */
+    for (t = 32; t < 80; t++) {
+        TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+        W[t] = S1(TEMP);
     }
 
-  }
+    A = H0;
+    B = H1;
+    C = H2;
+    D = H3;
+    E = H4;
 
+    for (t = 0; t < 20; t++) {
+        TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
+        E = D;
+        D = C;
+        C = S30(B);
+        B = A;
+        A = TEMP;
+    }
+    for (; t < 40; t++) {
+        TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
+        E = D;
+        D = C;
+        C = S30(B);
+        B = A;
+        A = TEMP;
+    }
+    for (; t < 60; t++) {
+        TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
+        E = D;
+        D = C;
+        C = S30(B);
+        B = A;
+        A = TEMP;
+    }
+    for (; t < 80; t++) {
+        TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
+        E = D;
+        D = C;
+        C = S30(B);
+        B = A;
+        A = TEMP;
+    }
+
+    hash_value[0] = H0 + A;
+    hash_value[1] = H1 + B;
+    hash_value[2] = H2 + C;
+    hash_value[3] = H3 + D;
+    hash_value[4] = H4 + E;
+
+    return;
+}
+
+void srtp_sha1_init(srtp_sha1_ctx_t *ctx)
+{
+    /* initialize state vector */
+    ctx->H[0] = 0x67452301;
+    ctx->H[1] = 0xefcdab89;
+    ctx->H[2] = 0x98badcfe;
+    ctx->H[3] = 0x10325476;
+    ctx->H[4] = 0xc3d2e1f0;
+
+    /* indicate that message buffer is empty */
+    ctx->octets_in_buffer = 0;
+
+    /* reset message bit-count to zero */
+    ctx->num_bits_in_msg = 0;
+}
+
+void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
+                      const uint8_t *msg,
+                      int octets_in_msg)
+{
+    int i;
+    uint8_t *buf = (uint8_t *)ctx->M;
+
+    /* update message bit-count */
+    ctx->num_bits_in_msg += octets_in_msg * 8;
+
+    /* loop over 16-word blocks of M */
+    while (octets_in_msg > 0) {
+        if (octets_in_msg + ctx->octets_in_buffer >= 64) {
+            /*
+             * copy words of M into msg buffer until that buffer is full,
+             * converting them into host byte order as needed
+             */
+            octets_in_msg -= (64 - ctx->octets_in_buffer);
+            for (i = ctx->octets_in_buffer; i < 64; i++) {
+                buf[i] = *msg++;
+            }
+            ctx->octets_in_buffer = 0;
+
+            /* process a whole block */
+
+            debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()",
+                        NULL);
+
+            srtp_sha1_core(ctx->M, ctx->H);
+
+        } else {
+            debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()",
+                        NULL);
+
+            for (i = ctx->octets_in_buffer;
+                 i < (ctx->octets_in_buffer + octets_in_msg); i++) {
+                buf[i] = *msg++;
+            }
+            ctx->octets_in_buffer += octets_in_msg;
+            octets_in_msg = 0;
+        }
+    }
 }
 
 /*
- * sha1_final(ctx, output) computes the result for ctx and copies it
+ * srtp_sha1_final(ctx, output) computes the result for ctx and copies it
  * into the twenty octets located at *output
  */
 
-void
-sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
-  uint32_t A, B, C, D, E, TEMP;
-  uint32_t W[80];  
-  int i, t;
+void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output)
+{
+    uint32_t A, B, C, D, E, TEMP;
+    uint32_t W[80];
+    int i, t;
 
-  /*
-   * process the remaining octets_in_buffer, padding and terminating as
-   * necessary
-   */
-  {
-    int tail = ctx->octets_in_buffer % 4;
-    
-    /* copy/xor message into array */
-    for (i=0; i < (ctx->octets_in_buffer+3)/4; i++) 
-      W[i]  = bswap_32(ctx->M[i]);  /* why no bswap_32() here?   - DAM */
-
-    /* set the high bit of the octet immediately following the message */
-    switch (tail) {
-    case (3):
-      W[i-1] = (bswap_32(ctx->M[i-1]) & 0xffffff00) | 0x80;
-      W[i] = 0x0;
-      break;
-    case (2):      
-      W[i-1] = (bswap_32(ctx->M[i-1]) & 0xffff0000) | 0x8000;
-      W[i] = 0x0;
-      break;
-    case (1):
-      W[i-1] = (bswap_32(ctx->M[i-1]) & 0xff000000) | 0x800000;
-      W[i] = 0x0;
-      break;
-    case (0):
-      W[i] = 0x80000000;
-      break;
-    }
-    
-    /* zeroize remaining words */
-    for (i++   ; i < 15; i++)
-      W[i] = 0x0;
-
-    /* 
-     * if there is room at the end of the word array, then set the
-     * last word to the bit-length of the message; otherwise, set that
-     * word to zero and then we need to do one more run of the
-     * compression algo.
+    /*
+     * process the remaining octets_in_buffer, padding and terminating as
+     * necessary
      */
-    if (ctx->octets_in_buffer < 56) 
-      W[15] = ctx->num_bits_in_msg;
-    else
-      W[15] = 0x0;
+    {
+        int tail = ctx->octets_in_buffer % 4;
 
-    /* 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);
+        /* copy/xor message into array */
+        for (i = 0; i < (ctx->octets_in_buffer + 3) / 4; i++) {
+            W[i] = be32_to_cpu(ctx->M[i]);
+        }
+
+        /* set the high bit of the octet immediately following the message */
+        switch (tail) {
+        case (3):
+            W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffffff00) | 0x80;
+            W[i] = 0x0;
+            break;
+        case (2):
+            W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xffff0000) | 0x8000;
+            W[i] = 0x0;
+            break;
+        case (1):
+            W[i - 1] = (be32_to_cpu(ctx->M[i - 1]) & 0xff000000) | 0x800000;
+            W[i] = 0x0;
+            break;
+        case (0):
+            W[i] = 0x80000000;
+            break;
+        }
+
+        /* zeroize remaining words */
+        for (i++; i < 15; i++) {
+            W[i] = 0x0;
+        }
+
+        /*
+         * if there is room at the end of the word array, then set the
+         * last word to the bit-length of the message; otherwise, set that
+         * word to zero and then we need to do one more run of the
+         * compression algo.
+         */
+        if (ctx->octets_in_buffer < 56) {
+            W[15] = ctx->num_bits_in_msg;
+        } else if (ctx->octets_in_buffer < 60) {
+            W[15] = 0x0;
+        }
+
+        /* process the word array */
+        for (t = 16; t < 80; t++) {
+            TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+            W[t] = S1(TEMP);
+        }
+
+        A = ctx->H[0];
+        B = ctx->H[1];
+        C = ctx->H[2];
+        D = ctx->H[3];
+        E = ctx->H[4];
+
+        for (t = 0; t < 20; t++) {
+            TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 40; t++) {
+            TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 60; t++) {
+            TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 80; t++) {
+            TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+
+        ctx->H[0] += A;
+        ctx->H[1] += B;
+        ctx->H[2] += C;
+        ctx->H[3] += D;
+        ctx->H[4] += E;
     }
 
-    A = ctx->H[0]; 
-    B = ctx->H[1]; 
-    C = ctx->H[2]; 
-    D = ctx->H[3]; 
-    E = ctx->H[4];
+    debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL);
 
-    for (t=0; t < 20; t++) {
-      TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 40; t++) {
-      TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 60; t++) {
-      TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 80; t++) {
-      TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
+    if (ctx->octets_in_buffer >= 56) {
+        debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again",
+                    NULL);
+
+        /* we need to do one final run of the compression algo */
+
+        /*
+         * set initial part of word array to zeros, and set the
+         * final part to the number of bits in the message
+         */
+        for (i = 0; i < 15; i++) {
+            W[i] = 0x0;
+        }
+        W[15] = ctx->num_bits_in_msg;
+
+        /* process the word array */
+        for (t = 16; t < 80; t++) {
+            TEMP = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+            W[t] = S1(TEMP);
+        }
+
+        A = ctx->H[0];
+        B = ctx->H[1];
+        C = ctx->H[2];
+        D = ctx->H[3];
+        E = ctx->H[4];
+
+        for (t = 0; t < 20; t++) {
+            TEMP = S5(A) + f0(B, C, D) + E + W[t] + SHA_K0;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 40; t++) {
+            TEMP = S5(A) + f1(B, C, D) + E + W[t] + SHA_K1;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 60; t++) {
+            TEMP = S5(A) + f2(B, C, D) + E + W[t] + SHA_K2;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+        for (; t < 80; t++) {
+            TEMP = S5(A) + f3(B, C, D) + E + W[t] + SHA_K3;
+            E = D;
+            D = C;
+            C = S30(B);
+            B = A;
+            A = TEMP;
+        }
+
+        ctx->H[0] += A;
+        ctx->H[1] += B;
+        ctx->H[2] += C;
+        ctx->H[3] += D;
+        ctx->H[4] += E;
     }
 
-    ctx->H[0] += A;
-    ctx->H[1] += B;
-    ctx->H[2] += C;
-    ctx->H[3] += D;
-    ctx->H[4] += E;
+    /* copy result into output buffer */
+    output[0] = be32_to_cpu(ctx->H[0]);
+    output[1] = be32_to_cpu(ctx->H[1]);
+    output[2] = be32_to_cpu(ctx->H[2]);
+    output[3] = be32_to_cpu(ctx->H[3]);
+    output[4] = be32_to_cpu(ctx->H[4]);
 
-  }
+    /* indicate that message buffer in context is empty */
+    ctx->octets_in_buffer = 0;
 
-  debug_print(mod_sha1, "(final) running sha1_core()", NULL);
-
-  if (ctx->octets_in_buffer >= 56) {
-
-    debug_print(mod_sha1, "(final) running sha1_core() again", NULL);
-
-    /* we need to do one final run of the compression algo */
-
-    /* 
-     * set initial part of word array to zeros, and set the 
-     * final part to the number of bits in the message
-     */
-    for (i=0; i < 15; i++)
-      W[i] = 0x0;
-    W[15] = ctx->num_bits_in_msg;
-
-    /* process the word array */
-    for (t=16; t < 80; t++) {
-      TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
-      W[t] = S1(TEMP);
-    }
-
-    A = ctx->H[0]; 
-    B = ctx->H[1]; 
-    C = ctx->H[2]; 
-    D = ctx->H[3]; 
-    E = ctx->H[4];
-
-    for (t=0; t < 20; t++) {
-      TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 40; t++) {
-      TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 60; t++) {
-      TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-    for (   ; t < 80; t++) {
-      TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
-      E = D; D = C; C = S30(B); B = A; A = TEMP;
-    }
-
-    ctx->H[0] += A;
-    ctx->H[1] += B;
-    ctx->H[2] += C;
-    ctx->H[3] += D;
-    ctx->H[4] += E;
-  }
-
-  /* copy result into output buffer */
-  output[0] = bswap_32(ctx->H[0]);
-  output[1] = bswap_32(ctx->H[1]);
-  output[2] = bswap_32(ctx->H[2]);
-  output[3] = bswap_32(ctx->H[3]);
-  output[4] = bswap_32(ctx->H[4]);
-
-  /* indicate that message buffer in context is empty */
-  ctx->octets_in_buffer = 0;
-
-  return;
+    return;
 }
-
-
diff --git a/crypto/include/aes.h b/crypto/include/aes.h
index 126f970..779c3ac 100644
--- a/crypto/include/aes.h
+++ b/crypto/include/aes.h
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,50 +43,41 @@
  *
  */
 
-#ifndef _AES_H
-#define _AES_H
-
-#include "config.h"
+#ifndef AES_H
+#define AES_H
 
 #include "datatypes.h"
-#include "gf2_8.h"
+#include "err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* aes internals */
 
-typedef v128_t aes_expanded_key_t[11];
+typedef struct {
+    v128_t round[15];
+    int num_rounds;
+} srtp_aes_expanded_key_t;
 
-void
-aes_expand_encryption_key(v128_t key, 
-			  aes_expanded_key_t expanded_key);
+srtp_err_status_t srtp_aes_expand_encryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key);
 
-inline void
-aes_expand_decryption_key(const v128_t key, 
-			  aes_expanded_key_t expanded_key);
+srtp_err_status_t srtp_aes_expand_decryption_key(
+    const uint8_t *key,
+    int key_len,
+    srtp_aes_expanded_key_t *expanded_key);
 
-void
-aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
+void srtp_aes_encrypt(v128_t *plaintext,
+                      const srtp_aes_expanded_key_t *exp_key);
 
-void
-aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
+void srtp_aes_decrypt(v128_t *plaintext,
+                      const srtp_aes_expanded_key_t *exp_key);
 
-/*
- * gf2_8_shift(x) returns the next gf2_8 value in the cyclic
- * representation of that field
- */
+#ifdef __cplusplus
+}
+#endif
 
-gf2_8
-gf2_8_shift(octet_t input);
-
-#if 0
-/*
- * internal functions 
- */
-
-void
-aes_init_sbox(void);
-
-void
-aes_compute_tables(void);
-#endif 
-
-#endif /* _AES_H */
+#endif /* AES_H */
diff --git a/crypto/include/aes_cbc.h b/crypto/include/aes_cbc.h
deleted file mode 100644
index b45d601..0000000
--- a/crypto/include/aes_cbc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * aes_cbc.h
- *
- * Header for AES Cipher Blobk Chaining Mode.
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- *
- */
-
-#ifndef AES_CBC_H
-#define AES_CBC_H
-
-#include "aes.h"
-#include "cipher.h"
-
-typedef struct {
-  v128_t   state;                  /* cipher chaining state            */
-  v128_t   previous;               /* previous ciphertext block        */
-  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 octet_t *key, 
-		     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 */
-
diff --git a/crypto/include/aes_gcm.h b/crypto/include/aes_gcm.h
new file mode 100644
index 0000000..4d6031f
--- /dev/null
+++ b/crypto/include/aes_gcm.h
@@ -0,0 +1,89 @@
+/*
+ * aes_gcm.h
+ *
+ * Header for AES Galois Counter Mode.
+ *
+ * John A. Foley
+ * Cisco Systems, Inc.
+ *
+ */
+/*
+ *
+ * Copyright (c) 2013-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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_GCM_H
+#define AES_GCM_H
+
+#include "cipher.h"
+#include "srtp.h"
+#include "datatypes.h"
+
+#ifdef OPENSSL
+
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+
+typedef struct {
+    int key_size;
+    int tag_len;
+    EVP_CIPHER_CTX *ctx;
+    srtp_cipher_direction_t dir;
+} srtp_aes_gcm_ctx_t;
+
+#endif /* OPENSSL */
+
+#ifdef NSS
+
+#include <nss.h>
+#include <pk11pub.h>
+
+#define MAX_AD_SIZE 2048
+
+typedef struct {
+    int key_size;
+    int tag_size;
+    srtp_cipher_direction_t dir;
+    NSSInitContext *nss;
+    PK11SymKey *key;
+    uint8_t iv[12];
+    uint8_t aad[MAX_AD_SIZE];
+    int aad_size;
+    CK_GCM_PARAMS params;
+    uint8_t tag[16];
+} srtp_aes_gcm_ctx_t;
+
+#endif /* NSS */
+
+#endif /* AES_GCM_H */
diff --git a/crypto/include/aes_icm.h b/crypto/include/aes_icm.h
index bbfee2c..8ded156 100644
--- a/crypto/include/aes_icm.h
+++ b/crypto/include/aes_icm.h
@@ -8,6 +8,42 @@
  *
  */
 
+/*
+ *
+ * Copyright (c) 2001-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
 #ifndef AES_ICM_H
 #define AES_ICM_H
 
@@ -15,28 +51,12 @@
 #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       */
-  int      bytes_in_buffer;        /* number of unused bytes in buffer */
-  aes_expanded_key_t expanded_key; /* the cipher key                   */
-} aes_icm_ctx_t;
-
-
-err_status_t
-aes_icm_context_init(aes_icm_ctx_t *c,
-		     const unsigned char *key); 
-
-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);
+    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 */
-
diff --git a/crypto/include/aes_icm_ext.h b/crypto/include/aes_icm_ext.h
new file mode 100644
index 0000000..ad306dd
--- /dev/null
+++ b/crypto/include/aes_icm_ext.h
@@ -0,0 +1,83 @@
+/*
+ * aes_icm.h
+ *
+ * Header for AES Integer Counter Mode.
+ *
+ * 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.
+ *
+ */
+
+#ifndef AES_ICM_H
+#define AES_ICM_H
+
+#include "cipher.h"
+#include "datatypes.h"
+
+#ifdef OPENSSL
+
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+
+typedef struct {
+    v128_t counter; /* holds the counter value          */
+    v128_t offset;  /* initial offset value             */
+    int key_size;
+    EVP_CIPHER_CTX *ctx;
+} srtp_aes_icm_ctx_t;
+
+#endif /* OPENSSL */
+
+#ifdef NSS
+
+#include <nss.h>
+#include <pk11pub.h>
+
+typedef struct {
+    v128_t counter;
+    v128_t offset;
+    int key_size;
+    uint8_t iv[16];
+    NSSInitContext *nss;
+    PK11SymKey *key;
+    PK11Context *ctx;
+} srtp_aes_icm_ctx_t;
+
+#endif /* NSS */
+
+#endif /* AES_ICM_H */
diff --git a/crypto/include/alloc.h b/crypto/include/alloc.h
index 843a7f8..1fc0410 100644
--- a/crypto/include/alloc.h
+++ b/crypto/include/alloc.h
@@ -1,32 +1,32 @@
 /*
  * alloc.h
  *
- * interface to memory allocation and deallocation, with optional debugging 
+ * interface to memory allocation and deallocation, with optional debugging
  *
  * David A. McGrew
  * Cisco Systems, Inc.
  */
 /*
- *	
- * Copyright (c) 2001-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
@@ -42,20 +42,35 @@
  *
  */
 
-
 #ifndef CRYPTO_ALLOC_H
 #define CRYPTO_ALLOC_H
 
-#include "config.h"
+#include "datatypes.h"
 
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-void *
-crypto_alloc(size_t size);
+/*
+ * srtp_crypto_alloc
+ *
+ * Allocates a block of memory  of given size. The memory will be
+ * initialized to zero's. Free the memory with a call to srtp_crypto_free.
+ *
+ * returns pointer to memory on success or else NULL
+ */
+void *srtp_crypto_alloc(size_t size);
 
-void
-crypto_free(void *ptr);
+/*
+ * 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 */
diff --git a/crypto/include/auth.h b/crypto/include/auth.h
index 50e6032..774ea16 100644
--- a/crypto/include/auth.h
+++ b/crypto/include/auth.h
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,117 +43,131 @@
  *
  */
 
-#ifndef AUTH_H
-#define AUTH_H
+#ifndef SRTP_AUTH_H
+#define SRTP_AUTH_H
 
-#include "datatypes.h"          
-#include "err.h"                /* error codes    */
+#include "srtp.h"
+#include "crypto_types.h" /* for values of auth_type_id_t */
 
-typedef struct auth_type_t *auth_type_pointer;
-typedef struct auth_t      *auth_pointer_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-typedef err_status_t (*auth_alloc_func)
-     (auth_pointer_t *ap, int key_len, int out_len);
+typedef const struct srtp_auth_type_t *srtp_auth_type_pointer;
+typedef struct srtp_auth_t *srtp_auth_pointer_t;
 
-typedef err_status_t (*auth_init_func)
-     (void *state, const octet_t *key, int key_len);
+typedef srtp_err_status_t (*srtp_auth_alloc_func)(srtp_auth_pointer_t *ap,
+                                                  int key_len,
+                                                  int out_len);
 
-typedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap);
+typedef srtp_err_status_t (*srtp_auth_init_func)(void *state,
+                                                 const uint8_t *key,
+                                                 int key_len);
 
-typedef err_status_t (*auth_compute_func)
-     (void *state, octet_t *buffer, int octets_to_auth, 
-      int tag_len, octet_t *tag);
+typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap);
 
-typedef err_status_t (*auth_update_func)
-     (void *state, octet_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);
-     
+typedef srtp_err_status_t (*srtp_auth_update_func)(void *state,
+                                                   const uint8_t *buffer,
+                                                   int octets_to_auth);
+
+typedef srtp_err_status_t (*srtp_auth_start_func)(void *state);
+
 /* some syntactic sugar on these function types */
+#define srtp_auth_type_alloc(at, a, klen, outlen)                              \
+    ((at)->alloc((a), (klen), (outlen)))
 
-#define auth_type_alloc(at, a, klen, outlen)                        \
-                 ((at)->alloc((a), (klen), (outlen)))
+#define srtp_auth_init(a, key)                                                 \
+    (((a)->type)->init((a)->state, (key), ((a)->key_len)))
 
-#define auth_init(a, key)                                           \
-                 (((a)->type)->init((a)->state, (key), ((a)->key_len)))
+#define srtp_auth_compute(a, buf, len, res)                                    \
+    (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
 
-#define auth_compute(a, buf, len, res)                              \
-       (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
+#define srtp_auth_update(a, buf, len)                                          \
+    (((a)->type)->update((a)->state, (buf), (len)))
 
-#define auth_update(a, buf, len)                                    \
-       (((a)->type)->update((a)->state, (buf), (len)))
+#define srtp_auth_start(a) (((a)->type)->start((a)->state))
 
-#define auth_start(a)(((a)->type)->start((a)->state))
-
-#define auth_dealloc(c) (((c)->type)->dealloc(c))
+#define srtp_auth_dealloc(c) (((c)->type)->dealloc(c))
 
 /* functions to get information about a particular auth_t */
+int srtp_auth_get_key_length(const struct srtp_auth_t *a);
 
-int
-auth_get_key_length(const struct auth_t *a);
+int srtp_auth_get_tag_length(const struct srtp_auth_t *a);
 
-int
-auth_get_tag_length(const struct auth_t *a);
-
-int
-auth_get_prefix_length(const struct auth_t *a);
+int srtp_auth_get_prefix_length(const struct srtp_auth_t *a);
 
 /*
- * auth_test_case_t is a (list of) key/message/tag values that are
+ * srtp_auth_test_case_t is a (list of) key/message/tag values that are
  * known to be correct for a particular cipher.  this data can be used
  * to test an implementation in an on-the-fly self test of the
- * correcness of the implementation.  (see the auth_type_self_test()
+ * correctness of the implementation.  (see the srtp_auth_type_self_test()
  * function below)
  */
+typedef struct srtp_auth_test_case_t {
+    int key_length_octets;  /* octets in key            */
+    const uint8_t *key;     /* key                      */
+    int data_length_octets; /* octets in data           */
+    const uint8_t *data;    /* data                     */
+    int tag_length_octets;  /* octets in tag            */
+    const uint8_t *tag;     /* tag                      */
+    const struct srtp_auth_test_case_t
+        *next_test_case; /* pointer to next testcase */
+} srtp_auth_test_case_t;
 
-typedef struct auth_test_case_t {
-  int key_length_octets;                    /* octets in key            */
-  octet_t *key;                             /* key                      */
-  int data_length_octets;                   /* octets in data           */ 
-  octet_t *data;                            /* data                     */
-  int tag_length_octets;                    /* octets in tag            */
-  octet_t *tag;                             /* tag                      */
-  struct auth_test_case_t *next_test_case;  /* pointer to next testcase */
-} auth_test_case_t;
+/* srtp_auth_type_t */
+typedef struct srtp_auth_type_t {
+    srtp_auth_alloc_func alloc;
+    srtp_auth_dealloc_func dealloc;
+    srtp_auth_init_func init;
+    srtp_auth_compute_func compute;
+    srtp_auth_update_func update;
+    srtp_auth_start_func start;
+    const char *description;
+    const srtp_auth_test_case_t *test_data;
+    srtp_auth_type_id_t id;
+} srtp_auth_type_t;
 
-/* auth_type_t */
+typedef struct 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;
 
-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_t;
-
-typedef struct auth_t {
-  auth_type_t *type;
-  void        *state;                   
-  int          out_len;           /* length of output tag in octets */
-  int          key_len;           /* length of key in octets        */
-  int          prefix_len;        /* length of keystream prefix     */
-} auth_t;
-
-/* 
- * auth_type_self_test() tests an auth_type against test cases
+/*
+ * 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
  */
-
-err_status_t
-auth_type_self_test(const auth_type_t *at);
+srtp_err_status_t srtp_auth_type_self_test(const srtp_auth_type_t *at);
 
 /*
- * auth_type_get_ref_count(at) returns the reference count (the number
- * of instantiations) of the auth_type_t at
+ * srtp_auth_type_test() tests an auth_type against external test cases
+ * provided in an array of values of key/message/tag that is known to
+ * be good
  */
+srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at,
+                                      const srtp_auth_test_case_t *test_data);
 
-int
-auth_type_get_ref_count(const 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);
 
-#endif /* AUTH_H */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_AUTH_H */
diff --git a/crypto/include/cipher.h b/crypto/include/cipher.h
index b2bc88b..4f14e35 100644
--- a/crypto/include/cipher.h
+++ b/crypto/include/cipher.h
@@ -7,26 +7,26 @@
  * 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
@@ -42,178 +42,207 @@
  *
  */
 
+#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  */
+#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 { 
-  direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
-  direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
-  direction_any      /**< encryption or decryption                     */
-} cipher_direction_t;
+typedef enum {
+    srtp_direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
+    srtp_direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
+    srtp_direction_any      /**< encryption or decryption                     */
+} srtp_cipher_direction_t;
 
 /*
- * the cipher_pointer and cipher_type_pointer definitions are needed
- * as cipher_t and cipher_type_t are not yet defined
+ * the srtp_cipher_pointer_t definition is needed
+ * as srtp_cipher_t is not yet defined
  */
-
-typedef struct cipher_type_t *cipher_type_pointer_t;
-typedef struct cipher_t      *cipher_pointer_t;
+typedef struct srtp_cipher_t *srtp_cipher_pointer_t;
 
 /*
- *  a cipher_alloc_func_t allocates (but does not initialize) a cipher_t 
+ *  a srtp_cipher_alloc_func_t allocates (but does not initialize) a
+ * srtp_cipher_t
  */
-
-typedef err_status_t (*cipher_alloc_func_t)
-     (cipher_pointer_t *cp, int key_len);
-
-/* 
- * a cipher_init_func_t [re-]initializes a cipher_t with a given key
- * and direction (i.e., encrypt or decrypt)
- */
-
-typedef err_status_t (*cipher_init_func_t)
-  (void *state, const octet_t *key, cipher_direction_t dir);
-
-/* a cipher_dealloc_func_t de-allocates a cipher_t */
-
-typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp);
-
-/* a cipher_set_segment_func_t sets the segment index of a cipher_t */
-
-typedef err_status_t (*cipher_set_segment_func_t)
-     (void *state, xtd_seq_num_t idx);
-
-/* a cipher_encrypt_func_t encrypts data in-place */
-
-typedef err_status_t (*cipher_encrypt_func_t)
-     (void *state, octet_t *buffer, unsigned int *octets_to_encrypt);
-
-/* a cipher_decrypt_func_t decrypts data in-place */
-
-typedef err_status_t (*cipher_decrypt_func_t)
-     (void *state, octet_t *buffer, unsigned int *octets_to_decrypt);
-
-/* 
- * a cipher_set_nonce_seq_func_t function sets both the nonce
- * and the extended sequence number
- */
-
-typedef err_status_t (*cipher_set_iv_func_t)
-     (cipher_pointer_t cp, void *iv);
+typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)(srtp_cipher_pointer_t *cp,
+                                                      int key_len,
+                                                      int tag_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
+ * a srtp_cipher_init_func_t [re-]initializes a cipher_t with a given key
+ */
+typedef srtp_err_status_t (*srtp_cipher_init_func_t)(void *state,
+                                                     const uint8_t *key);
+
+/* a srtp_cipher_dealloc_func_t de-allocates a cipher_t */
+typedef srtp_err_status_t (*srtp_cipher_dealloc_func_t)(
+    srtp_cipher_pointer_t cp);
+
+/*
+ * a srtp_cipher_set_aad_func_t processes the AAD data for AEAD ciphers
+ */
+typedef srtp_err_status_t (*srtp_cipher_set_aad_func_t)(void *state,
+                                                        const uint8_t *aad,
+                                                        uint32_t aad_len);
+
+/* a srtp_cipher_encrypt_func_t encrypts data in-place */
+typedef srtp_err_status_t (*srtp_cipher_encrypt_func_t)(
+    void *state,
+    uint8_t *buffer,
+    unsigned int *octets_to_encrypt);
+
+/* a srtp_cipher_decrypt_func_t decrypts data in-place */
+typedef srtp_err_status_t (*srtp_cipher_decrypt_func_t)(
+    void *state,
+    uint8_t *buffer,
+    unsigned int *octets_to_decrypt);
+
+/*
+ * a srtp_cipher_set_iv_func_t function sets the current initialization vector
+ */
+typedef srtp_err_status_t (*srtp_cipher_set_iv_func_t)(
+    void *state,
+    uint8_t *iv,
+    srtp_cipher_direction_t direction);
+
+/*
+ * a cipher_get_tag_func_t function is used to get the authentication
+ * tag that was calculated by an AEAD cipher.
+ */
+typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)(void *state,
+                                                        uint8_t *tag,
+                                                        uint32_t *len);
+
+/*
+ * srtp_cipher_test_case_t is a (list of) key, salt, plaintext, ciphertext,
+ * 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            */
-  octet_t *key;                               /* key                      */
-  octet_t *idx;                               /* packet index             */
-  int plaintext_length_octets;                /* octets in plaintext      */ 
-  octet_t *plaintext;                         /* plaintext                */
-  int ciphertext_length_octets;               /* octets in plaintext      */ 
-  octet_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_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;
-#if 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), (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(((c)->state), (n))) :   \
-                                err_status_no_such_op)  
-
-err_status_t
-cipher_output(cipher_t *c, octet_t *buffer, int num_octets_to_output);
-
+typedef struct srtp_cipher_t {
+    const srtp_cipher_type_t *type;
+    void *state;
+    int key_len;
+    int algorithm;
+} srtp_cipher_t;
 
 /* some bookkeeping functions */
-
-int
-cipher_get_key_length(const cipher_t *c);
-
-
-/* 
- * cipher_type_self_test() tests a cipher against test cases provided in 
- * an array of values of key/xtd_seq_num_t/plaintext/ciphertext 
- * that is known to be good
- */
-
-err_status_t
-cipher_type_self_test(const cipher_type_t *ct);
-
+int srtp_cipher_get_key_length(const srtp_cipher_t *c);
 
 /*
- * cipher_bits_per_second(c, l, t) computes (and estimate of) the
+ * srtp_cipher_type_self_test() tests a cipher against test cases provided in
+ * an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext
+ * that is known to be good
+ */
+srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct);
+
+/*
+ * srtp_cipher_type_test() tests a cipher against external test cases provided
+ * in
+ * an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext
+ * that is known to be good
+ */
+srtp_err_status_t srtp_cipher_type_test(
+    const srtp_cipher_type_t *ct,
+    const srtp_cipher_test_case_t *test_data);
+
+/*
+ * srtp_cipher_bits_per_second(c, l, t) computes (an estimate of) the
  * number of bits that a cipher implementation can encrypt in a second
- * 
+ *
  * c is a cipher (which MUST be allocated and initialized already), l
  * is the length in octets of the test data to be encrypted, and t is
  * the number of trials
  *
- * if an error is encountered, then the value 0.0 is returned
+ * if an error is encountered, then the value 0 is returned
  */
+uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c,
+                                     int octets_in_buffer,
+                                     int num_trials);
 
-double
-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 */
diff --git a/crypto/include/cipher_priv.h b/crypto/include/cipher_priv.h
new file mode 100644
index 0000000..46848ea
--- /dev/null
+++ b/crypto/include/cipher_priv.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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_CIHPER_PRIV_H
+#define SRTP_CIHPER_PRIV_H
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A trivial platform independent random source.
+ * For use in test only.
+ */
+void srtp_cipher_rand_for_tests(void *dest, uint32_t len);
+
+/*
+ * A trivial platform independent 32 bit random number.
+ * For use in test only.
+ */
+uint32_t srtp_cipher_rand_u32_for_tests(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_CIPHER_PRIV_H */
diff --git a/crypto/include/cipher_types.h b/crypto/include/cipher_types.h
new file mode 100644
index 0000000..18f0328
--- /dev/null
+++ b/crypto/include/cipher_types.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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
+ */
+
+extern const srtp_cipher_type_t srtp_null_cipher;
+extern const srtp_cipher_type_t srtp_aes_icm_128;
+extern const srtp_cipher_type_t srtp_aes_icm_256;
+#ifdef GCM
+extern const srtp_cipher_type_t srtp_aes_icm_192;
+extern const srtp_cipher_type_t srtp_aes_gcm_128;
+extern const srtp_cipher_type_t srtp_aes_gcm_256;
+#endif
+
+/*
+ * auth func types that can be included in the kernel
+ */
+
+extern const srtp_auth_type_t srtp_null_auth;
+extern const srtp_auth_type_t srtp_hmac;
+
+/*
+ * other generic debug modules that can be included in the kernel
+ */
+
+extern srtp_debug_module_t srtp_mod_auth;
+extern srtp_debug_module_t srtp_mod_cipher;
+extern srtp_debug_module_t srtp_mod_stat;
+extern srtp_debug_module_t srtp_mod_alloc;
+
+/* debug modules for cipher types */
+extern srtp_debug_module_t srtp_mod_aes_icm;
+#ifdef OPENSSL
+extern srtp_debug_module_t srtp_mod_aes_gcm;
+#endif
+#ifdef NSS
+extern srtp_debug_module_t srtp_mod_aes_gcm;
+#endif
+
+/* debug modules for auth types */
+extern srtp_debug_module_t srtp_mod_hmac;
+
+#endif
diff --git a/crypto/include/config.h b/crypto/include/config.h
index 2dee171..333cf43 100644
--- a/crypto/include/config.h
+++ b/crypto/include/config.h
@@ -1,121 +1,197 @@
-/* include/config.h.  Generated automatically by configure.  */
-/*
- * config.h
- *
- * template for header config file for Secure RTP and UST implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
+/* crypto/include/config.h.  Generated from config_in.h by configure.  */
+/* config_in.h.  Generated from configure.ac by autoheader.  */
 
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
 
-#ifndef CONFIG_H
-#define CONFIG_H
+/* Define if building for a CISC machine (e.g. Intel). */
+#define CPU_CISC 1
 
-/* if we're on a big endian machine, we need to define this */
+/* Define if building for a RISC machine (assume slow byte access). */
+/* #undef CPU_RISC */
 
-#include <sys/types.h>
-#if (BYTE_ORDER == BIG_ENDIAN)
-#define WORDS_BIGENDIAN      1
-#else
-#define WORDS_BIGENDIAN      0
-#endif
+/* Define to enabled debug logging for all mudules. */
+/* #undef ENABLE_DEBUG_LOGGING */
 
-/* check for <stdint.h> or <machine/types.h>              */
+/* Logging statments will be writen to this file. */
+/* #undef ERR_REPORTING_FILE */
 
-#define HAVE_STDINT_H        1
-#define HAVE_MACHINE_TYPES_H 1
-#define HAVE_SYS_INT_TYPES_H 0
+/* Define to redirect logging to stdout. */
+/* #undef ERR_REPORTING_STDOUT */
 
-/* check for microsoft integer definitions (e.g., cygwin) */
+/* Define this to use AES-GCM. */
+/* #undef GCM */
 
-#define HAVE_MS_TYPES        1
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
 
-/* if we don't have uio.h, we'll need to define struct iovec */
+/* Define to 1 if you have the <byteswap.h> header file. */
+#define HAVE_BYTESWAP_H 1
 
-#define HAVE_SYS_UIO_H       1
+/* Define to 1 if you have the `inet_aton' function. */
+#define HAVE_INET_ATON 1
 
-/* <unistd.h> is used by some test/ apps                  */
+/* Define to 1 if the system has the type `int16_t'. */
+#define HAVE_INT16_T 1
 
-#define HAVE_UNISTD_H        1
+/* Define to 1 if the system has the type `int32_t'. */
+#define HAVE_INT32_T 1
 
-/* test apps should use inet_aton(), if it's available */
+/* Define to 1 if the system has the type `int8_t'. */
+#define HAVE_INT8_T 1
 
-#define HAVE_INET_ATON       1
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
 
-/* check if we have syslog functions                      */
+/* Define to 1 if you have the `dl' library (-ldl). */
+/* #undef HAVE_LIBDL */
 
-#define HAVE_SYSLOG_H        1
+/* Define to 1 if you have the `nspr4' library (-lnspr4). */
+/* #undef HAVE_LIBNSPR4 */
 
-/* check to see if the user has requested the use of syslog */
+/* Define to 1 if you have the `nss3' library (-lnss3). */
+/* #undef HAVE_LIBNSS3 */
 
-#define USE_SYSLOG           0
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
 
-#define ERR_REPORTING_STDOUT 1
+/* Define to 1 if you have the `z' library (-lz). */
+/* #undef HAVE_LIBZ */
 
-#define ERR_REPORTING_SYSLOG (HAVE_SYSLOG_H & USE_SYSLOG)
+/* Define to 1 if you have the <machine/types.h> header file. */
+/* #undef HAVE_MACHINE_TYPES_H */
 
-/* define ERR_REPORTING_FILE to have messages sent to file */
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
 
-#define ERR_REPORTING_FILE 
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
 
-/* 
- * set ENABLE_DEBUGGING to 1 to compile in dynamic debugging system,
- * set it to 0 to not compile in dynamic debugging (for a slight
- * performance improvement)
- */
+/* Define to 1 if you have the <nss.h> header file. */
+/* #undef HAVE_NSS_H */
 
-#define ENABLE_DEBUGGING     1
+/* Define to 1 if you have the `winpcap' library (-lwpcap) */
+/* #undef HAVE_PCAP */
 
-/* if we're going to use GDOI, define SRTP_GDOI to 1      */
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
 
-#define SRTP_GDOI            0
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
 
-/*
- * CPU_type is defined as 1 if the host processor is of that type.
- * Note that more than one type can be defined at once; this is so
- * that special instructions and other optimizations can be handled
- * independently.
- * 
- * CPU_RISC     RISC machines (assume slow byte access)
- * CPU_CISC     CISC machines (e.g. Intel)
- * 
- */
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
 
-#if WORDS_BIGENDIAN
-#define CPU_RISC     1
-#else
-#define CPU_CISC     1
-#endif
-
-/*
- * define CPU_16 if cryptoalgorithms should use 16-bit operations -
- * this is probably only the case on very low-end devices
- */
-#define CPU_16       0
-
-/* 
- * define CPU_ALTIVEC in order to use the G4/G5 processor's AltiVec
- * SIMD instruction set where possible
- */
-#define CPU_ALTIVEC  0
-
-
-/*
- * if /dev/random is available, then DEV_RANDOM == 1
- *
- * /dev/random is a (true) random number generator which is
- * implemented in many modern operating systems
- */
-
-#define DEV_RANDOM 0
-
-/* check for stdlib.h - we use it for alloc() and free() */
-
+/* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
-#endif /* CONFIG_H */
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
 
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
 
+/* Define to 1 if you have the <sys/int_types.h> header file. */
+/* #undef HAVE_SYS_INT_TYPES_H */
 
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
 
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if the system has the type `uint16_t'. */
+#define HAVE_UINT16_T 1
+
+/* Define to 1 if the system has the type `uint32_t'. */
+#define HAVE_UINT32_T 1
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#define HAVE_UINT64_T 1
+
+/* Define to 1 if the system has the type `uint8_t'. */
+#define HAVE_UINT8_T 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+#define HAVE_USLEEP 1
+
+/* Define to 1 if you have the <windows.h> header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to use X86 inlined assembly code */
+#define HAVE_X86 1
+
+/* Define this to use NSS crypto. */
+/* #undef NSS */
+
+/* Define this to use OpenSSL crypto. */
+/* #undef OPENSSL */
+
+/* Define this if OPENSSL_cleanse is broken. */
+/* #undef OPENSSL_CLEANSE_BROKEN */
+
+/* Define this to use OpenSSL KDF for SRTP. */
+/* #undef OPENSSL_KDF */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://github.com/cisco/libsrtp/issues"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libsrtp2"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libsrtp2 2.3.0-pre"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libsrtp2"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.3.0-pre"
+
+/* The size of `unsigned long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG 8
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG_LONG 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/crypto/include/crypto.h b/crypto/include/crypto.h
deleted file mode 100644
index dc52821..0000000
--- a/crypto/include/crypto.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * crypto.h
- *
- * API for libcrypto
- * 
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-#ifndef CRYPTO_H
-#define CRYPTO_H
-
-#include "crypto_kernel.h"
-
-#endif /* CRYPTO_H */
-
-
diff --git a/crypto/include/crypto_kernel.h b/crypto/include/crypto_kernel.h
index 0f3f7ee..1f8dfa7 100644
--- a/crypto/include/crypto_kernel.h
+++ b/crypto/include/crypto_kernel.h
@@ -7,26 +7,26 @@
  * 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
@@ -42,20 +42,18 @@
  *
  */
 
-
 #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"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
  * crypto_kernel_state_t defines the possible states:
@@ -63,71 +61,36 @@
  *    insecure - not yet initialized
  *    secure   - initialized and passed self-tests
  */
-
 typedef enum {
-  crypto_kernel_state_insecure,
-  crypto_kernel_state_secure
-} crypto_kernel_state_t;
-
-
-/** 
- *  @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;
-
-
-/* 
- * linked list of cipher types 
- */
-
-typedef struct kernel_cipher_type {
-  cipher_type_id_t  id;
-  cipher_type_t    *cipher_type;
-  struct kernel_cipher_type *next;
-} kernel_cipher_type_t;
-
-/* 
- * linked list of auth types 
- */
-
-typedef struct kernel_auth_type {
-  auth_type_id_t  id;
-  auth_type_t    *auth_type;
-  struct kernel_auth_type *next;
-} kernel_auth_type_t;
+    srtp_crypto_kernel_state_insecure,
+    srtp_crypto_kernel_state_secure
+} srtp_crypto_kernel_state_t;
 
 /*
- * linked list of debug modules 
+ * linked list of cipher types
  */
+typedef struct srtp_kernel_cipher_type {
+    srtp_cipher_type_id_t id;
+    const srtp_cipher_type_t *cipher_type;
+    struct srtp_kernel_cipher_type *next;
+} srtp_kernel_cipher_type_t;
 
-typedef struct kernel_debug_module {
-  debug_module_t *mod;
-  struct kernel_debug_module *next;
-} kernel_debug_module_t;
+/*
+ * linked list of auth types
+ */
+typedef struct srtp_kernel_auth_type {
+    srtp_auth_type_id_t id;
+    const srtp_auth_type_t *auth_type;
+    struct srtp_kernel_auth_type *next;
+} srtp_kernel_auth_type_t;
 
+/*
+ * linked list of debug modules
+ */
+typedef struct srtp_kernel_debug_module {
+    srtp_debug_module_t *mod;
+    struct srtp_kernel_debug_module *next;
+} srtp_kernel_debug_module_t;
 
 /*
  * crypto_kernel_t is the data structure for the crypto kernel
@@ -135,154 +98,118 @@
  * 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();
-
+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();
+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();
-
+srtp_err_status_t srtp_crypto_kernel_status(void);
 
 /*
- * crypto_kernel_list_debug_modules() outputs a list of debugging modules
+ * srtp_crypto_kernel_list_debug_modules() outputs a list of debugging modules
  *
  */
-
-err_status_t
-crypto_kernel_list_debug_modules();
+srtp_err_status_t srtp_crypto_kernel_list_debug_modules(void);
 
 /*
- * crypto_kernel_load_cipher_type()
+ * srtp_crypto_kernel_load_cipher_type()
  *
  */
+srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
+    const srtp_cipher_type_t *ct,
+    srtp_cipher_type_id_t id);
 
-err_status_t
-crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
+srtp_err_status_t srtp_crypto_kernel_load_auth_type(const srtp_auth_type_t *ct,
+                                                    srtp_auth_type_id_t id);
 
-err_status_t
-crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);
-
-err_status_t
-crypto_kernel_load_debug_module(debug_module_t *new_dm);
+srtp_err_status_t srtp_crypto_kernel_load_debug_module(
+    srtp_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
  */
+srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *mod_name,
+                                                      int v);
 
-err_status_t
-crypto_kernel_set_debug_module(char *mod_name, int v);
+#ifdef __cplusplus
+}
+#endif
 
-/**
- * @brief writes a random octet string.
- *
- * The function call crypto_get_random(dest, len) writes len octets of
- * random data to the location to which dest points, and returns an
- * error code.  This error code @b must be checked, and if a failure is
- * reported, the data in the buffer @b must @b not be used.
- * 
- * @warning If the return code is not checked, then non-random
- *          data may be in the buffer.  This function will fail
- *          unless it is called after crypto_kernel_init().
- *
- * @return
- *     - err_status_ok    if no problems occured.
- *     - [other]          a problem occured, and no assumptions should
- *                        be made about the contents of the destination
- *                        buffer.
- *
- * @ingroup SRTP
- */
-err_status_t
-crypto_get_random(unsigned char *buffer, unsigned int length);
-     
 #endif /* CRYPTO_KERNEL */
diff --git a/crypto/include/crypto_types.h b/crypto/include/crypto_types.h
index e20c771..7fd3178 100644
--- a/crypto/include/crypto_types.h
+++ b/crypto/include/crypto_types.h
@@ -7,26 +7,26 @@
  * 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
@@ -42,165 +42,75 @@
  *
  */
 
-#ifndef CRYPTO_TYPES_H
-#define CRYPTO_TYPES_H
+#ifndef SRTP_CRYPTO_TYPES_H
+#define SRTP_CRYPTO_TYPES_H
 
-/**
- * @defgroup Algos Cryptographic Algorithms
+/*
+ * The null cipher performs no encryption.
  *
- *
- * This library provides several different cryptographic algorithms,
- * each of which can be selected by using the cipher_type_id_t and
- * auth_type_id_t.  These algorithms are documented below.
- *
- * Authentication functions that use the Universal Security Transform
- * (UST) must be used in conjunction with a cipher other than the null
- * cipher.  These functions require a per-message pseudorandom input
- * that is generated by the cipher.
- * 
- * The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the
- * strongest available authentication function and cipher,
- * respectively.  They are resolved at compile time to the strongest
- * available algorithm.  The stronghold algorithms can serve as did
- * the keep of a medieval fortification; they provide the strongest
- * defense (or the last refuge).
- * 
- * @{
- */
-
-/**
- * @defgroup Ciphers Cipher Types
- *
- * @brief    Each cipher type is identified by an unsigned integer.  The
- *           cipher types available in this edition of libSRTP are given 
- *           by the #defines below.
- *
- * A cipher_type_id_t is an identifier for a cipher_type; only values
- * given by the #defines above (or those present in the file
- * crypto_types.h) should be used.
- *
- * The identifier STRONGHOLD_CIPHER indicates the strongest available
- * cipher, allowing an application to choose the strongest available
- * algorithm without any advance knowledge about the avaliable
- * algorithms.
- *
- * @{
- */
-
-/**
- * @brief The null cipher performs no encryption.
- *
- * The NULL_CIPHER leaves its inputs unaltered, during both the 
+ * The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the
  * encryption and decryption operations.  This cipher can be chosen
  * to indicate that no encryption is to be performed.
  */
-#define NULL_CIPHER        0            
+#define SRTP_NULL_CIPHER 0
 
-/** 
- * @brief AES-128 Integer Counter Mode (AES ICM)             
+/*
+ * AES-128 Integer Counter Mode (AES ICM)
  *
- * AES-128 ICM is the variant of counter mode that is used by Secure RTP.  
- * This cipher uses a 16-octet key and a 30-octet offset (or salt) value.
+ * AES-128 ICM is the variant of counter mode that is used by
+ * Secure RTP.  This cipher uses a 16-octet key concatenated with a
+ * 14-octet offset (or salt) value.
  */
-#define AES_128_ICM        1            
+#define SRTP_AES_ICM_128 1
 
-/**
- * @brief SEAL 3.0 
- * 
- * SEAL is the Software-Optimized Encryption Algorithm of Coppersmith
- * and Rogaway.  Nota bene: this cipher is IBM proprietary.
- */
-#define SEAL               2            
-
-/** 
- * @brief AES-128 Integer Counter Mode (AES ICM)             
+/*
+ * 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 16-octet key and a 30-octet offset (or salt) value.
+ * 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_128_CBC        3            
+#define SRTP_AES_ICM_192 4
 
-/**
- * @brief Strongest available cipher.
+/*
+ * AES-256 Integer Counter Mode (AES ICM)
  *
- * This identifier resolves to the strongest cipher type available.
+ * 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 STRONGHOLD_CIPHER  AES_128_ICM  
+#define SRTP_AES_ICM_256 5
 
-/**
- * @}
+/*
+ * AES-128_GCM Galois Counter Mode (AES GCM)
+ *
+ * AES-128 GCM is the variant of galois counter mode that is used by
+ * Secure RTP.  This cipher uses a 16-octet key.
  */
+#define 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 */
diff --git a/crypto/include/cryptoalg.h b/crypto/include/cryptoalg.h
deleted file mode 100644
index b5bf3b3..0000000
--- a/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-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#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 protected 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 *protected,         
-      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 */
-
-
diff --git a/crypto/include/datatypes.h b/crypto/include/datatypes.h
index f7ef3f8..6a588d0 100644
--- a/crypto/include/datatypes.h
+++ b/crypto/include/datatypes.h
@@ -1,6 +1,6 @@
 /*
  * datatypes.h
- * 
+ *
  * data types for bit vectors and finite fields
  *
  * David A. McGrew
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,186 +43,140 @@
  *
  */
 
+#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"
 
-/* if DATATYPES_USE_MACROS is defined, then little functions are macros */
-#define DATATYPES_USE_MACROS  
+#include <stdarg.h>
 
-typedef unsigned char octet_t;
+#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
 
 typedef union {
-  unsigned char octet[2];
-  uint16_t value;
+    uint8_t v8[2];
+    uint16_t value;
 } v16_t;
 
 typedef union {
-  unsigned char octet[4];
-  uint16_t v16[2];
-  uint32_t value;
+    uint8_t v8[4];
+    uint16_t v16[2];
+    uint32_t value;
 } v32_t;
 
 typedef union {
-  unsigned char octet[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 {
-  unsigned char octet[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_weight(x) returns the hamming weight (number of bits equal to
+ * octet_get_weight(x) returns the hamming weight (number of bits equal to
  * one) in the octet x
  */
 
-int
-octet_get_weight(octet_t octet);
-
-char *
-octet_bit_string(octet_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 *srtp_octet_string_hex_string(const void *str, int length);
 
-char *
-v128_bit_string(v128_t *x);
+char *v128_bit_string(v128_t *x);
 
-char *
-v128_hex_string(v128_t *x);
+char *v128_hex_string(v128_t *x);
 
-octet_t
-nibble_to_hex_char(octet_t nibble);
+void v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
 
-char *
-char_to_hex_string(char *x, int num_char);
+void v128_left_shift(v128_t *x, int shift_index);
 
-octet_t
-hex_string_to_octet(char *s);
-
-/*
- * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal
- * string at *hex (of length len octets) to the equivalent raw data
- * and writes it to *raw.
- *
- * if a character in the hex string that is not a hexadeciaml digit
- * (0123456789abcdefABCDEF) is encountered, the function stops writing
- * data to *raw
- *
- * the number of hex digits copied (which is two times the number of
- * octets in *raw) is returned
- */
-
-int
-hex_string_to_octet_string(char *raw, char *hex, int len);
-
-v128_t
-hex_string_to_v128(char *s);
-
-void
-v128_copy_octet_string(v128_t *x, const octet_t s[16]);
-
-void
-v128_left_shift(v128_t *x, int index);
-
-void
-v128_right_shift(v128_t *x, int 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! */
@@ -234,145 +188,191 @@
    really care which bit is which.  AES does care which bit is which, but
    doesn't use the 128-bit get/set or 128-bit shifts  */
 
-#define _v128_get_bit(x, bit)                     \
-(                                                 \
-  ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1)  \
-)
+#define _v128_get_bit(x, bit) (((((x)->v32[(bit) >> 5]) >> ((bit)&31)) & 1))
 
-#define _v128_set_bit(x, bit)                                    \
-(                                                                \
-  (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \
-)
+#define _v128_set_bit(x, bit)                                                  \
+    ((((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit)&31))))
 
-#define _v128_clear_bit(x, bit)                                   \
-(                                                                 \
-  (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \
-)
+#define _v128_clear_bit(x, bit)                                                \
+    ((((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit)&31))))
 
-#define _v128_set_bit_to(x, bit, value)   \
-(                                         \
-   (value) ? _v128_set_bit(x, bit) :      \
-             _v128_clear_bit(x, bit)      \
-)
+#define _v128_set_bit_to(x, bit, value)                                        \
+    ((value) ? _v128_set_bit(x, bit) : _v128_clear_bit(x, bit))
 
+#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
 
-#if 0
-/* nothing uses this */
-#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 /* 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
+ * srtp_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(octet_t *a, octet_t *b, int len);
+int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
 
-void
-octet_string_set_to_zero(octet_t *s, 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);
 
+/*
+ * 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);
 
-/* 
- * bswap_32() is an optimized version of htonl/ntohl
+#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)
+#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 /* 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;
+}
+#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  /* 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 /* WORDS_BIGENDIAN */
+
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * 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.
+ *
  */
 
-uint32_t
-bswap_32(uint32_t v);
+#define bits_per_word 32
+#define bytes_per_word 4
 
-uint64_t
-bswap_64(uint64_t v);
+typedef struct {
+    uint32_t length;
+    uint32_t *word;
+} bitvector_t;
 
+#define _bitvector_get_bit(v, bit_index)                                       \
+    (((((v)->word[((bit_index) >> 5)]) >> ((bit_index)&31)) & 1))
 
-#endif /* _DATATYPES_H */
+#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_get_length(v) (((v)->length))
+
+#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);
+
+void bitvector_set_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);
+
+#endif
+
+int bitvector_alloc(bitvector_t *v, unsigned long length);
+
+void bitvector_dealloc(bitvector_t *v);
+
+void bitvector_set_to_zero(bitvector_t *x);
+
+void bitvector_left_shift(bitvector_t *x, int index);
+
+char *bitvector_bit_string(bitvector_t *x, char *buf, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DATATYPES_H */
diff --git a/crypto/include/err.h b/crypto/include/err.h
index c5b6127..66a1023 100644
--- a/crypto/include/err.h
+++ b/crypto/include/err.h
@@ -1,32 +1,32 @@
 /*
  * err.h
- * 
+ *
  * error status codes
  *
  * David A. 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
@@ -42,152 +42,93 @@
  *
  */
 
-
 #ifndef ERR_H
 #define ERR_H
 
-#include "config.h"             /* check for ERR_REPORTING_SYSLOG */
-
 #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;
-
 /**
  * @}
  */
 
-#if (ERR_REPORTING_SYSLOG) 
-
-#include <syslog.h>
-
 typedef enum {
-  err_level_emergency = LOG_EMERG,
-  err_level_alert     = LOG_ALERT,  
-  err_level_critical  = LOG_CRIT,  
-  err_level_error     = LOG_ERR,  
-  err_level_warning   = LOG_WARNING,
-  err_level_notice    = LOG_NOTICE,  
-  err_level_info      = LOG_INFO,  
-  err_level_debug     = LOG_DEBUG,  
-  err_level_none
-} err_reporting_level_t;
-
-#else
-
-typedef enum {
-  err_level_emergency, 
-  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;
-
-#endif
+    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);
-  
-/*
- * 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, ...);
+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);
 
 /*
- * debug_module_t defines a debug module 
+ * 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.
+ *
  */
 
-typedef struct { 
-  unsigned int   on;          /* 1 if debugging is on, 0 if it is off */
-  char *name;                 /* printable name for debug module      */
-} debug_module_t;
+void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...);
 
-#if ENABLE_DEBUGGING 
+/*
+ * debug_module_t defines a debug module
+ */
 
-#define debug_on(mod)  (mod).on = 1
+typedef struct {
+    int on;           /* 1 if debugging is on, 0 if it is off */
+    const char *name; /* printable name for debug module      */
+} srtp_debug_module_t;
 
-#define debug_off(mod) (mod).on = 0
+#ifdef ENABLE_DEBUG_LOGGING
 
-/* use err_report() to report debug message */
-#define debug_print(mod, format, arg)                  \
-  if (mod.on) err_report(err_level_debug, ("%s: " format), mod.name, arg)
-#define debug_print2(mod, format, arg1,arg2)                  \
-  if (mod.on) err_report(err_level_debug, ("%s: " format), 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_print(mod, format, arg)                                          \
+    if (mod.on)                                                                \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg)
+#define debug_print2(mod, format, arg1, arg2)                                  \
+    if (mod.on)                                                                \
+    srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name,      \
+                    arg1, arg2)
 
-#define debug_on(mod)  
+#endif
 
-#define debug_off(mod) 
-
+#ifdef __cplusplus
+}
 #endif
 
 #endif /* ERR_H */
diff --git a/crypto/include/gf2_8.h b/crypto/include/gf2_8.h
deleted file mode 100644
index ee08da6..0000000
--- a/crypto/include/gf2_8.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * gf2_8.h
- *
- * GF(256) implementation
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef GF2_8_H
-#define GF2_8_H
-
-#include "datatypes.h"  /* for octet_t definition */
-
-typedef octet_t gf2_8;
-
-#define gf2_8_field_polynomial 0x1B
-
-/*
- * gf2_8_shift(x) returns the next gf2_8 value in the cyclic
- * representation of that field
- */
-
-gf2_8
-gf2_8_shift(octet_t input);
-
-gf2_8
-gf2_8_compute_inverse(gf2_8 x);
-
-void
-test_gf2_8(void);
-
-gf2_8
-gf2_8_multiply(gf2_8 x, gf2_8 y);
-
-#endif /* GF2_8_H */
diff --git a/crypto/include/hmac.h b/crypto/include/hmac.h
index 569a175..1488181 100644
--- a/crypto/include/hmac.h
+++ b/crypto/include/hmac.h
@@ -1,33 +1,33 @@
 /*
  * hmac.h
  *
- * interface to hmac auth_type_t
+ * interface to hmac srtp_auth_type_t
  *
  * David A. McGrew
  * Cisco Systems, Inc.
  *
  */
 /*
- *	
- * Copyright (c) 2001-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
@@ -50,28 +50,9 @@
 #include "sha1.h"
 
 typedef struct {
-  octet_t    ipad[64], opad[64];
-  sha1_ctx_t 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 octet_t *key, int key_len);
-
-err_status_t
-hmac_start(hmac_ctx_t *state);
-
-err_status_t
-hmac_update(hmac_ctx_t *state, const octet_t *message, int msg_octets);
-
-err_status_t
-hmac_compute(hmac_ctx_t *state, const octet_t *message,
-	     int msg_octets, int tag_len, octet_t *result);
-
+    uint8_t opad[64];
+    srtp_sha1_ctx_t ctx;
+    srtp_sha1_ctx_t init_ctx;
+} srtp_hmac_ctx_t;
 
 #endif /* HMAC_H */
diff --git a/crypto/include/integers.h b/crypto/include/integers.h
index 5e3dada..f2cd7c0 100644
--- a/crypto/include/integers.h
+++ b/crypto/include/integers.h
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,104 +43,104 @@
  *
  */
 
-
 #ifndef INTEGERS_H
 #define INTEGERS_H
 
-#include "config.h"       /* configuration file, using autoconf          */
-
-#include <stdlib.h>       /* standard integers should be referenced here */
-
-
 /* use standard integer definitions, if they're available  */
-#if HAVE_STDINT_H 
-
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STDINT_H
 #include <stdint.h>
-
-#elif HAVE_SYS_INT_TYPES_H  
-
-#include <sys/int_types.h>    /* this exists on Sun OS */
-
-#elif (HAVE_MACHINE_TYPES_H && !HAVE_MS_TYPES) /* Open BSD, not Cygwin */
-
+#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_INT_TYPES_H
+#include <sys/int_types.h> /* this exists on Sun OS */
+#endif
+#ifdef HAVE_MACHINE_TYPES_H
 #include <machine/types.h>
+#endif
 
-#else  /* if all else fails, use these definitions */
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-/*
- * machine-specific definitions for 32 bit machines - you may need to
- * edit these definitions for your own machine
- */
+/* 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
+#endif
 
-typedef unsigned short int     uint16_t;
-typedef unsigned int           uint32_t;
-#ifdef NO_64BIT_MATH
+/* 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;
+#endif
+#ifndef HAVE_UINT16_T
+typedef unsigned short int uint16_t;
+#endif
+#ifndef HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+#ifndef HAVE_INT32_T
+typedef int int32_t;
+#endif
+
+#if defined(NO_64BIT_MATH) && defined(HAVE_CONFIG_H)
 typedef double uint64_t;
 /* assert that sizeof(double) == 8 */
-#else
-typedef unsigned long long int uint64_t;
-#endif
-
-/* 
- * if we're on MS, avoid re-defining the following mirosoft types - *
- * these are present in cygwin
- */
-
-#if (HAVE_MS_TYPES == 0)
-
-typedef short int     int16_t;
-typedef int           int32_t;
-#ifdef NO_64BIT_MATH
-typedef double int64_t;
-/* assert that sizeof(double) == 8 */
-#else
-typedef long long int int64_t;
-#endif
-
-#else
-
-#include <sys/types.h>  /* pick up cygwin definitions */
-
-#endif
-
+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
 
 /* 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. */
-#if ALIGNMENT_32BIT_REQUIRED
-// Note that if it's in a variable, you can memcpy it
-#if WORDS_BIGENDIAN == 1
-#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; \
+#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 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
 
-#include <sys/types.h>
-#include <netinet/in.h>
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* INTEGERS_H */
diff --git a/crypto/include/key.h b/crypto/include/key.h
index 05a0669..3498114 100644
--- a/crypto/include/key.h
+++ b/crypto/include/key.h
@@ -2,31 +2,31 @@
  * key.h
  *
  * key usage limits enforcement
- * 
+ *
  * David A. 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
@@ -45,38 +45,44 @@
 #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, xtd_seq_num_t s);
+srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key,
+                                     const srtp_xtd_seq_num_t s);
 
-err_status_t
-key_limit_clone(key_limit_t original, key_limit_t *new_key);
+srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original,
+                                       srtp_key_limit_t *new_key);
 
-err_status_t
-key_limit_check(const key_limit_t key);
+srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key);
 
-key_event_t
-key_limit_update(key_limit_t key);
+srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key);
 
-typedef enum { 
-   key_state_normal,
-   key_state_past_soft_limit,
-   key_state_expired
-} key_state_t;
+typedef enum {
+    srtp_key_state_normal,
+    srtp_key_state_past_soft_limit,
+    srtp_key_state_expired
+} srtp_key_state_t;
 
-typedef struct key_limit_ctx_t {
-  xtd_seq_num_t num_left;
-  key_state_t   state;
-} key_limit_ctx_t;
+typedef struct srtp_key_limit_ctx_t {
+    srtp_xtd_seq_num_t num_left;
+    srtp_key_state_t state;
+} srtp_key_limit_ctx_t;
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* KEY_H */
diff --git a/crypto/include/math.h b/crypto/include/math.h
deleted file mode 100644
index 55ed775..0000000
--- a/crypto/include/math.h
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * math.h
- *
- * crypto math operations and data types
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright (c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef MATH_H
-#define MATH_H
-
-#include "datatypes.h"
-
-inline int
-octet_get_weight(octet_t octet);
-
-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 *
-octet_bit_string(octet_t x);
-
-char *
-v16_bit_string(v16_t x);
-
-char *
-v32_bit_string(v32_t x);
-
-char *
-v64_bit_string(v64_t x);
-
-char *
-v128_bit_string(v128_t x);
-
-octet_t
-nibble_to_hex_char(octet_t nibble);
-
-char *
-octet_hex_string(octet_t x);
-
-char *
-octet_string_hex_string(const octet_t *str, int length);
-
-char *
-v16_hex_string(v16_t x);
-
-char *
-v32_hex_string(v32_t x);
-
-char *
-v64_hex_string(v64_t x);
-
-char *
-v128_hex_string(v128_t x);
-
-char *
-char_to_hex_string(char *x, int num_char);
-
-int
-hex_char_to_nibble(octet_t c);
-
-int
-is_hex_string(char *s);
-
-octet_t
-hex_string_to_octet(char *s);
-
-/*
- * 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); 
-
-v16_t
-hex_string_to_v16(char *s);
-
-v32_t
-hex_string_to_v32(char *s);
-
-v64_t
-hex_string_to_v64(char *s);
-
-v128_t
-hex_string_to_v128(char *s);
-
-/* the matrix A[] is stored in column format, i.e., A[i] is
-   the ith column of the matrix */
-
-octet_t 
-A_times_x_plus_b(octet_t A[8], octet_t x, octet_t b);
-
-void
-v16_copy_octet_string(v16_t *x, const octet_t s[2]);
-
-void
-v32_copy_octet_string(v32_t *x, const octet_t s[4]);
-
-void
-v64_copy_octet_string(v64_t *x, const octet_t s[8]);
-
-void
-v128_copy_octet_string(v128_t *x, const octet_t s[16]);
-
-void
-v128_add(v128_t *z, v128_t *x, v128_t *y);
-
-int
-octet_string_is_eq(octet_t *a, octet_t *b, int len);
-
-void
-octet_string_set_to_zero(octet_t *s, int len);
-
-
-
-/* 
- * the matrix A[] is stored in column format, i.e., A[i] is the ith
- * column of the matrix
-*/
-octet_t 
-A_times_x_plus_b(octet_t A[8], octet_t x, octet_t b);
-
-void
-v128_copy_octet_string(v128_t *x, const octet_t s[16]);
-
-void
-v128_left_shift(v128_t *x, int index);
-
-void
-v128_right_shift(v128_t *x, int 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_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_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_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_is_eq(x, y)                                        \
-  (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
-
-
-#define _v128_xor_eq(z, x)         \
-(                                  \
-   (z)->v64[0] ^= (x)->v64[0],     \
-   (z)->v64[1] ^= (x)->v64[1]      \
-)
-
-
-#define _v128_get_bit(x, bit)                     \
-(                                                 \
-   (x->v32[3-((bit) >> 5)] >> ((bit) & 31)) & 1       \
-)
-
-#define _v128_set_bit(x, bit)                                    \
-(                                                                \
-  (((x)->v32[3-((bit) >> 5)]) |= ((uint32_t)1 << ((bit) & 31))) \
-)
-
-#define _v128_clear_bit(x, bit)                                   \
-(                                                                 \
-  (((x)->v32[(bit) >> 5]) &= ~((unsigned long)1 << ((bit) & 31))) \
-)
-
-#define _v128_set_bit_to(x, bit, value)   \
-(                                         \
-   (value) ? _v128_set_bit(x, bit) :      \
-             _v128_clear_bit(x, bit)      \
-)
-
-
-#if OLD
-
-#define _v128_get_bit(x, bit)                     \
-(                                                 \
-  ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1)  \
-)
-
-#define _v128_set_bit(x, bit)                                    \
-(                                                                \
-  (((x)->v32[(bit) >> 5]) |= ((unsigned long)1 << ((bit) & 31))) \
-)
-
-#define _v128_clear_bit(x, bit)                                   \
-(                                                                 \
-  (((x)->v32[(bit) >> 5]) &= ~((unsigned long)1 << ((bit) & 31))) \
-)
-
-#define _v128_set_bit_to(x, bit, value)   \
-(                                         \
-   (value) ? _v128_set_bit(x, bit) :      \
-             _v128_clear_bit(x, bit)      \
-)
-
-#endif /* OLD */
-
-#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 */                      
-
-
-#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(octet_t *a, octet_t *b, int len);
-
-void
-octet_string_set_to_zero(octet_t *s, int len);
-
-
-/*
- * functions manipulating bit_vector_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 bytes_per_word 4
-
-typedef struct {
-  uint32_t length;   
-  uint32_t *word;
-} bitvector_t;
-
-#include <stdio.h>
-
-int
-bitvector_alloc(bitvector_t *v, unsigned long length);
-
-void
-bitvector_set_bit(bitvector_t *v, int bit_index);
-
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index);
-
-int
-bitvector_print_hex(const bitvector_t *v, FILE *stream);
-
-int
-bitvector_set_from_hex(bitvector_t *v, char *string);
-
-#endif /* MATH_H */
-
-
-
diff --git a/crypto/include/null_auth.h b/crypto/include/null_auth.h
index adb6052..490dd7b 100644
--- a/crypto/include/null_auth.h
+++ b/crypto/include/null_auth.h
@@ -7,26 +7,26 @@
  */
 
 /*
- *	
- * 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
@@ -47,22 +47,27 @@
 
 #include "auth.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct {
-	char foo;
-} null_auth_ctx_t;
+    char foo;
+} srtp_null_auth_ctx_t;
 
-err_status_t
-null_auth_alloc(auth_t **a, int key_len, int out_len);
+#if 0
+srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a, int key_len, int out_len);
 
-err_status_t
-null_auth_dealloc(auth_t *a);
+srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a);
 
-err_status_t
-null_auth_init(null_auth_ctx_t *state, const octet_t *key, int key_len);
+srtp_err_status_t srtp_null_auth_init(srtp_null_auth_ctx_t *state, const uint8_t *key, int key_len);
 
-err_status_t
-null_auth_compute (null_auth_ctx_t *state, octet_t *message,
-		   int msg_octets, int tag_len, octet_t *result);
+srtp_err_status_t srtp_null_auth_compute(srtp_null_auth_ctx_t *state, uint8_t *message, int msg_octets, int tag_len, uint8_t *result);
 
+#endif
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* NULL_AUTH_H */
diff --git a/crypto/include/null_cipher.h b/crypto/include/null_cipher.h
index cfbefe9..5e8c91c 100644
--- a/crypto/include/null_cipher.h
+++ b/crypto/include/null_cipher.h
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -44,7 +44,6 @@
  *
  */
 
-
 #ifndef NULL_CIPHER_H
 #define NULL_CIPHER_H
 
@@ -52,29 +51,7 @@
 #include "cipher.h"
 
 typedef struct {
-  char foo ;/* empty, for now */
-} null_cipher_ctx_t;
-
-
-/*
- * none of these functions do anything (though future versions may keep
- * track of bytes encrypted, number of instances, and/or other info).
- */
-
-err_status_t
-null_cipher_init(null_cipher_ctx_t *c, const octet_t *key);
-
-err_status_t
-null_cipher_set_segment(null_cipher_ctx_t *c,
-			unsigned long 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 */
diff --git a/crypto/include/prng.h b/crypto/include/prng.h
deleted file mode 100644
index 25a06af..0000000
--- a/crypto/include/prng.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * prng.h
- *
- * pseudorandom source
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-#ifndef PRNG_H
-#define PRNG_H
-
-#ifndef CLOCKS_PER_SEC
-#include <time.h>         /* for time()                              */
-#endif
-
-#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();
-
-err_status_t
-x917_prng_get_octet_string(octet_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();
-
-err_status_t
-ctr_prng_get_octet_string(void *dest, int len);
-
-
-#endif
diff --git a/crypto/include/rand_source.h b/crypto/include/rand_source.h
deleted file mode 100644
index 575a2bc..0000000
--- a/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-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef RAND_SOURCE
-#define RAND_SOURCE
-
-#include "err.h"
-#include "datatypes.h"
-
-err_status_t
-rand_source_init();
-
-/*
- * 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, int length);
-
-err_status_t
-rand_source_deinit();
-
-/* 
- * 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, int num_octets);
-
-#endif /* RAND_SOURCE */
diff --git a/crypto/include/rdb.h b/crypto/include/rdb.h
new file mode 100644
index 0000000..98314c1
--- /dev/null
+++ b/crypto/include/rdb.h
@@ -0,0 +1,125 @@
+/*
+ * replay-database.h
+ *
+ * interface for a replay database for packet security
+ *
+ * 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.
+ *
+ */
+
+#ifndef REPLAY_DB_H
+#define REPLAY_DB_H
+
+#include "integers.h"  /* for uint32_t     */
+#include "datatypes.h" /* for v128_t       */
+#include "err.h"       /* for srtp_err_status_t */
+
+#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;
+} srtp_rdb_t;
+
+#define rdb_bits_in_bitmask (8 * sizeof(v128_t))
+
+/*
+ * srtp_rdb_init
+ *
+ * initalizes rdb
+ *
+ * returns srtp_err_status_ok on success, srtp_err_status_t_fail otherwise
+ */
+srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb);
+
+/*
+ * srtp_rdb_check
+ *
+ * checks to see if index appears in rdb
+ *
+ * returns srtp_err_status_fail if the index already appears in rdb,
+ * returns srtp_err_status_ok otherwise
+ */
+srtp_err_status_t srtp_rdb_check(const srtp_rdb_t *rdb, uint32_t rdb_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
+ *
+ */
+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!
+ */
+
+/*
+ * srtp_rdb_increment(db) increments the sequence number in db, if it is
+ * not too high
+ *
+ * return values:
+ *
+ *    srtp_err_status_ok            no problem
+ *    srtp_err_status_key_expired   sequence number too high
+ *
+ */
+srtp_err_status_t srtp_rdb_increment(srtp_rdb_t *rdb);
+
+/*
+ * srtp_rdb_get_value(db) returns the current sequence number of db
+ */
+uint32_t srtp_rdb_get_value(const srtp_rdb_t *rdb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* REPLAY_DB_H */
diff --git a/crypto/include/rdbx.h b/crypto/include/rdbx.h
index ce9ecf6..2194178 100644
--- a/crypto/include/rdbx.h
+++ b/crypto/include/rdbx.h
@@ -8,139 +8,202 @@
  *
  */
 
+/*
+ *
+ * Copyright (c) 2001-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
 #ifndef RDBX_H
 #define RDBX_H
 
 #include "datatypes.h"
 #include "err.h"
 
-/* #define ROC_TEST */  
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* #define ROC_TEST */
 
 #ifndef ROC_TEST
 
-typedef uint16_t sequence_number_t;   /* 16 bit sequence number  */
-typedef uint32_t rollover_counter_t;   /* 32 bit rollover counter */
+typedef uint16_t srtp_sequence_number_t;  /* 16 bit sequence number  */
+typedef uint32_t srtp_rollover_counter_t; /* 32 bit rollover counter */
 
-#else  /* use small seq_num and roc datatypes for testing purposes */
+#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;
-  v128_t bitmask;
-} rdbx_t;
-
+    srtp_xtd_seq_num_t index;
+    bitvector_t bitmask;
+} srtp_rdbx_t;
 
 /*
- * rdbx_init(rdbx_ptr)
+ * srtp_rdbx_init(rdbx_ptr, ws)
  *
- * initializes the rdbx pointed to by its argument, setting the
- * rollover counter and sequence number to zero
+ * 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);
-
+srtp_err_status_t srtp_rdbx_init(srtp_rdbx_t *rdbx, unsigned long ws);
 
 /*
- * rdbx_estimate_index(rdbx, guess, s)
- * 
+ * srtp_rdbx_dealloc(rdbx_ptr)
+ *
+ * frees memory associated with the rdbx
+ */
+srtp_err_status_t srtp_rdbx_dealloc(srtp_rdbx_t *rdbx);
+
+/*
+ * 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);
 
 /*
- * xtd_seq_num_t functions - these are *internal* functions of rdbx, and
+ * 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
+ * srtp_err_status_replay_old; otherwise, srtp_err_status_ok is returned.
+ *
+ */
+srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc);
+
+/*
+ * srtp_rdbx_get_packet_index(rdbx) returns the value of the rollover counter
+ * for
+ * the srtp_rdbx_t pointed to by rdbx
+ *
+ */
+srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx);
+
+/*
+ * srtp_xtd_seq_num_t functions - these are *internal* functions of rdbx, and
  * shouldn't be used to manipulate rdbx internal values.  use the rdbx
  * api instead!
  */
 
+/*
+ * srtp_rdbx_get_ws(rdbx_ptr)
+ *
+ * gets the window size which was used to initialize the 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 */
-
-
-
-
-
-
-
-
-
diff --git a/crypto/include/sha1.h b/crypto/include/sha1.h
index 2f508cb..933c146 100644
--- a/crypto/include/sha1.h
+++ b/crypto/include/sha1.h
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -47,63 +47,138 @@
 #ifndef SHA1_H
 #define SHA1_H
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "err.h"
+#ifdef OPENSSL
+#include <openssl/evp.h>
+#include <stdint.h>
+#else
 #include "datatypes.h"
+#endif
 
-typedef 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;
+#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
- * 
- */
-
-void
-sha1(const octet_t *message,  int octets_in_msg, uint32_t output[5]);
-
-/*
- * sha1_init(&ctx) initializes the SHA1 context ctx
- * 
- * sha1_update(&ctx, msg, len) hashes the len octets starting at msg
+ * srtp_sha1_init(&ctx) initializes the SHA1 context ctx
+ *
+ * srtp_sha1_update(&ctx, msg, len) hashes the len octets starting at msg
  * into the SHA1 context
- * 
- * sha1_final(&ctx, output) performs the final processing of the SHA1
+ *
+ * srtp_sha1_final(&ctx, output) performs the final processing of the SHA1
  * context and writes the result to the 20 octets at output
  *
+ * Return values are ignored on the EVP functions since all three
+ * of these functions return void.
+ *
  */
 
-void
-sha1_init(sha1_ctx_t *ctx);
+/* OpenSSL 1.1.0 made EVP_MD_CTX an opaque structure, which must be allocated
+   using EVP_MD_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || LIBRESSL_VERSION_NUMBER
 
-void
-sha1_update(sha1_ctx_t *ctx, const octet_t *M, int octets_in_msg);
+typedef EVP_MD_CTX srtp_sha1_ctx_t;
 
-void
-sha1_final(sha1_ctx_t *ctx, uint32_t output[5]);
+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;
 
 /*
- * The sha1_core function is INTERNAL to SHA-1, but it is declared
+ * 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
+ *
+ */
+void srtp_sha1_init(srtp_sha1_ctx_t *ctx);
+
+void srtp_sha1_update(srtp_sha1_ctx_t *ctx,
+                      const uint8_t *M,
+                      int octets_in_msg);
+
+void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t output[5]);
+
+/*
+ * 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 */
diff --git a/crypto/include/stat.h b/crypto/include/stat.h
index 6d5e4a4..1894e04 100644
--- a/crypto/include/stat.h
+++ b/crypto/include/stat.h
@@ -1,6 +1,6 @@
 /*
  * stats.h
- * 
+ *
  * interface to statistical test functions
  *
  * David A. McGrew
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,24 +43,24 @@
  *
  */
 
-
 #ifndef STAT_H
 #define STAT_H
 
-#include "datatypes.h"       /* for octet_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(octet_t *data);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-err_status_t
-stat_test_poker(octet_t *data);
+srtp_err_status_t stat_test_monobit(uint8_t *data);
 
-err_status_t
-stat_test_runs(octet_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);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* STAT_H */
diff --git a/crypto/include/xfm.h b/crypto/include/xfm.h
deleted file mode 100644
index 4d5449e..0000000
--- a/crypto/include/xfm.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * xfm.h
- *
- * interface for abstract crypto transform
- * 
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-#ifndef XFM_H
-#define XFM_H
-
-#include "crypto_kernel.h"
-#include "err.h"
-
-/**
- * @defgroup Crypto Cryptography
- *
- * A simple interface to an abstract cryptographic transform that
- * provides both confidentiality and message authentication.
- *
- * @{
- */
-
-/**
- * @brief applies a crypto transform
- *
- * The function pointer xfm_func_t points to a function that
- * implements a crypto transform, and provides a uniform API for
- * accessing crypto mechanisms.
- * 
- * @param key       location of secret key                  
- *
- * @param clear     data to be authenticated only           
- *
- * @param clear_len length of data to be authenticated only 
- *
- * @param iv        location to write the Initialization Vector (IV)
- *
- * @param protected 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 *opaque,         
-      unsigned *opaque_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 */
-
-
diff --git a/crypto/kernel/alloc.c b/crypto/kernel/alloc.c
index d09910b..dbe5826 100644
--- a/crypto/kernel/alloc.c
+++ b/crypto/kernel/alloc.c
@@ -1,32 +1,32 @@
 /*
  * alloc.c
  *
- * memory allocation and deallocation 
+ * memory allocation and deallocation
  *
  * David A. 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
@@ -42,51 +42,60 @@
  *
  */
 
+#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 srtp_mod_alloc = {
+    0,      /* debugging is off by default */
+    "alloc" /* printable name for module   */
 };
 
-#if HAVE_STDLIB_H
-
 /*
- * 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.
  */
 
-void *
-crypto_alloc(size_t size) {
-  void *ptr;
+#if defined(HAVE_STDLIB_H)
 
-  ptr = malloc(size);
-    
-  if (ptr) {
-    debug_print(mod_alloc, "(location: %p) allocated", ptr);
-  } else
-    debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
-    
-  return ptr;
+void *srtp_crypto_alloc(size_t size)
+{
+    void *ptr;
+
+    if (!size) {
+        return NULL;
+    }
+
+    ptr = calloc(1, size);
+
+    if (ptr) {
+        debug_print(srtp_mod_alloc, "(location: %p) allocated", ptr);
+    } else {
+        debug_print(srtp_mod_alloc, "allocation failed (asked for %d bytes)\n",
+                    size);
+    }
+
+    return ptr;
 }
 
-void 
-crypto_free(void *ptr) {
+void srtp_crypto_free(void *ptr)
+{
+    debug_print(srtp_mod_alloc, "(location: %p) freed", ptr);
 
-  debug_print(mod_alloc, "(location: %p) freed", ptr);
-
-  free(ptr);
+    free(ptr);
 }
 
-#else  /* we need to define our own memory allocation routines */
+#else /* we need to define our own memory allocation routines */
 
-#error no memory allocation defined yet 
+#error no memory allocation defined yet
 
 #endif
diff --git a/crypto/kernel/crypto_kernel.c b/crypto/kernel/crypto_kernel.c
index 82b4aca..df6af7d 100644
--- a/crypto/kernel/crypto_kernel.c
+++ b/crypto/kernel/crypto_kernel.c
@@ -7,26 +7,26 @@
  * 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
@@ -42,456 +42,520 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <stdio.h>      /* printf() is used in crypto_kernel_status() */
 #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        */
 };
 
-err_status_t
-crypto_kernel_init() {
-  err_status_t status;  
+#define MAX_RNG_TRIALS 25
 
-  /* initialize error reporting system */
-  status = err_reporting_init("crypto");
-  if (status)
-    return status;
+srtp_err_status_t srtp_crypto_kernel_init()
+{
+    srtp_err_status_t 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;
+    /* 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();
+    }
 
-  /* run FIPS-140 statistical tests on rand_source */  
-  status = stat_test_rand_source(rand_source_get_octet_string);
-  if (status)
-    return status;
-
-  /* initialize pseudorandom number generator */
-  status = ctr_prng_init(rand_source_get_octet_string);
-  if (status)
-    return status;
-
-  /* run FIPS-140 statistical tests on ctr_prng */  
-  status = stat_test_rand_source(ctr_prng_get_octet_string);
-  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_128_ICM);
-  if (status) 
-    return status;
-  status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC);
-  if (status) 
-    return status;
-
-  /* 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;
-}
-
-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;
-
-  /* run FIPS-140 statistical tests on rand_source */  
-  printf("testing rand_source...");
-  status = stat_test_rand_source(rand_source_get_octet_string);
-  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);
+    /* initialize error reporting system */
+    status = srtp_err_reporting_init();
     if (status) {
-      printf("failed with error code %d\n", status);
-      exit(status);
+        return status;
     }
-    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);
+
+    /* load debug modules */
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_crypto_kernel);
     if (status) {
-      printf("failed with error code %d\n", status);
-      exit(status);
+        return status;
     }
-    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;
-  }
-
-  return err_status_ok;
-}
-
-err_status_t
-crypto_kernel_list_debug_modules() {
-  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;
-  }
-
-  return err_status_ok;
-}
-
-err_status_t
-crypto_kernel_shutdown() {
-  err_status_t status;
-  kernel_cipher_type_t *ctype, *next;
-
-  /*
-   * free dynamic memory used in crypto_kernel at present
-   */
-
-  /* walk down cipher type list, freeing memory */
-  ctype = crypto_kernel.cipher_type_list;
-  while (ctype != NULL) {
-    next = ctype->next;
-    debug_print(mod_crypto_kernel, 
-		"freeing memory for cipher %s", 
-		ctype->cipher_type->description);
-    crypto_free(ctype);
-    ctype = next;
-  }
-
-  /* de-initialize random number generator */
-  status = rand_source_deinit();
-  if (status)
-    return status;
-
-  /* return to insecure state */
-  crypto_kernel.state = crypto_kernel_state_insecure;
-  
-  return err_status_ok;
-}
-
-err_status_t
-crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
-  kernel_cipher_type_t *ctype, *new;
-  err_status_t status;
-
-  /* defensive coding */
-  if (new_ct == NULL)
-    return err_status_bad_param;
-
-  /* check cipher type by running self-test */
-  status = cipher_type_self_test(new_ct);
-  if (status) {
-    return status;
-  }
-
-  /* walk down list, checking if this type is in the list already  */
-  ctype = crypto_kernel.cipher_type_list;
-  while (ctype != NULL) {
-    if ((new_ct == ctype->cipher_type) || (id == ctype->id))
-      return err_status_bad_param;    
-    ctype = ctype->next;
-  }
-
-  /* put new_ct at the head of the list */
-  /* allocate memory */
-  new = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
-  if (new == NULL)
-    return err_status_alloc_fail;
-    
-  /* set fields */
-  new->cipher_type = new_ct;
-  new->id = id;
-  new->next = crypto_kernel.cipher_type_list;
-
-  /* set head of list to new cipher type */
-  crypto_kernel.cipher_type_list = new;    
-
-  /* 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 */
-
-  return err_status_ok;
-}
-
-err_status_t
-crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
-  kernel_auth_type_t *atype, *new;
-  err_status_t status;
-
-  /* defensive coding */
-  if (new_at == NULL)
-    return err_status_bad_param;
-
-  /* check auth type by running self-test */
-  status = auth_type_self_test(new_at);
-  if (status) {
-    return status;
-  }
-
-  /* walk down list, checking if this type is in the list already  */
-  atype = crypto_kernel.auth_type_list;
-  while (atype != NULL) {
-    if ((new_at == atype->auth_type) || (id == atype->id))
-      return err_status_bad_param;    
-    atype = atype->next;
-  }
-
-  /* put new_at at the head of the list */
-  /* allocate memory */
-  new = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
-  if (new == NULL)
-    return err_status_alloc_fail;
-    
-  /* set fields */
-  new->auth_type = new_at;
-  new->id = id;
-  new->next = crypto_kernel.auth_type_list;
-
-  /* set head of list to new auth type */
-  crypto_kernel.auth_type_list = new;    
-
-  /* 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 */
-
-  return err_status_ok;
-
-}
-
-
-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;
-  } 
-
-  /* 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;
-
-  /* 
-   * 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;
-
-  ct = crypto_kernel_get_cipher_type(id);
-  if (!ct)
-    return err_status_fail;
-  
-  return ((ct)->alloc(cp, key_len));
-}
-
-
-
-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;
-  } 
-
-  /* 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;
-
-  /* 
-   * 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;
-
-  at = crypto_kernel_get_auth_type(id);
-  if (!at)
-    return err_status_fail;
-  
-  return ((at)->alloc(ap, key_len, tag_len));
-}
-
-#include <string.h>   /* for strncmp() */
-
-err_status_t
-crypto_kernel_load_debug_module(debug_module_t *new_dm) {
-  kernel_debug_module_t *kdm, *new;
-
-  /* defensive coding */
-  if (new_dm == NULL)
-    return 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;
-  }
-
-  /* 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;
-
-  /* set head of list to new cipher type */
-  crypto_kernel.debug_module_list = new;    
-
-  return 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;
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_auth);
+    if (status) {
+        return status;
     }
-    kdm = kdm->next;
-  }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_cipher);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_stat);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_alloc);
+    if (status) {
+        return status;
+    }
 
-  return err_status_fail;
+    /* 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 GCM
+    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,
+                                                 SRTP_AES_GCM_128);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256,
+                                                 SRTP_AES_GCM_256);
+    if (status) {
+        return status;
+    }
+    status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_gcm);
+    if (status) {
+        return status;
+    }
+#endif
+
+    /* 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;
+    }
+
+    /* change state to secure */
+    crypto_kernel.state = srtp_crypto_kernel_state_secure;
+
+    return srtp_err_status_ok;
 }
 
-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;
+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;
+
+    /* 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;
+    }
+
+    /* 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;
+    }
+
+    srtp_crypto_kernel_list_debug_modules();
+
+    return srtp_err_status_ok;
+}
+
+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 */
+    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 srtp_err_status_ok;
+}
+
+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) {
+        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) {
+        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) {
+        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);
+    }
+
+    /* return to insecure state */
+    crypto_kernel.state = srtp_crypto_kernel_state_insecure;
+
+    return srtp_err_status_ok;
+}
+
+static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type(
+    const srtp_cipher_type_t *new_ct,
+    srtp_cipher_type_id_t id,
+    int replace)
+{
+    srtp_kernel_cipher_type_t *ctype, *new_ctype;
+    srtp_err_status_t status;
+
+    /* defensive coding */
+    if (new_ct == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    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;
+    }
+
+    /* 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;
+    }
+
+    /* 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;
+
+        /* 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;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
+    const srtp_cipher_type_t *new_ct,
+    srtp_cipher_type_id_t id)
+{
+    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);
+}
+
+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;
+
+    /* defensive coding */
+    if (new_at == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    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;
+    }
+
+    /* 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;
+    }
+
+    /* 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;
+        }
+
+        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;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_crypto_kernel_load_auth_type(
+    const srtp_auth_type_t *new_at,
+    srtp_auth_type_id_t id)
+{
+    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;
+
+    /* 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;
+}
+
+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 != srtp_crypto_kernel_state_secure) {
+        return srtp_err_status_init_fail;
+    }
+
+    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;
+
+    /* 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;
+}
+
+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 != srtp_crypto_kernel_state_secure) {
+        return srtp_err_status_init_fail;
+    }
+
+    at = srtp_crypto_kernel_get_auth_type(id);
+    if (!at) {
+        return srtp_err_status_fail;
+    }
+
+    return ((at)->alloc(ap, key_len, tag_len));
+}
+
+srtp_err_status_t srtp_crypto_kernel_load_debug_module(
+    srtp_debug_module_t *new_dm)
+{
+    srtp_kernel_debug_module_t *kdm, *new;
+
+    /* defensive coding */
+    if (new_dm == NULL || new_dm->name == 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 srtp_err_status_bad_param;
+        }
+        kdm = kdm->next;
+    }
+
+    /* 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 fields */
+    new->mod = new_dm;
+    new->next = crypto_kernel.debug_module_list;
+
+    /* set head of list to new cipher type */
+    crypto_kernel.debug_module_list = new;
+
+    return srtp_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;
+    }
+
+    return srtp_err_status_fail;
 }
diff --git a/crypto/kernel/err.c b/crypto/kernel/err.c
index 9710955..9db5bfb 100644
--- a/crypto/kernel/err.c
+++ b/crypto/kernel/err.c
@@ -7,26 +7,26 @@
  * 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
@@ -42,63 +42,67 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "err.h"
+#include "datatypes.h"
+#include <string.h>
 
+/* srtp_err_file is the FILE to which errors are reported */
 
-/*  err_level reflects the level of errors that are reported  */
+static FILE *srtp_err_file = NULL;
 
-err_reporting_level_t err_level = err_level_none;
-
-/* err_file is the FILE to which errors are reported */
-
-FILE *err_file = NULL;
-
-err_status_t
-err_reporting_init(char *ident) {
-#if (ERR_REPORTING_SYSLOG == 1)
-  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...
-   */
-
-#if ERR_REPORTING_STDOUT
-  err_file = stdout;
-#else
-#ifdef ERR_REPORTING_FILE
-  /* open file for error reporting */
-  err_file = fopen(ERR_REPORTING_FILE, "w");
-  if (err_file == NULL)
-    return err_status_init_fail;
-#endif
-#endif
-
-  return err_status_ok;
-}
-
-void
-err_report(int priority, char *format, ...) {
-  va_list args;
-
-  if (priority <= err_level) {
-
-    va_start(args, format);
-    if (err_file != NULL) {
-      vfprintf(err_file, format, args);
-	  /*      fprintf(err_file, "\n"); */
+srtp_err_status_t srtp_err_reporting_init()
+{
+#ifdef ERR_REPORTING_STDOUT
+    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;
     }
-#if (ERR_REPORTING_SYSLOG == 1)
-    vsyslog(priority, format, args);
 #endif
-    va_end(args);
-  }
+
+    return srtp_err_status_ok;
 }
 
-void
-err_reporting_set_level(err_reporting_level_t lvl) { 
-  err_level = lvl;
+static srtp_err_report_handler_func_t *srtp_err_report_handler = NULL;
+
+srtp_err_status_t srtp_install_err_report_handler(
+    srtp_err_report_handler_func_t func)
+{
+    srtp_err_report_handler = func;
+    return srtp_err_status_ok;
 }
 
-
+void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...)
+{
+    char msg[512];
+    va_list args;
+    if (srtp_err_file != NULL) {
+        va_start(args, format);
+        vfprintf(srtp_err_file, format, args);
+        va_end(args);
+    }
+    if (srtp_err_report_handler != NULL) {
+        va_start(args, format);
+        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);
+    }
+}
diff --git a/crypto/kernel/key.c b/crypto/kernel/key.c
index fd75a63..0466195 100644
--- a/crypto/kernel/key.c
+++ b/crypto/kernel/key.c
@@ -2,31 +2,31 @@
  * key.c
  *
  * key usage limits enforcement
- * 
+ *
  * David A. 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
@@ -42,74 +42,81 @@
  *
  */
 
+#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) {
-  if (original == NULL)
-    return err_status_bad_param;
-  *new = 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,lo32(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;
 }
-
diff --git a/crypto/math/datatypes.c b/crypto/math/datatypes.c
index 0da9fe7..001584c 100644
--- a/crypto/math/datatypes.c
+++ b/crypto/math/datatypes.c
@@ -8,26 +8,26 @@
  * 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
@@ -43,50 +43,34 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef OPENSSL
+#include <openssl/crypto.h>
+#endif
+
 #include "datatypes.h"
 
-int 
-octet_weight[256] = {
-  0, 1, 1, 2, 1, 2, 2, 3,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  1, 2, 2, 3, 2, 3, 3, 4,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  2, 3, 3, 4, 3, 4, 4, 5,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  3, 4, 4, 5, 4, 5, 5, 6,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  4, 5, 5, 6, 5, 6, 6, 7,
-  5, 6, 6, 7, 6, 7, 7, 8
+static const int8_t octet_weight[256] = {
+    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
+    2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
+    3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
+    4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
 };
 
-int
-octet_get_weight(octet_t octet) {
-  extern int octet_weight[256];
-
-  return octet_weight[octet];
-}  
+int octet_get_weight(uint8_t octet)
+{
+    return (int)octet_weight[octet];
+}
 
 /*
  * bit_string is a buffer that is used to hold output strings, e.g.
@@ -97,534 +81,410 @@
 
 char bit_string[MAX_PRINT_STRING_LEN];
 
-octet_t
-nibble_to_hex_char(octet_t nibble) {
-  char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
-		  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-  return buf[nibble & 0xF];
+uint8_t srtp_nibble_to_hex_char(uint8_t nibble)
+{
+    char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+    return buf[nibble & 0xF];
 }
 
-char *
-octet_string_hex_string(const void *s, int length) {
-  const octet_t *str = s;
-  int i;
-  
-  /* double length, since one octet takes two hex characters */
-  length *= 2;
+char *srtp_octet_string_hex_string(const void *s, int length)
+{
+    const uint8_t *str = (const uint8_t *)s;
+    int i;
 
-  /* truncate string if it would be too long */
-  if (length > MAX_PRINT_STRING_LEN)
-    length = MAX_PRINT_STRING_LEN-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;
-}
+    /* double length, since one octet takes two hex characters */
+    length *= 2;
 
-inline int
-hex_char_to_nibble(octet_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 */
-}
+    /* truncate string if it would be too long */
+    if (length > MAX_PRINT_STRING_LEN)
+        length = MAX_PRINT_STRING_LEN - 2;
 
-int
-is_hex_string(char *s) {
-  while(*s != 0)
-    if (hex_char_to_nibble(*s++) == -1)
-      return 0;
-  return 1;
-}
-
-/*
- * hex_string_to_octet_string converts a hexadecimal string
- * of length 2 * len to a raw octet string of length len
- */
-
-int
-hex_string_to_octet_string(char *raw, char *hex, int len) {
-  octet_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 *
-v128_hex_string(v128_t *x) {
-  int i, j;
-
-  for (i=j=0; i < 16; i++) {
-    bit_string[j++]  = nibble_to_hex_char(x->octet[i] >> 4);
-    bit_string[j++]  = nibble_to_hex_char(x->octet[i] & 0xF);
-  }
-  
-  bit_string[j] = 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;
+    for (i = 0; i < length; i += 2) {
+        bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
+        bit_string[i + 1] = srtp_nibble_to_hex_char(*str++ & 0xF);
     }
-  }
-  bit_string[128] = 0; /* null terminate string */
-
-  return bit_string;
+    bit_string[i] = 0; /* null terminate string */
+    return bit_string;
 }
 
-void
-v128_copy_octet_string(v128_t *x, const octet_t s[16]) {
-#if ALIGNMENT_32BIT_REQUIRED
-  if ((((uint32_t) &s[0]) & 0x3) != 0)
-#endif
-  {
-	  x->octet[0]  = s[0];
-	  x->octet[1]  = s[1];
-	  x->octet[2]  = s[2];
-	  x->octet[3]  = s[3];
-	  x->octet[4]  = s[4];
-	  x->octet[5]  = s[5];
-	  x->octet[6]  = s[6];
-	  x->octet[7]  = s[7];
-	  x->octet[8]  = s[8];
-	  x->octet[9]  = s[9];
-	  x->octet[10] = s[10];
-	  x->octet[11] = s[11];
-	  x->octet[12] = s[12];
-	  x->octet[13] = s[13];
-	  x->octet[14] = s[14];
-	  x->octet[15] = s[15];
-  }
-#if ALIGNMENT_32BIT_REQUIRED
-  else 
-  {
-	  v128_t *v = (v128_t *) &s[0];
+char *v128_hex_string(v128_t *x)
+{
+    int i, j;
 
-	  v128_copy(x,v);
-  }
+    for (i = j = 0; i < 16; i++) {
+        bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
+        bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
+    }
+
+    bit_string[j] = 0; /* null terminate string */
+    return bit_string;
+}
+
+char *v128_bit_string(v128_t *x)
+{
+    int j, i;
+    uint32_t mask;
+
+    for (j = i = 0; j < 4; j++) {
+        for (mask = 0x80000000; mask > 0; mask >>= 1) {
+            if (x->v32[j] & mask)
+                bit_string[i] = '1';
+            else
+                bit_string[i] = '0';
+            ++i;
+        }
+    }
+    bit_string[128] = 0; /* null terminate string */
+
+    return bit_string;
+}
+
+void v128_copy_octet_string(v128_t *x, const uint8_t s[16])
+{
+#ifdef ALIGNMENT_32BIT_REQUIRED
+    if ((((uint32_t)&s[0]) & 0x3) != 0)
+#endif
+    {
+        x->v8[0] = s[0];
+        x->v8[1] = s[1];
+        x->v8[2] = s[2];
+        x->v8[3] = s[3];
+        x->v8[4] = s[4];
+        x->v8[5] = s[5];
+        x->v8[6] = s[6];
+        x->v8[7] = s[7];
+        x->v8[8] = s[8];
+        x->v8[9] = s[9];
+        x->v8[10] = s[10];
+        x->v8[11] = s[11];
+        x->v8[12] = s[12];
+        x->v8[13] = s[13];
+        x->v8[14] = s[14];
+        x->v8[15] = s[15];
+    }
+#ifdef ALIGNMENT_32BIT_REQUIRED
+    else {
+        v128_t *v = (v128_t *)&s[0];
+
+        v128_copy(x, v);
+    }
 #endif
 }
 
 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */
 
-void
-v128_set_to_zero(v128_t *x) {
-  _v128_set_to_zero(x);
+void v128_set_to_zero(v128_t *x)
+{
+    _v128_set_to_zero(x);
 }
 
-void
-v128_copy(v128_t *x, const v128_t *y) {
-  _v128_copy(x, y);
+void v128_copy(v128_t *x, const v128_t *y)
+{
+    _v128_copy(x, y);
 }
 
-void
-v128_xor(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_xor(z, x, y);
-} 
-
-void
-v128_and(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_and(z, x, y);
+void v128_xor(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_xor(z, x, y);
 }
 
-void
-v128_or(v128_t *z, v128_t *x, v128_t *y) {
-  _v128_or(z, x, y);
+void v128_and(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_and(z, x, y);
 }
 
-void
-v128_complement(v128_t *x) {
-  _v128_complement(x);
+void v128_or(v128_t *z, v128_t *x, v128_t *y)
+{
+    _v128_or(z, x, y);
 }
 
-int
-v128_is_eq(const v128_t *x, const v128_t *y) {
-  return _v128_is_eq(x, y);
+void v128_complement(v128_t *x)
+{
+    _v128_complement(x);
 }
 
-int
-v128_xor_eq(v128_t *x, const v128_t *y) {
-  return _v128_xor_eq(x, y);
+int v128_is_eq(const v128_t *x, const v128_t *y)
+{
+    return _v128_is_eq(x, y);
 }
 
-int
-v128_get_bit(const v128_t *x, int i) {
-  return _v128_get_bit(x, i);
+int v128_xor_eq(v128_t *x, const v128_t *y)
+{
+    return _v128_xor_eq(x, y);
 }
 
-void
-v128_set_bit(v128_t *x, int i) {
-  _v128_set_bit(x, i);
-}     
-
-void
-v128_clear_bit(v128_t *x, int i){
-  _v128_clear_bit(x, i);
-}    
-
-void
-v128_set_bit_to(v128_t *x, int i, int y){
-  _v128_set_bit_to(x, i, y);
+int v128_get_bit(const v128_t *x, int i)
+{
+    return _v128_get_bit(x, i);
 }
 
+void v128_set_bit(v128_t *x, int i)
+{
+    _v128_set_bit(x, i);
+}
+
+void v128_clear_bit(v128_t *x, int i)
+{
+    _v128_clear_bit(x, i);
+}
+
+void v128_set_bit_to(v128_t *x, int i, int y)
+{
+    _v128_set_bit_to(x, i, y);
+}
 
 #endif /* DATATYPES_USE_MACROS */
 
-void
-v128_right_shift(v128_t *x, int 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;
-  }
+void v128_right_shift(v128_t *x, int shift)
+{
+    const int base_index = shift >> 5;
+    const int bit_index = shift & 31;
+    int i, from;
+    uint32_t b;
 
-  if (bit_index == 0) {
-
-    /* copy each word from left size to right side */
-    x->v32[4-1] = x->v32[4-1-base_index];
-    for (i=4-1; i > base_index; i--) 
-      x->v32[i-1] = x->v32[i-1-base_index];
-
-  } else {
-    
-    /* set each word to the "or" of the two bit-shifted words */
-    for (i = 4; i > base_index; i--) {
-      from = i-1 - base_index;
-      b = x->v32[from] << bit_index;
-      if (from > 0)
-        b |= x->v32[from-1] >> (32-bit_index);
-      x->v32[i-1] = b;
+    if (shift > 127) {
+        v128_set_to_zero(x);
+        return;
     }
-    
-  }
 
-  /* now wrap up the final portion */
-  for (i=0; i < base_index; i++) 
-    x->v32[i] = 0;
-  
+    if (bit_index == 0) {
+        /* copy each word from left size to right side */
+        x->v32[4 - 1] = x->v32[4 - 1 - base_index];
+        for (i = 4 - 1; i > base_index; i--)
+            x->v32[i - 1] = x->v32[i - 1 - base_index];
+
+    } else {
+        /* set each word to the "or" of the two bit-shifted words */
+        for (i = 4; i > base_index; i--) {
+            from = i - 1 - base_index;
+            b = x->v32[from] << bit_index;
+            if (from > 0)
+                b |= x->v32[from - 1] >> (32 - bit_index);
+            x->v32[i - 1] = b;
+        }
+    }
+
+    /* now wrap up the final portion */
+    for (i = 0; i < base_index; i++)
+        x->v32[i] = 0;
 }
 
-void
-v128_left_shift(v128_t *x, int index) {
-  int i;
-  const int base_index = index >> 5;
-  const int bit_index = index & 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 (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;
-  }
+    if (shift > 127) {
+        v128_set_to_zero(x);
+        return;
+    }
 
-  /* now wrap up the final portion */
-  for (i = 4 - base_index; i < 4; i++) 
-    x->v32[i] = 0;
+    if (bit_index == 0) {
+        for (i = 0; i < 4 - base_index; i++)
+            x->v32[i] = x->v32[i + base_index];
+    } else {
+        for (i = 0; i < 4 - base_index - 1; i++)
+            x->v32[i] = (x->v32[i + base_index] >> bit_index) ^
+                        (x->v32[i + base_index + 1] << (32 - bit_index));
+        x->v32[4 - base_index - 1] = x->v32[4 - 1] >> bit_index;
+    }
 
+    /* now wrap up the final portion */
+    for (i = 4 - base_index; i < 4; i++)
+        x->v32[i] = 0;
 }
 
+/* functions manipulating bitvector_t */
 
-int
-octet_string_is_eq(octet_t *a, octet_t *b, int len) {
-  octet_t *end = b + len;
-  while (b < end)
-    if (*a++ != *b++)
-      return 1;
-  return 0;
+#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
+
+int bitvector_get_bit(const bitvector_t *v, int bit_index)
+{
+    return _bitvector_get_bit(v, bit_index);
 }
 
-void
-octet_string_set_to_zero(octet_t *s, int len) {
-  octet_t *end = s + len;
-
-  do {
-    *s = 0;
-  } while (++s < end);
-  
+void bitvector_set_bit(bitvector_t *v, int bit_index)
+{
+    _bitvector_set_bit(v, bit_index);
 }
 
-/* 
- * bswap_32() is an optimized version of htonl/ntohl
- */
-
-inline uint32_t
-bswap_32(uint32_t v) {
-#if CPU_CISC                     
-#ifndef MIPSEL  /* MIPSEL stands for MIPS Endian Little, but it's not x86,
-		 * so ignore the assembly language */
-  /* assume that we're on an Intel x86 with x > 3 */
-  asm("bswap %0" : "=r" (v) : "0" (v));
-#endif
-#endif
-  /* assume that we're on a big-endian or non-intel machine */
-  return v;
+void bitvector_clear_bit(bitvector_t *v, int bit_index)
+{
+    _bitvector_clear_bit(v, bit_index);
 }
 
-inline uint64_t
-bswap_64(uint64_t v) {
-#if CPU_CISC  /* assume that we're on an Intel x86 with x > 3 */
-#ifndef MIPSEL  /* MIPSEL stands for MIPS Endian Little, but it's not x86,
-		 * so ignore the assembly language */
-  v= (bswap_32(v >> 32)) | ((uint64_t)bswap_32((uint32_t)v)) << 32 ;
-#endif
-#endif        /* assume that we're on a big-endian or non-intel machine */
-  return v;
-}
+#endif /* DATATYPES_USE_MACROS */
 
+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));
 
+    l = length / bits_per_word * bytes_per_word;
 
-/*
- *  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
- */
+    /* allocate memory, then set parameters */
+    if (l == 0) {
+        v->word = NULL;
+        v->length = 0;
+        return -1;
+    } else {
+        v->word = (uint32_t *)srtp_crypto_alloc(l);
+        if (v->word == NULL) {
+            v->length = 0;
+            return -1;
+        }
+    }
+    v->length = length;
 
-int
-base64_char_to_sextet(octet_t c) {
-  switch(c) {
-  case 'A':
+    /* initialize bitvector to zero */
+    bitvector_set_to_zero(v);
+
     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:
-    return -1;
- }
- return -1;
 }
 
-/*
- * base64_string_to_octet_string converts a hexadecimal string
- * of length 2 * len to a raw octet string of length len
- */
-
-int
-base64_string_to_octet_string(char *raw, char *base64, int len) {
-  octet_t x;
-  int tmp;
-  int base64_len;
-
-  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;
+void bitvector_dealloc(bitvector_t *v)
+{
+    if (v->word != NULL)
+        srtp_crypto_free(v->word);
+    v->word = NULL;
+    v->length = 0;
 }
+
+void bitvector_set_to_zero(bitvector_t *x)
+{
+    /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
+    memset(x->word, 0, x->length >> 3);
+}
+
+char *bitvector_bit_string(bitvector_t *x, char *buf, int len)
+{
+    int j, i;
+    uint32_t mask;
+
+    for (j = i = 0; j < (int)(x->length >> 5) && i < len - 1; j++) {
+        for (mask = 0x80000000; mask > 0; mask >>= 1) {
+            if (x->word[j] & mask)
+                buf[i] = '1';
+            else
+                buf[i] = '0';
+            ++i;
+            if (i >= len - 1)
+                break;
+        }
+    }
+    buf[i] = 0; /* null terminate string */
+
+    return buf;
+}
+
+void bitvector_left_shift(bitvector_t *x, int shift)
+{
+    int i;
+    const int base_index = shift >> 5;
+    const int bit_index = shift & 31;
+    const int word_length = x->length >> 5;
+
+    if (shift >= (int)x->length) {
+        bitvector_set_to_zero(x);
+        return;
+    }
+
+    if (bit_index == 0) {
+        for (i = 0; i < word_length - base_index; i++)
+            x->word[i] = x->word[i + base_index];
+    } else {
+        for (i = 0; i < word_length - base_index - 1; i++)
+            x->word[i] = (x->word[i + base_index] >> bit_index) ^
+                         (x->word[i + base_index + 1] << (32 - bit_index));
+        x->word[word_length - base_index - 1] =
+            x->word[word_length - 1] >> bit_index;
+    }
+
+    /* now wrap up the final portion */
+    for (i = word_length - base_index; i < word_length; i++)
+        x->word[i] = 0;
+}
+
+int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
+{
+    uint8_t *end = b + len;
+    uint8_t accumulator = 0;
+
+    /*
+     * We use this somewhat obscure implementation to try to ensure the running
+     * time only depends on len, even accounting for compiler optimizations.
+     * The accumulator ends up zero iff the strings are equal.
+     */
+    while (b < end)
+        accumulator |= (*a++ ^ *b++);
+
+    /* Return 1 if *not* equal. */
+    return accumulator != 0;
+}
+
+void srtp_cleanse(void *s, size_t len)
+{
+    volatile unsigned char *p = (volatile unsigned char *)s;
+    while (len--)
+        *p++ = 0;
+}
+
+void octet_string_set_to_zero(void *s, size_t len)
+{
+#if defined(OPENSSL) && !defined(OPENSSL_CLEANSE_BROKEN)
+    OPENSSL_cleanse(s, len);
+#else
+    srtp_cleanse(s, len);
+#endif
+}
+
+#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;
+
+    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
diff --git a/crypto/math/gf2_8.c b/crypto/math/gf2_8.c
deleted file mode 100644
index d1b6169..0000000
--- a/crypto/math/gf2_8.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * gf2_8.c
- *
- * GF(256) finite field implementation, with the representation used
- * in the AES cipher.
- * 
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "datatypes.h"
-#include "gf2_8.h"
-
-/*
- * gf2_8_shift(x) returns the result of the GF(2^8) 'multiply by x' 
- * operation, using the field representation from AES.  
- */
-
-inline gf2_8
-gf2_8_shift(gf2_8 input) {
-  if ((input & 128) == 0)
-    return input << 1;
-  else
-    return (input << 1) ^ gf2_8_field_polynomial; 
-}
-
-inline gf2_8
-gf2_8_multiply(gf2_8 x, gf2_8 y) {
-  gf2_8 z = 0;
-
-  if (y &   1) z ^= x; x = gf2_8_shift(x);
-  if (y &   2) z ^= x; x = gf2_8_shift(x);
-  if (y &   4) z ^= x; x = gf2_8_shift(x);
-  if (y &   8) z ^= x; x = gf2_8_shift(x);
-  if (y &  16) z ^= x; x = gf2_8_shift(x);
-  if (y &  32) z ^= x; x = gf2_8_shift(x);
-  if (y &  64) z ^= x; x = gf2_8_shift(x);
-  if (y & 128) z ^= x; 
-  
-  return z;
-}
-
-
-/* this should use the euclidean algorithm */
-
-gf2_8
-gf2_8_compute_inverse(gf2_8 x) {
-  unsigned int i;
-
-  if (x == 0) return 0;    /* zero is a special case */
-  for (i=0; i < 256; i++)
-    if (gf2_8_multiply((gf2_8) i, x) == 1)
-      return (gf2_8) i;
-
-    return 0;
-}
-
diff --git a/crypto/math/math.c b/crypto/math/math.c
deleted file mode 100644
index bf9af3f..0000000
--- a/crypto/math/math.c
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
- * math.c
- *
- * crypto math operations and data types
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright (c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "math.h"
-#include <stdlib.h>           /* malloc() used in bitvector_alloc */
-
-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(octet_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.octet[0]];  /* note: endian-ness makes no difference */
-  wt += octet_weight[a.octet[1]];
-  wt += octet_weight[a.octet[2]];
-  wt += octet_weight[a.octet[3]];
-  
-  return wt;
-}
-
-inline 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(octet_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.octet[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.octet[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(v64_t *x) {
-  int i, mask, index;
-
-  for (i = index = 0; i < 8; i++) {
-    for (mask = 1; mask < 256; mask <<= 1)
-      if ((x->octet[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;
-}
-
-octet_t
-nibble_to_hex_char(octet_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(octet_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 octet_t *str, int length) {
-  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(*str >> 4);
-    bit_string[i+1] = nibble_to_hex_char(*str++ & 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.octet[i] >> 4);
-    bit_string[j++]  = nibble_to_hex_char(x.octet[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.octet[i] >> 4);
-    bit_string[j++]  = nibble_to_hex_char(x.octet[i] & 0xF);
-  }
-  
-  bit_string[j] = 0; /* null terminate string */
-  return bit_string;
-}
-
-char *
-v64_hex_string(v64_t *x) {
-  int i, j;
-
-  for (i=j=0; i < 8; i++) {
-    bit_string[j++]  = nibble_to_hex_char(x->octet[i] >> 4);
-    bit_string[j++]  = nibble_to_hex_char(x->octet[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->octet[i] >> 4);
-    bit_string[j++]  = nibble_to_hex_char(x->octet[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(octet_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;
-}
-
-octet_t
-hex_string_to_octet(char *s) {
-  octet_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) {
-  octet_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.octet[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.octet[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.octet[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.octet[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 
- */
-
-octet_t 
-A_times_x_plus_b(octet_t A[8], octet_t x, octet_t b) {
-  int index = 0;
-  unsigned mask;
-  
-  for (mask=1; mask < 256; mask *= 2) {
-    if (x & mask)
-      b^= A[index];
-    ++index;
-  }
-
-  return b;
-}
-
-inline void
-v16_copy_octet_string(v16_t *x, const octet_t s[2]) {
-  x->octet[0]  = s[0];
-  x->octet[1]  = s[1];
-}
-
-inline void
-v32_copy_octet_string(v32_t *x, const octet_t s[4]) {
-  x->octet[0]  = s[0];
-  x->octet[1]  = s[1];
-  x->octet[2]  = s[2];
-  x->octet[3]  = s[3];
-}
-
-inline void
-v64_copy_octet_string(v64_t *x, const octet_t s[8]) {
-  x->octet[0]  = s[0];
-  x->octet[1]  = s[1];
-  x->octet[2]  = s[2];
-  x->octet[3]  = s[3];
-  x->octet[4]  = s[4];
-  x->octet[5]  = s[5];
-  x->octet[6]  = s[6];
-  x->octet[7]  = s[7];
-}
-
-void
-v128_copy_octet_string(v128_t *x, const octet_t s[16]) {
-  x->octet[0]  = s[0];
-  x->octet[1]  = s[1];
-  x->octet[2]  = s[2];
-  x->octet[3]  = s[3];
-  x->octet[4]  = s[4];
-  x->octet[5]  = s[5];
-  x->octet[6]  = s[6];
-  x->octet[7]  = s[7];
-  x->octet[8]  = s[8];
-  x->octet[9]  = s[9];
-  x->octet[10] = s[10];
-  x->octet[11] = s[11];
-  x->octet[12] = s[12];
-  x->octet[13] = s[13];
-  x->octet[14] = s[14];
-  x->octet[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 */
-
-
-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    */
-
-#if 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(octet_t *a, octet_t *b, int len) {
-  octet_t *end = b + len;
-  while (b < end)
-    if (*a++ != *b++)
-      return 1;
-  return 0;
-}
-
-void
-octet_string_set_to_zero(octet_t *s, int len) {
-  octet_t *end = s + len;
-
-  do {
-    *s = 0;
-  } while (++s < end);
-  
-}
-
-/* functions manipulating bit_vector_t */
-
-#define BITVECTOR_MAX_WORDS 5
-
-int
-bitvector_alloc(bitvector_t *v, unsigned long length) {
-  unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;
-  int i;
-
-  /* allocate memory, then set parameters */
-  if (l > BITVECTOR_MAX_WORDS)
-    return -1;
-  else
-    l = BITVECTOR_MAX_WORDS;
-  v->word   = malloc(l);
-  if (v->word == NULL)
-    return -1;
-  v->length = length;
-
-  /* initialize bitvector to zero */
-  for (i=0; i < (length >> 5); i++) {
-    v->word = 0;
-  }
-
-  return 0;
-}
-
-void
-bitvector_set_bit(bitvector_t *v, int bit_index) {
-
-  v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));
-  
-}
-
-int
-bitvector_get_bit(const bitvector_t *v, int bit_index) {
-
-  return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;
-  
-}
-
-#include <stdio.h>
-
-int
-bitvector_print_hex(const bitvector_t *v, FILE *stream) {
-  int i;
-  int m = v->length >> 5;
-  int n = v->length & 31;
-  char string[9];
-  uint32_t tmp;
-
-  /* if length isn't a multiple of four, we can't hex_print */
-  if (n & 3)
-    return -1;
-  
-  /* if the length is zero, do nothing */
-  if (v->length == 0)
-    return 0;
-
-  /*
-   * loop over words from most significant to least significant - 
-   */
-  
-  for (i=m; i > 0; i++) {
-    char *str = string + 7;
-    tmp = v->word[i];
-    
-    /* null terminate string */
-    string[8] = 0;   
-
-    /* loop over nibbles */
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);  tmp >>= 4; 
-    *str-- = nibble_to_hex_char(tmp & 0xf);   
-
-    /* now print stream */
-    fprintf(stream, string);
-  }
-  
-  return 0;
-
-}
-
-
-int
-hex_string_length(char *s) {
-  int count = 0;
-  
-  /* ignore leading zeros */
-  while ((*s != 0) && *s == '0')
-    s++;
-
-  /* count remaining characters */
-  while (*s != 0) {
-    if (hex_char_to_nibble(*s++) == -1)
-      return -1;
-    count++;
-  }
-
-  return count;
-}
-
-int
-bitvector_set_from_hex(bitvector_t *v, char *string) {
-  int num_hex_chars, m, n, i, j;
-  uint32_t tmp;
-  
-  num_hex_chars = hex_string_length(string);
-  if (num_hex_chars == -1)
-    return -1;
-
-  /* set length */
-  v->length = num_hex_chars * 4;
-  /* 
-   * at this point, we should subtract away a bit if the high
-   * bit of the first character is zero, but we ignore that 
-   * for now and assume that we're four-bit aligned - DAM
-   */
-
-  
-  m = num_hex_chars / 8;   /* number of words                */
-  n = num_hex_chars % 8;   /* number of nibbles in last word */
-
-  /* if the length is greater than the bitvector, return an error */
-  if (m > BITVECTOR_MAX_WORDS)
-    return -1;
-
-  /* 
-   * loop over words from most significant - first word is a special
-   * case 
-   */
-  
-  if (n) {
-    tmp = 0;
-    for (i=0; i < n; i++) {
-      tmp = hex_char_to_nibble(*string++); 
-      tmp <<= 4;  
-    }
-    v->word[m] = tmp;
-  }
-
-  /* now loop over the rest of the words */
-  for (i=m-1; i >= 0; i--) {
-     tmp = 0;
-     for (j=0; j < 8; j++) {
-       tmp = hex_char_to_nibble(*string++); 
-       tmp <<= 4;  
-     }
-     v->word[i] = tmp;
-  }
-
-  return 0;
-}
-
-
-/* functions below not yet tested! */
-
-int
-v32_low_bit(v32_t *w) {
-  int value;
-
-  value = low_bit[w->octet[0]];
-  if (value != -1)
-    return value;
-  value = low_bit[w->octet[1]];
-  if (value != -1)
-    return value + 8;
-  value = low_bit[w->octet[2]];
-  if (value != -1)
-    return value + 16;
-  value = low_bit[w->octet[3]];
-  if (value == -1)
-    return -1;
-  return value + 24;
-}
-
-/* high_bit not done yet */
-
-
-
-
-
diff --git a/crypto/math/stat.c b/crypto/math/stat.c
index fddacac..6dd332b 100644
--- a/crypto/math/stat.c
+++ b/crypto/math/stat.c
@@ -1,17 +1,57 @@
 /*
  * stats.c
  *
- * statistical tests for randomness (FIPS 140-2, Section 4.9)
- * 
+ * statistical tests
+ *
  * David A. McGrew
  * Cisco Systems, Inc.
  */
 
+/*
+ *
+ * Copyright (c) 2001-2017, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "stat.h"
 
-debug_module_t mod_stat = {
-  0,                 /* debugging is off by default */
-  "stat test"        /* printable module name       */
+srtp_debug_module_t srtp_mod_stat = {
+    0,                  /* debugging is off by default */
+    (char *)"stat test" /* printable module name       */
 };
 
 /*
@@ -21,331 +61,153 @@
 
 #define STAT_TEST_DATA_LEN 2500
 
-err_status_t
-stat_test_monobit(octet_t *data) {
-  octet_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(srtp_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(octet_t *data) {
-  int i;
-  octet_t *data_end = data + STAT_TEST_DATA_LEN;
-  double poker;
-  uint16_t f[16] = {
-    0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0
-  };
-  
-  while (data < data_end) {
-    f[*data & 0x0f]++;    /* increment freq. count for low nibble  */
-    f[(*data) >> 4]++;    /* increment freq. count for high nibble */
-    data++;
-  }
+srtp_err_status_t stat_test_poker(uint8_t *data)
+{
+    int i;
+    uint8_t *data_end = data + STAT_TEST_DATA_LEN;
+    double poker;
+    uint16_t f[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
-  poker = 0.0;
-  for (i=0; i < 16; i++) 
-    poker += (double) f[i] * f[i];
+    while (data < data_end) {
+        f[*data & 0x0f]++; /* increment freq. count for low nibble  */
+        f[(*data) >> 4]++; /* increment freq. count for high nibble */
+        data++;
+    }
 
-  poker *= (16.0 / 5000.0);
-  poker -= 5000.0;
+    poker = 0.0;
+    for (i = 0; i < 16; i++)
+        poker += (double)f[i] * f[i];
 
-  debug_print(mod_stat, "poker test: %f\n", poker);
-    
-  if ((poker < 2.16) || (poker > 46.17))
-    return err_status_algo_fail;
-  
-  return err_status_ok;
+    poker *= (16.0 / 5000.0);
+    poker -= 5000.0;
+
+    debug_print(srtp_mod_stat, "poker test: %f\n", poker);
+
+    if ((poker < 2.16) || (poker > 46.17))
+        return srtp_err_status_algo_fail;
+
+    return srtp_err_status_ok;
 }
 
-
 /*
  * runs[i] holds the number of runs of size (i-1)
  */
 
-err_status_t
-stat_test_runs(octet_t *data) {
-  octet_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 };
-  int16_t  state = 0;
-  uint16_t mask;
-  int i;
-  
-  /*
-   * the state variable holds the number of bits in the
-   * current run (or gap, if negative)
-   */
-  
-  while (data < data_end) {
+srtp_err_status_t stat_test_runs(uint8_t *data)
+{
+    uint8_t *data_end = data + STAT_TEST_DATA_LEN;
+    uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
+    uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
+    uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
+    uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
+    int state = 0;
+    uint16_t mask;
+    int i;
 
-    /* loop over the bits of this byte */
-    for (mask = 1; mask < 256; mask <<= 1) {
-      if (*data & mask) {
+    /*
+     * the state variable holds the number of bits in the
+     * current run (or gap, if negative)
+     */
 
- 	/* next bit is a one  */
-	if (state > 0) {
-
-	  /* 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) {
-
-	  /* 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) {
-
-	  /* 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) {
-
-	  /* prefix is a gap, so increment gap-count (decrement state) */
-	  state--;
-
-	  /* check for long gaps */ 
-	  if (state < -25) {
-		debug_print(mod_stat, ">25 gaps (2): %d", state);
-	    return err_status_algo_fail;
-	  }
-
-	} else {
-
-	  /* state is zero; this happens only at initialization        */
-	  state = -1;
-	}
-      }
-    }
-
-    /* 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;
-  octet_t *data, *data_end;
-  uint16_t f[16] = {
-    0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0
-  };
-  octet_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 };
-  int16_t  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) {
+        /* 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++;
 
-      /* update monobit test counter */
-      ones_count += octet_get_weight(*data);
+                    /* check for long runs */
+                    if (state > 25) {
+                        debug_print(srtp_mod_stat, ">25 runs: %d", state);
+                        return srtp_err_status_algo_fail;
+                    }
 
-      /* update poker test counters */
-      f[*data & 0x0f]++;    /* increment freq. count for low nibble  */
-      f[(*data) >> 4]++;    /* increment freq. count for high nibble */
+                } else if (state < 0) {
+                    /* prefix is a gap  */
+                    if (state < -25) {
+                        debug_print(srtp_mod_stat, ">25 gaps: %d", state);
+                        return srtp_err_status_algo_fail; /* long-runs test
+                                                             failed   */
+                    }
+                    if (state < -6) {
+                        state = -6; /* group together gaps > 5 */
+                    }
+                    gaps[-1 - state]++; /* increment gap count      */
+                    state = 1;          /* set state at one set bit */
+                } else {
+                    /* state is zero; this happens only at initialization */
+                    state = 1;
+                }
+            } else {
+                /* next bit is a zero  */
+                if (state > 0) {
+                    /* prefix is a run */
+                    if (state > 25) {
+                        debug_print(srtp_mod_stat, ">25 runs (2): %d", state);
+                        return srtp_err_status_algo_fail; /* long-runs test
+                                                             failed   */
+                    }
+                    if (state > 6) {
+                        state = 6; /* group together runs > 5 */
+                    }
+                    runs[state - 1]++; /* increment run count       */
+                    state = -1;        /* set state at one zero bit */
+                } else if (state < 0) {
+                    /* prefix is a gap, so increment gap-count (decrement state)
+                     */
+                    state--;
 
-      /* 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 for long gaps */
+                    if (state < -25) {
+                        debug_print(srtp_mod_stat, ">25 gaps (2): %d", state);
+                        return srtp_err_status_algo_fail;
+                    }
 
-  /* check to see if test data is within bounds */
+                } else {
+                    /* state is zero; this happens only at initialization */
+                    state = -1;
+                }
+            }
+        }
 
-  /* 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; 
+        /* move along to next octet */
+        data++;
     }
 
-  debug_print(mod_stat, "passed random stat test", NULL);
-  return err_status_ok;
+    if (srtp_mod_stat.on) {
+        debug_print(srtp_mod_stat, "runs test", NULL);
+        for (i = 0; i < 6; i++)
+            debug_print(srtp_mod_stat, "  runs[]: %d", runs[i]);
+        for (i = 0; i < 6; i++)
+            debug_print(srtp_mod_stat, "  gaps[]: %d", gaps[i]);
+    }
+
+    /* check run and gap counts against the fixed limits */
+    for (i = 0; i < 6; i++)
+        if ((runs[i] < lo_value[i]) || (runs[i] > hi_value[i]) ||
+            (gaps[i] < lo_value[i]) || (gaps[i] > hi_value[i]))
+            return srtp_err_status_algo_fail;
+
+    return srtp_err_status_ok;
 }
diff --git a/crypto/replay/rdb.c b/crypto/replay/rdb.c
index 19eca79..ab1c7b5 100644
--- a/crypto/replay/rdb.c
+++ b/crypto/replay/rdb.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,95 +43,95 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include "rdb.h"
 
-
 /*
  * this implementation of a replay database works as follows:
- * 
+ *
  * window_start is the index of the first packet in the window
  * bitmask      a bit-buffer, containing the most recently entered
- *              index as the leftmost bit 
+ *              index as the leftmost bit
  *
  */
 
-/* rdb_init initalizes rdb */
-
-err_status_t
-rdb_init(rdb_t *rdb) {
-  v128_set_to_zero(&rdb->bitmask);
-  rdb->window_start = 0;
-  return err_status_ok;
+/* srtp_rdb_init initalizes rdb */
+srtp_err_status_t srtp_rdb_init(srtp_rdb_t *rdb)
+{
+    v128_set_to_zero(&rdb->bitmask);
+    rdb->window_start = 0;
+    return srtp_err_status_ok;
 }
 
 /*
- * rdb_check checks to see if index appears in rdb
+ * srtp_rdb_check checks to see if index appears in rdb
  */
+srtp_err_status_t srtp_rdb_check(const srtp_rdb_t *rdb, uint32_t p_index)
+{
+    /* 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;
+    }
 
-err_status_t
-rdb_check(const rdb_t *rdb, uint32_t index) {
-  
-  /* if the index appears after (or at very end of) the window, its good */
-  if (index > rdb->window_start + rdb_bits_in_bitmask)
-    return err_status_ok;
-  
-  /* if the index appears before the window, its bad */
-  if (index < rdb->window_start)
-    return err_status_fail;
+    /* 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, (index - rdb->window_start)) == 1)
-    return err_status_fail;    
-      
-  /* otherwise, the index is okay */
-  return err_status_ok;
+    /* otherwise, the index appears within the window, so check the bitmask */
+    if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1) {
+        return srtp_err_status_replay_fail;
+    }
+
+    /* otherwise, the index is okay */
+    return srtp_err_status_ok;
 }
 
 /*
- * rdb_add_index adds index to rdb_t (and does *not* check if
+ * srtp_rdb_add_index adds index to srtp_rdb_t (and does *not* check if
  * index appears in db)
  *
- * this function should be called only after rdb_check has
+ * this function should be called only after srtp_rdb_check has
  * indicated that the index does not appear in the rdb, e.g., a mutex
  * should protect the rdb between these calls
  */
+srtp_err_status_t srtp_rdb_add_index(srtp_rdb_t *rdb, uint32_t p_index)
+{
+    unsigned int delta;
 
-err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t index) {
-  int delta;  
+    if (p_index < rdb->window_start)
+        return srtp_err_status_replay_fail;
 
-  /* here we *assume* that index > rdb->window_start */
+    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);
 
-  delta = (index - rdb->window_start);    
-  if (delta < rdb_bits_in_bitmask) {
+    } else {
+        delta -= rdb_bits_in_bitmask - 1;
 
-    /* if the index is within the window, set the appropriate bit */
-    v128_set_bit(&rdb->bitmask, 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;
+    }
 
-  } else { 
-    
-    delta -= rdb_bits_in_bitmask;
-
-    /* shift the window forward by delta bits*/
-    v128_left_shift(&rdb->bitmask, delta);
-    v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-delta);
-    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;
 }
diff --git a/crypto/replay/rdbx.c b/crypto/replay/rdbx.c
index 9012aa7..40cba01 100644
--- a/crypto/replay/rdbx.c
+++ b/crypto/replay/rdbx.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,134 +43,124 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "rdbx.h"
 
-#define rdbx_high_bit_in_bitmask 127
-
 /*
- * from draft-ietf-avt-srtp-00.txt:
+ * from RFC 3711:
  *
  * A receiver reconstructs the index i of a packet with sequence
- *  number s using the estimate
+ *  number SEQ using the estimate
  *
- * i = 65,536 * t + s,
+ * i = 2^16 * v + SEQ,
  *
- * where t is chosen from the set { r-1, r, r+1 } such that i is
- * closest to the value 65,536 * r + s_l.  If the value r+1 is used,
+ * 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
-#ifdef NO_64BIT_MATH
-  uint32_t guess_roc = ((high32(*guess) << 16) |
-						(low32(*guess) >> 16));
-  uint16_t guess_seq = (uint16_t) (low32(*guess));
-#else
-  uint32_t guess_roc = (uint32_t)(*guess >> 16);
-  uint16_t guess_seq = (uint16_t) *guess;  
-#endif
-  int 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;
+    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 = 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;
-  
-  /* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
+    guess_seq = s;
+
+/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
 #ifdef NO_64BIT_MATH
-  *guess = make64(guess_roc >> 16,
-				  (guess_roc << 16) | guess_seq);
+    *guess = make64(guess_roc >> 16, (guess_roc << 16) | guess_seq);
 #else
-  *guess = (((uint64_t) guess_roc) << 16) | guess_seq;
+    *guess = (((uint64_t)guess_roc) << 16) | guess_seq;
 #endif
 
-  return difference;
+    return difference;
 }
 
 /*
@@ -178,112 +168,219 @@
  *
  */
 
-
 /*
- *  rdbx_init(&r) initalizes the rdbx_t pointed to by r 
+ *  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) {
-  v128_set_to_zero(&rdbx->bitmask);
-  index_init(&rdbx->index);
+    if (bitvector_alloc(&rdbx->bitmask, ws) != 0) {
+        return srtp_err_status_alloc_fail;
+    }
 
-  return err_status_ok;
+    srtp_index_init(&rdbx->index);
+
+    return srtp_err_status_ok;
 }
 
+/*
+ *  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);
+
+    return srtp_err_status_ok;
+}
 
 /*
- * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
+ * 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
+ * srtp_err_status_replay_old; otherwise, srtp_err_status_ok is returned.
+ *
+ */
+srtp_err_status_t srtp_rdbx_set_roc(srtp_rdbx_t *rdbx, uint32_t roc)
+{
+    bitvector_set_to_zero(&rdbx->bitmask);
+
+#ifdef NO_64BIT_MATH
+#error not yet implemented
+#else
+
+    /* make sure that we're not moving backwards */
+    if (roc < (rdbx->index >> 16)) {
+        return srtp_err_status_replay_old;
+    }
+
+    rdbx->index &= 0xffff;                /* retain lowest 16 bits */
+    rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
+#endif
+
+    return srtp_err_status_ok;
+}
+
+/*
+ * srtp_rdbx_get_packet_index(rdbx) returns the value of the packet index
+ * for the srtp_rdbx_t pointed to by rdbx
+ *
+ */
+srtp_xtd_seq_num_t srtp_rdbx_get_packet_index(const srtp_rdbx_t *rdbx)
+{
+    return rdbx->index;
+}
+
+/*
+ * srtp_rdbx_get_window_size(rdbx) returns the value of the window size
+ * for the srtp_rdbx_t pointed to by rdbx
+ *
+ */
+unsigned long srtp_rdbx_get_window_size(const srtp_rdbx_t *rdbx)
+{
+    return bitvector_get_length(&rdbx->bitmask);
+}
+
+/*
+ * 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 (rdbx_high_bit_in_bitmask + delta < 0) {   
-                         /* if delta is lower than the bitmask, it's bad */
-    return err_status_replay_old; 
-  } else if (v128_get_bit(&rdbx->bitmask, 
-			  rdbx_high_bit_in_bitmask + 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);
-    v128_left_shift(&rdbx->bitmask, delta);
-    v128_set_bit(&rdbx->bitmask, 127);
-  } else {
-    /* delta is in window, so flip bit in bitmask */
-    v128_set_bit(&rdbx->bitmask, -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
  */
+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)
+ */
 
-int
-rdbx_estimate_index(const rdbx_t *rdbx,
-		    xtd_seq_num_t *guess,
-		    sequence_number_t s) {
-
-  /*
-   * if the sequence number and rollover counter in the rdbx are
-   * non-zero, then use the index_guess(...) function, otherwise, just
-   * set the rollover counter to zero (since the index_guess(...)
-   * function might incorrectly guess that the rollover counter is
-   * 0xffffffff)
-   */
-
-#if NO_64BIT_MATH
-  /* seq_num_median = 0x8000 */
-  if (high32(rdbx->index) > 0 ||
-	  low32(rdbx->index) > seq_num_median)
+#ifdef NO_64BIT_MATH
+    /* 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);
+    }
 
-#if NO_64BIT_MATH
-  *guess = make64(0,(uint32_t) s);
-#else  
-  *guess = s;
-#endif
-
-#if NO_64BIT_MATH
-  return s - (uint16_t) low32(rdbx->index);
+#ifdef NO_64BIT_MATH
+    *guess = make64(0, (uint32_t)s);
 #else
-  return s - (uint16_t) rdbx->index;
+    *guess = s;
 #endif
+
+#ifdef NO_64BIT_MATH
+    return s - (uint16_t)low32(rdbx->index);
+#else
+    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;
 }
diff --git a/crypto/replay/ut_sim.c b/crypto/replay/ut_sim.c
index a348d7c..2825b68 100644
--- a/crypto/replay/ut_sim.c
+++ b/crypto/replay/ut_sim.c
@@ -3,32 +3,32 @@
  *
  * an unreliable transport simulator
  * (for testing replay databases and suchlike)
- * 
+ *
  * David A. 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
@@ -44,62 +44,64 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include "ut_sim.h"
+#include "cipher_priv.h"
 
-
-int
-ut_compar(const void *a, const void *b) {
-  return random() > (RAND_MAX/2) ? -1 : 1;
+int ut_compar(const void *a, const void *b)
+{
+    uint8_t r;
+    srtp_cipher_rand_for_tests(&r, sizeof(r));
+    return r > (UINT8_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
diff --git a/crypto/rng/ctr_prng.c b/crypto/rng/ctr_prng.c
deleted file mode 100644
index 6d52710..0000000
--- a/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-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "prng.h"
-
-/* single, global prng structure */
-
-ctr_prng_t ctr_prng;
-
-err_status_t
-ctr_prng_init(rand_source_func_t random_source) {
-  octet_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);
-  if (status) 
-    return status;
-
-  return err_status_ok;
-}
-
-err_status_t
-ctr_prng_get_octet_string(void *dest, int len) {
-  err_status_t status;
-
-  /* 
-   * if we need to re-initialize the prng, do so now 
-   *
-   * we cast to a 64-bit integer in order to avoid overflows
-   */
-  if ((uint64_t) ctr_prng.octet_count + len > MAX_PRNG_OUT_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, dest, len);
-  if (status)
-    return status;
-  
-  return err_status_ok;
-}
-
-err_status_t
-ctr_prng_deinit() {
-
-  /* nothing */
-  
-  return err_status_ok;  
-}
diff --git a/crypto/rng/prng.c b/crypto/rng/prng.c
deleted file mode 100644
index 57c08d4..0000000
--- a/crypto/rng/prng.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * prng.c 
- *
- * pseudorandom source
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright(c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "prng.h"
-
-/* single, global prng structure */
-
-x917_prng_t x917_prng;
-
-err_status_t
-x917_prng_init(rand_source_func_t random_source) {
-  v128_t tmp_key;
-  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((octet_t *)&tmp_key, 16);
-  if (status) 
-    return status;
-
-  /* expand aes key */
-  aes_expand_encryption_key(tmp_key, x917_prng.key);
-
-  /* initialize prng state from random source */
-  status = x917_prng.rand((octet_t *)&x917_prng.state, 16);
-  if (status) 
-    return status;
-
-  return err_status_ok;
-}
-
-err_status_t
-x917_prng_get_octet_string(octet_t *dest, uint32_t len) {
-  uint32_t t;
-  v128_t buffer;
-  int i, tail_len;
-  err_status_t status;
-
-  /* 
-   * if we need to re-initialize the prng, do so now 
-   *
-   * we cast to a 64-bit integer in order to avoid overflows
-   */
-  if ((uint64_t) x917_prng.octet_count + len > MAX_PRNG_OUT_LEN) {
-    status = x917_prng_init(x917_prng.rand);    
-    if (status)
-      return status;
-  }
-  x917_prng.octet_count += len;
-  
-  /* find out the time */
-  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.octet[0];
-    *dest++ = buffer.octet[1];
-    *dest++ = buffer.octet[2];
-    *dest++ = buffer.octet[3];
-    *dest++ = buffer.octet[4];
-    *dest++ = buffer.octet[5];
-    *dest++ = buffer.octet[6];
-    *dest++ = buffer.octet[7];
-    *dest++ = buffer.octet[8];
-    *dest++ = buffer.octet[9];
-    *dest++ = buffer.octet[10];
-    *dest++ = buffer.octet[11];
-    *dest++ = buffer.octet[12];
-    *dest++ = buffer.octet[13];
-    *dest++ = buffer.octet[14];
-    *dest++ = buffer.octet[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.octet[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() {
-  
-  return err_status_ok;  
-}
diff --git a/crypto/rng/rand_source.c b/crypto/rng/rand_source.c
deleted file mode 100644
index 9521719..0000000
--- a/crypto/rng/rand_source.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * rand_source.c
- *
- * implements a random source based on /dev/random
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright(c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "rand_source.h"
-
-#include <fcntl.h>          /* for open()  */
-#include <unistd.h>         /* for close() */
-
-/* global dev_rand_fdes is file descriptor for /dev/random */
-
-int dev_random_fdes = 0;
-
-err_status_t
-rand_source_init() {
-
-  /* open /dev/random for reading */
-  dev_random_fdes = open("/dev/urandom", O_RDONLY, 0);
-  if (dev_random_fdes == 0)
-    return err_status_init_fail;
-
-  return err_status_ok;
-}
-
-err_status_t
-rand_source_get_octet_string(void *dest, int len) {
-
-  /* 
-   * read len octets from /dev/random to dest, and
-   * check return value to make sure enough octets were
-   * written 
-   */
-  if (read(dev_random_fdes, dest, len) != len)
-    return err_status_fail;
-
-  return err_status_ok;
-}
-
-err_status_t
-rand_source_deinit() {
-
-  if (dev_random_fdes == 0)
-    return err_status_dealloc_fail;  /* well, we haven't really failed, *
-				      * but there is something wrong    */
-  close(dev_random_fdes);  
-  
-  return err_status_ok;  
-}
diff --git a/crypto/test/aes_calc.c b/crypto/test/aes_calc.c
index 56b0323..b362fd5 100644
--- a/crypto/test/aes_calc.c
+++ b/crypto/test/aes_calc.c
@@ -1,6 +1,6 @@
 /*
  * aes_calc.c
- * 
+ *
  * A simple AES calculator for generating AES encryption values
  *
  * David A. McGrew
@@ -8,104 +8,150 @@
  */
 
 /*
-  
+ *
+ * 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_KEY_LEN 16
+#define AES_MAX_KEY_LEN 32
 
-int
-main (int argc, char *argv[]) {
-  v128_t data, key;
-  aes_expanded_key_t exp_key;
-  int len;
-  int verbose;
+int main(int argc, char *argv[])
+{
+    v128_t data;
+    uint8_t key[AES_MAX_KEY_LEN];
+    srtp_aes_expanded_key_t exp_key;
+    int key_len, len;
+    int verbose = 0;
+    srtp_err_status_t status;
 
-  if (argc == 3) {
-    /* we're not in verbose mode */
-    verbose = 0;
-  } else if (argc == 4) {
-    if (strncmp(argv[3], "-v", 2) == 0) {
-      /* we're in verbose mode */
-      verbose = 1;
+    if (argc == 3) {
+        /* we're not in verbose mode */
+        verbose = 0;
+    } else if (argc == 4) {
+        if (strncmp(argv[3], "-v", 2) == 0) {
+            /* we're in verbose mode */
+            verbose = 1;
+        } else {
+            /* unrecognized flag, complain and exit */
+            usage(argv[0]);
+        }
     } else {
-      /* unrecognized flag, complain and exit */
-      usage(argv[0]);
+        /* we've been fed the wrong number of arguments - compain and exit */
+        usage(argv[0]);
     }
-  } else {
-    /* we've been fed the wrong number of arguments - compain and exit */
-    usage(argv[0]);
-  }
-  
-  /* read in key, checking length */
-  if (strlen(argv[1]) > AES_KEY_LEN*2) {
-    fprintf(stderr, 
-	    "error: too many digits in key "
-	    "(should be %d hexadecimal digits, found %u)\n",
-	    AES_KEY_LEN*2, (unsigned)strlen(argv[1]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((octet_t *)&key, argv[1], AES_KEY_LEN*2);
-  /* check that hex string is the right length */
-  if (len < AES_KEY_LEN*2) {
-    fprintf(stderr, 
-	    "error: too few digits in key "
-	    "(should be %d hexadecimal digits, found %d)\n",
-	    AES_KEY_LEN*2, len);
-    exit(1);    
-  } 
-      
-  /* read in plaintext, checking length */
-  if (strlen(argv[2]) > 16*2) {
-    fprintf(stderr, 
-	    "error: too many digits in plaintext "
-	    "(should be %d hexadecimal digits, found %u)\n",
-	    16*2, (unsigned)strlen(argv[2]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((octet_t *)(&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((octet_t *)&data, 16));
-  }
+    /* read in key, checking length */
+    if (strlen(argv[1]) > AES_MAX_KEY_LEN * 2) {
+        fprintf(stderr, "error: too many digits in key "
+                        "(should be at most %d hexadecimal digits, found %u)\n",
+                AES_MAX_KEY_LEN * 2, (unsigned)strlen(argv[1]));
+        exit(1);
+    }
+    len = hex_string_to_octet_string((char *)key, argv[1], AES_MAX_KEY_LEN * 2);
+    /* check that hex string is the right length */
+    if (len != 32 && len != 48 && len != 64) {
+        fprintf(stderr, "error: bad number of digits in key "
+                        "(should be 32/48/64 hexadecimal digits, found %d)\n",
+                len);
+        exit(1);
+    }
+    key_len = len / 2;
 
-  /* encrypt plaintext */
-  aes_expand_encryption_key(key, exp_key);
+    /* 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);
+    }
 
-  aes_encrypt(&data, exp_key);
+    if (verbose) {
+        /* print out plaintext */
+        printf("plaintext:\t%s\n",
+               octet_string_hex_string((uint8_t *)&data, 16));
+    }
 
-  /* write ciphertext to output */
-  if (verbose) {
-    printf("key:\t\t%s\n", v128_hex_string(&key));
-    printf("ciphertext:\t");
-  }
-  printf("%s\n", v128_hex_string(&data));
+    /* encrypt plaintext */
+    status = srtp_aes_expand_encryption_key(key, key_len, &exp_key);
+    if (status) {
+        fprintf(stderr, "error: AES key expansion failed.\n");
+        exit(1);
+    }
 
-  return 0;
+    srtp_aes_encrypt(&data, &exp_key);
+
+    /* write ciphertext to output */
+    if (verbose) {
+        printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
+        printf("ciphertext:\t");
+    }
+    printf("%s\n", v128_hex_string(&data));
+
+    return 0;
 }
-
diff --git a/crypto/test/auth_driver.c b/crypto/test/auth_driver.c
deleted file mode 100644
index b133480..0000000
--- a/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-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#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, (octet_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;
-  octet_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, (octet_t *)msg_string, msg_len_octets, (octet_t *)result);
-  }
-  timer = clock() - timer;
-
-  free(msg_string);
-  free(result);
-  
-  return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer;
-}
-
-
diff --git a/crypto/test/cipher_driver.c b/crypto/test/cipher_driver.c
index 65cf6c0..8219a06 100644
--- a/crypto/test/cipher_driver.c
+++ b/crypto/test/cipher_driver.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,22 +43,26 @@
  *
  */
 
-#include <stdio.h>           /* for printf() */
-#include <stdlib.h>          /* for random() */
-#include <string.h>          /* for memset() */
-#include <unistd.h>          /* for getopt() */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h> /* for printf() */
+#include "getopt_s.h"
 #include "cipher.h"
+#include "cipher_priv.h"
+#ifdef GCM
+#include "aes_icm_ext.h"
+#include "aes_gcm.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
@@ -66,188 +70,280 @@
  * 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);
 
-double
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			     int 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;
+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 GCM
+extern srtp_cipher_type_t srtp_aes_icm_192;
+extern srtp_cipher_type_t srtp_aes_gcm_128;
+extern srtp_cipher_type_t srtp_aes_gcm_256;
+#endif
 
-int
-main(int argc, char *argv[]) {
-  cipher_t *c = NULL;
-  err_status_t status;
-  unsigned char test_key[20] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13
-  };
-  int q;
-  unsigned do_timing_test = 0;
-  unsigned do_validation = 0;
-  unsigned do_array_timing_test = 0;
+int main(int argc, char *argv[])
+{
+    srtp_cipher_t *c = NULL;
+    srtp_err_status_t status;
+    /* clang-format off */
+    unsigned char test_key[48] = {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    };
+    /* clang-format on */
+    int q;
+    unsigned do_timing_test = 0;
+    unsigned do_validation = 0;
+    unsigned do_array_timing_test = 0;
 
-  /* process input arguments */
-  while (1) {
-    q = getopt(argc, argv, "tva");
-    if (q == -1) 
-      break;
-    switch (q) {
-    case 't':
-      do_timing_test = 1;
-      break;
-    case 'v':
-      do_validation = 1;
-      break;
-    case 'a':
-      do_array_timing_test = 1;
-      break;
-    default:
-      usage(argv[0]);
-    }    
-  }
-   
-  printf("cipher test driver\n"
-	 "David A. McGrew\n"
-	 "Cisco Systems, Inc.\n");
-
-  if (!do_validation && !do_timing_test && !do_array_timing_test)
-    usage(argv[0]);
-
-   /* arry timing (cache thrash) test */
-  if (do_array_timing_test) {
-    int max_num_cipher = 1 << 16;   /* number of ciphers in cipher_array */
-    int num_cipher;
-    
-    for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
-      cipher_driver_test_array_throughput(&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_cbc, 16, num_cipher); 
- 
-  }
-
-  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 */
-    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 GCM
+        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, 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, 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 GCM
+        cipher_driver_self_test(&srtp_aes_icm_192);
+        cipher_driver_self_test(&srtp_aes_gcm_128);
+        cipher_driver_self_test(&srtp_aes_gcm_256);
+#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);
-  
-  return 0;
+
+    /* run the throughput test on the aes_icm cipher (128-bit key) */
+    status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
+                                    SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
+    if (status) {
+        fprintf(stderr, "error: can't allocate cipher\n");
+        exit(status);
+    }
+
+    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);
+
+    /* repeat the tests with 256-bit keys */
+    status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
+                                    SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
+    if (status) {
+        fprintf(stderr, "error: can't allocate cipher\n");
+        exit(status);
+    }
+
+    status = srtp_cipher_init(c, test_key);
+    check_status(status);
+
+    if (do_timing_test)
+        cipher_driver_test_throughput(c);
+
+    if (do_validation) {
+        status = cipher_driver_test_buffering(c);
+        check_status(status);
+    }
+
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+
+#ifdef GCM
+    /* run the throughput test on the aes_gcm_128 cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_128, &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);
+    }
+
+    // GCM ciphers don't do buffering; they're "one shot"
+
+    status = srtp_cipher_dealloc(c);
+    check_status(status);
+
+    /* run the throughput test on the aes_gcm_256 cipher */
+    status = srtp_cipher_type_alloc(&srtp_aes_gcm_256, &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);
+    }
+
+    // GCM ciphers don't do buffering; they're "one shot"
+
+    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 = 100000;  
-  
-  printf("timing %s throughput:\n", c->type->description);
-  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;
 }
 
 /*
@@ -256,234 +352,252 @@
  * calls
  */
 
-err_status_t
-cipher_driver_test_buffering(cipher_t *c) {
-  int i, j, len, num_trials = 1000;
-  int buflen = 1024;
-  octet_t buffer0[buflen], buffer1[buflen], *current, *end;
-  octet_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;
 
-  for (i=0; i < num_trials; i++) {
+    printf("testing output buffering for cipher %s...", c->type->description);
 
-   /* set buffers to zero */
-    for (j=0; j < buflen; j++) 
-      buffer0[j] = buffer1[j] = 0;
-    
-    /* initialize cipher  */
-    status = cipher_set_iv(c, idx);
-    if (status)
-      return status;
+    for (i = 0; i < num_trials; i++) {
+        /* set buffers to zero */
+        for (j = 0; j < (int)buflen; j++) {
+            buffer0[j] = buffer1[j] = 0;
+        }
 
-    /* generate 'reference' value by encrypting all at once */
-    status = cipher_encrypt(c, buffer0, &buflen);
-    if (status)
-      return status;
+        /* initialize cipher  */
+        status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
+        if (status)
+            return status;
 
-    /* re-initialize cipher */
-    status = 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) {
+        /* generate 'reference' value by encrypting all at once */
+        status = srtp_cipher_encrypt(c, buffer0, &buflen);
+        if (status)
+            return status;
 
-      /* choose a short length */
-      len = random() & 0x01f;
+        /* re-initialize cipher */
+        status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
+        if (status)
+            return status;
 
-      /* make sure that len doesn't cause us to overreach the buffer */
-      if (current + len > end)
-	len = end - current;
+        /* now loop over short lengths until buffer1 is encrypted */
+        current = buffer1;
+        end = buffer1 + buflen;
+        while (current < end) {
+            /* choose a short length */
+            len = srtp_cipher_rand_u32_for_tests() & 0x01f;
 
-      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;
+            /* 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;
+
+            /* 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;
-  octet_t *key;
-  cipher_t **cipher_array;
+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);
-  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 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] = (octet_t) random();
-    status = cipher_init(*cipher_array, key, direction_encrypt);
-    if (status)
-      return status;
+    /* allocate and initialize an array of ciphers */
+    for (i = 0; i < num_ciphers; i++) {
+        /* allocate cipher */
+        status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
+        if (status)
+            return status;
 
-/*     printf("%dth cipher is at %p\n", i, *cipher_array); */
-/*     printf("%dth cipher description: %s\n", i,  */
-/* 	   (*cipher_array)->type->description); */
-    
-    /* advance cipher array pointer */
-    cipher_array++;
-  }
+        /* generate random key and initialize cipher */
+        srtp_cipher_rand_for_tests(key, klen);
+        for (j = klen; j < klen_pad; j++)
+            key[j] = 0;
+        status = srtp_cipher_init(*cipher_array, key);
+        if (status)
+            return status;
 
-  return err_status_ok;
+        /*     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++;
+    }
+
+    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.0 is returned
+ * if an error is encountered, the value 0 is returned
  */
 
-#include <time.h>
+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 = srtp_cipher_rand_u32_for_tests() % num_cipher;
 
-double
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			     int octets_in_buffer, int num_trials) {
-  int i;
-  v128_t nonce;
-  clock_t timer;
-  unsigned char *enc_buf;
-  int cipher_index = 0;
+    /* 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 */
 
+    /* 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;
 
-  enc_buf = crypto_alloc(octets_in_buffer);
-  if (enc_buf == NULL)
-    return 0.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) {
+        /* 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);
 
-    /* choose a cipher at random from the array*/
-    cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
+        /* choose a cipher at random from the array*/
+        cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
+    }
+    timer = clock() - timer;
 
-    /* encrypt buffer with cipher */
-    cipher_set_iv(cipher_array[cipher_index], &nonce);
-    cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer);
-  }
-  timer = clock() - timer;
+    srtp_crypto_free(enc_buf);
 
-  free(enc_buf);
-  
-  return (double) CLOCKS_PER_SEC * num_trials
-    * 8 * octets_in_buffer / timer;
+    if (timer == 0) {
+        /* Too fast! */
+        return 0;
+    }
+
+    return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
 }
 
-void
-cipher_array_test_throughput(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 = 10000;
+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 array size %d:\n", 
-	 (ca[0])->type->description, 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;
 }
diff --git a/crypto/test/datatypes_driver.c b/crypto/test/datatypes_driver.c
index 1e315b6..96379be 100644
--- a/crypto/test/datatypes_driver.c
+++ b/crypto/test/datatypes_driver.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,112 +43,111 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <stdio.h>            /* for printf() */
-#include <string.h>           /* for strlen() */
+#include <stdio.h>  /* for printf() */
+#include <string.h> /* for strlen() */
 #include "datatypes.h"
+#include "util.h"
 
-void
-byte_order();
+void byte_order(void);
 
-void
-test_hex_string_funcs();
+void test_hex_string_funcs(void);
 
-void
-print_string(octet_t *s);
+void print_string(char *s);
 
-void
-test_bswap();
+void test_bswap(void);
 
-int
-main () {
-  
-  /*
-   * 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
-   */
+void test_set_to_zero(void);
 
-  int i, j;
-  v128_t x;
-  octet_t *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.";
-  octet_t *s = "incomplet"; 
- 
-  print_string(r);
-  print_string(s);
- 
-  byte_order();
-  test_hex_string_funcs();
+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
+     */
 
-  for (j=0; j < 128; j++) {
+    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();
+
+    for (j = 0; j < 128; j++) {
+        v128_set_to_zero(&x);
+        /*      x.v32[0] = (1 << j); */
+        v128_set_bit(&x, j);
+        printf("%s\n", v128_bit_string(&x));
+        v128_clear_bit(&x, j);
+        printf("%s\n", v128_bit_string(&x));
+    }
+
+    printf("----------------------------------------------\n");
     v128_set_to_zero(&x);
-    /*      x.v32[0] = (1 << j); */
-    v128_set_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    v128_clear_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    
-  }
+    for (i = 0; i < 128; i++) {
+        v128_set_bit(&x, i);
+    }
+    printf("%s\n", v128_bit_string(&x));
 
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  for (i=0; i < 128; i++) {
-    v128_set_bit(&x, i);
-  }
-  printf("%s\n", v128_bit_string(&x)); 
-
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  v128_set_bit(&x, 0);
-  for (i=0; i < 128; i++) {
-      printf("%s\n", v128_bit_string(&x)); 
-    v128_right_shift(&x, 1);
-  }
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  v128_set_bit(&x, 127);
-  for (i=0; i < 128; i++) {
-      printf("%s\n", v128_bit_string(&x)); 
-    v128_left_shift(&x, 1);
-  }
-  printf("----------------------------------------------\n");
-  for (i=0; i < 128; i++) {
+    printf("----------------------------------------------\n");
+    v128_set_to_zero(&x);
+    v128_set_bit(&x, 0);
+    for (i = 0; i < 128; i++) {
+        printf("%s\n", v128_bit_string(&x));
+        v128_right_shift(&x, 1);
+    }
+    printf("----------------------------------------------\n");
     v128_set_to_zero(&x);
     v128_set_bit(&x, 127);
-    v128_left_shift(&x, i);
-      printf("%s\n", v128_bit_string(&x)); 
-  }
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  for (i=0; i < 128; i+=2) {
-    v128_set_bit(&x, i);
-  }
-  printf("bit_string: { %s }\n", v128_bit_string(&x)); 
-  printf("get_bit:    { ");   
-  for (i=0; i < 128; i++) {
-    if (v128_get_bit(&x, i) == 1)
-      printf("1");
-    else
-      printf("0");
-  }
-  printf(" } \n");
+    for (i = 0; i < 128; i++) {
+        printf("%s\n", v128_bit_string(&x));
+        v128_left_shift(&x, 1);
+    }
+    printf("----------------------------------------------\n");
+    for (i = 0; i < 128; i++) {
+        v128_set_to_zero(&x);
+        v128_set_bit(&x, 127);
+        v128_left_shift(&x, i);
+        printf("%s\n", v128_bit_string(&x));
+    }
+    printf("----------------------------------------------\n");
+    v128_set_to_zero(&x);
+    for (i = 0; i < 128; i += 2) {
+        v128_set_bit(&x, i);
+    }
+    printf("bit_string: { %s }\n", v128_bit_string(&x));
+    printf("get_bit:    { ");
+    for (i = 0; i < 128; i++) {
+        if (v128_get_bit(&x, i) == 1)
+            printf("1");
+        else
+            printf("0");
+    }
+    printf(" } \n");
 
-  test_bswap();
+    test_bswap();
+    test_set_to_zero();
 
-  return 0;
+    return 0;
 }
 
-
 /* byte_order() prints out byte ordering of datatypes */
 
-void
-byte_order() {
-  int i;
-  v128_t e;
+void byte_order(void)
+{
+    int i;
+    v128_t e;
 #if 0
   v16_t b;
   v32_t c;
@@ -175,63 +174,83 @@
 
   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.octet[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() {
-  octet_t hex1[] = "abadcafe";
-  octet_t hex2[] = "0123456789abcdefqqqqq";
-  octet_t 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));
-  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));
-  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(octet_t *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() {
-  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, bswap_32(x));
-  printf("before: %0llx\nafter:  %0llx\n", y, bswap_64(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", y);
-  printf("as octet string: %s\n", 
-	 octet_string_hex_string((octet_t *) &y, 8));
-  y = bswap_64(y);
-  printf("bswapped octet string: %s\n", 
-	 octet_string_hex_string((octet_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));
+}
 
+void test_set_to_zero(void)
+{
+#define BUFFER_SIZE (16)
+    uint8_t buffer[BUFFER_SIZE];
+    size_t i;
+
+    for (i = 0; i < BUFFER_SIZE; i++) {
+        buffer[i] = i & 0xff;
+    }
+    printf("Buffer before: %s\n", octet_string_hex_string(buffer, BUFFER_SIZE));
+    octet_string_set_to_zero(buffer, BUFFER_SIZE);
+    printf("Buffer after: %s\n", octet_string_hex_string(buffer, BUFFER_SIZE));
+    for (i = 0; i < BUFFER_SIZE; i++) {
+        if (buffer[i]) {
+            fprintf(stderr,
+                    "Buffer contents not zero at position %zu (is %d)\n", i,
+                    buffer[i]);
+            abort();
+        }
+    }
+#undef BUFFER_SIZE
 }
diff --git a/crypto/test/env.c b/crypto/test/env.c
new file mode 100644
index 0000000..8c3f4ed
--- /dev/null
+++ b/crypto/test/env.c
@@ -0,0 +1,89 @@
+/*
+ * env.c
+ *
+ * prints out a brief report on the build environment
+ *
+ * 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>
+#include <string.h> /* for srtcmp() */
+#include "config.h"
+
+int main(void)
+{
+    int err_count = 0;
+
+#ifdef WORDS_BIGENDIAN
+    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");
+#endif
+
+#ifdef CPU_RISC
+    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");
+#else
+    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");
+#endif
+
+#ifndef NO_64BIT_MATH
+    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");
+#endif
+
+#ifdef ERR_REPORTING_STDOUT
+    printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
+#endif
+
+    if (err_count)
+        printf("warning: configuration is probably in error "
+               "(found %d problems)\n",
+               err_count);
+
+    return err_count;
+}
diff --git a/crypto/test/kernel_driver.c b/crypto/test/kernel_driver.c
index f7bd203..d29405a 100644
--- a/crypto/test/kernel_driver.c
+++ b/crypto/test/kernel_driver.c
@@ -7,26 +7,26 @@
  * 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
@@ -42,74 +42,76 @@
  *
  */
 
+#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");
-
-  /* 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]);
-    }    
-  }
-
-  if (do_validation) {
-    printf("checking crypto_kernel status...\n");
-    status = crypto_kernel_status();
+    /* initialize kernel - we need to do this before anything else */
+    status = srtp_crypto_kernel_init();
     if (status) {
-      printf("failed\n");
-      exit(1);
+        printf("error: srtp_crypto_kernel init failed\n");
+        exit(1);
     }
-    printf("crypto_kernel passed self-tests\n");
-  }
+    printf("srtp_crypto_kernel successfully initalized\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;
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "vd:");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 'v':
+            do_validation = 1;
+            break;
+        case 'd':
+            status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
+            if (status) {
+                printf("error: set debug module (%s) failed\n", optarg_s);
+                exit(1);
+            }
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (do_validation) {
+        printf("checking srtp_crypto_kernel status...\n");
+        status = srtp_crypto_kernel_status();
+        if (status) {
+            printf("failed\n");
+            exit(1);
+        }
+        printf("srtp_crypto_kernel passed self-tests\n");
+    }
+
+    status = srtp_crypto_kernel_shutdown();
+    if (status) {
+        printf("error: srtp_crypto_kernel shutdown failed\n");
+        exit(1);
+    }
+    printf("srtp_crypto_kernel successfully shut down\n");
+
+    return 0;
 }
 
 /*
@@ -117,10 +119,9 @@
  * of the crypto_kernel
  */
 
-err_status_t
-crypto_kernel_cipher_test() {
+srtp_err_status_t crypto_kernel_cipher_test(void)
+{
+    /* not implemented yet! */
 
-  /* not implemented yet! */
-
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
diff --git a/crypto/test/rand_gen.c b/crypto/test/rand_gen.c
deleted file mode 100644
index b4e590b..0000000
--- a/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-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#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) {
-    octet_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;
-}
-
diff --git a/crypto/test/sha1_driver.c b/crypto/test/sha1_driver.c
index d9bfa8b..c64b000 100644
--- a/crypto/test/sha1_driver.c
+++ b/crypto/test/sha1_driver.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,56 +43,345 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
+#include <string.h>
 #include "sha1.h"
+#include "util.h"
 
-int
-hmac_sha1_test();
+#define SHA_PASS 0
+#define SHA_FAIL 1
 
-int
-main () {
-  uint32_t hash_value[5];
-  octet_t msg_ref[3] = { 0x61, 0x62, 0x63 };
-  octet_t hash_ref[20] = {
-    0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
-    0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 
-    0x9c, 0xd0, 0xd8, 0x9d 
-  };
-  octet_t msg_ref2[56] = {
-    0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, 
-    0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67,
-    0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, 
-    0x67, 0x68, 0x69, 0x6a, 0x68, 0x69, 0x6a, 0x6b,
-    0x69, 0x6a, 0x6b, 0x6c, 0x6a, 0x6b, 0x6c, 0x6d,
-    0x6b, 0x6c, 0x6d, 0x6e, 0x6c, 0x6d, 0x6e, 0x6f,
-    0x6d, 0x6e, 0x6f, 0x70, 0x6e, 0x6f, 0x70, 0x71
-  };
-  octet_t hash_ref2[20] = {
-    0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 
-    0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
-    0xe5, 0x46, 0x70, 0xf1
-  };
-  sha1_ctx_t ctx;
+#define MAX_HASH_DATA_LEN 1024
+#define MAX_HASH_OUT_LEN 20
 
-  printf("sha1 test driver\n"
-         "David A. McGrew\n"
-         "Cisco Systems, Inc.\n");
+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;
+} hash_test_case_t;
 
-  sha1_init(&ctx);
-  sha1_update(&ctx, msg_ref, 3);
-  sha1_final(&ctx, hash_value);
-  printf("reference value: %s\n", 
-	 octet_string_hex_string((octet_t *)hash_ref, 20));
-  printf("computed value:  %s\n", 
-	 octet_string_hex_string((octet_t *)hash_value, 20));
+hash_test_case_t *sha1_test_case_list;
 
-  sha1_init(&ctx);
-  sha1_update(&ctx, msg_ref2, 56);
-  sha1_final(&ctx, hash_value);
-  printf("reference value: %s\n", 
-	 octet_string_hex_string((octet_t *)hash_ref2, 20));
-  printf("computed value:  %s\n", 
-	 octet_string_hex_string((octet_t *)hash_value, 20));
+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;
 
-  return 0;
+    test_case = malloc(sizeof(hash_test_case_t));
+    if (test_case == NULL)
+        return srtp_err_status_alloc_fail;
+
+    tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data,
+                                         data_len * 2);
+    if (tmp_len != data_len * 2) {
+        free(test_case);
+        return srtp_err_status_parse_err;
+    }
+
+    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;
+
+    /* add the new test case to the head of the list */
+    test_case->next_test_case = list_head;
+    *list_ptr = test_case;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t sha1_test_case_validate(const hash_test_case_t *test_case)
+{
+    srtp_sha1_ctx_t ctx;
+    uint32_t hash_value[5];
+
+    if (test_case == NULL)
+        return srtp_err_status_bad_param;
+
+    if (test_case->hash_len != 20)
+        return srtp_err_status_bad_param;
+    if (test_case->data_len > MAX_HASH_DATA_LEN)
+        return srtp_err_status_bad_param;
+
+    srtp_sha1_init(&ctx);
+    srtp_sha1_update(&ctx, test_case->data, test_case->data_len);
+    srtp_sha1_final(&ctx, hash_value);
+    if (0 == memcmp(test_case->hash, hash_value, 20)) {
+#if VERBOSE
+        printf("PASSED: reference value: %s\n",
+               octet_string_hex_string((const uint8_t *)test_case->hash, 20));
+        printf("PASSED: computed value:  %s\n",
+               octet_string_hex_string((const uint8_t *)hash_value, 20));
+#endif
+        return srtp_err_status_ok;
+    }
+
+    printf("reference value: %s\n",
+           octet_string_hex_string((const uint8_t *)test_case->hash, 20));
+    printf("computed value:  %s\n",
+           octet_string_hex_string((const uint8_t *)hash_value, 20));
+
+    return srtp_err_status_algo_fail;
+}
+
+struct hex_sha1_test_case_t {
+    unsigned bit_len;
+    char hex_data[MAX_HASH_DATA_LEN * 2];
+    char hex_hash[40];
+};
+
+srtp_err_status_t sha1_add_test_cases(void)
+{
+    int i;
+    srtp_err_status_t err;
+
+    /*
+     * 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, "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;
+        }
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t sha1_dealloc_test_cases(void)
+{
+    hash_test_case_t *t, *next;
+
+    for (t = sha1_test_case_list; t != NULL; t = next) {
+        next = t->next_test_case;
+        free(t);
+    }
+
+    sha1_test_case_list = NULL;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t sha1_validate(void)
+{
+    hash_test_case_t *test_case;
+    srtp_err_status_t err;
+
+    err = sha1_add_test_cases();
+    if (err) {
+        printf("error adding SHA1 test cases (error code %d)\n", err);
+        return err;
+    }
+
+    if (sha1_test_case_list == NULL)
+        return srtp_err_status_cant_check;
+
+    test_case = sha1_test_case_list;
+    while (test_case != NULL) {
+        err = sha1_test_case_validate(test_case);
+        if (err) {
+            printf("error validating hash test case (error code %d)\n", err);
+            return err;
+        }
+        test_case = test_case->next_test_case;
+    }
+
+    sha1_dealloc_test_cases();
+
+    return srtp_err_status_ok;
+}
+
+int main(void)
+{
+    srtp_err_status_t err;
+
+    printf("sha1 test driver\n");
+
+    err = sha1_validate();
+    if (err) {
+        printf("SHA1 did not pass validation testing\n");
+        return 1;
+    }
+    printf("SHA1 passed validation tests\n");
+
+    return 0;
 }
diff --git a/crypto/test/stat_driver.c b/crypto/test/stat_driver.c
index b1fdbf4..9a3d918 100644
--- a/crypto/test/stat_driver.c
+++ b/crypto/test/stat_driver.c
@@ -7,95 +7,246 @@
  * 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"
+#include "cipher_priv.h"
 
-typedef struct {
-  void *state;
-} random_source_t;
-
-err_status_t
-random_source_alloc();
-
-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[]) {
-  octet_t buffer[2500];
-  unsigned int buf_len = 2500;
-  int i, j;
-  extern cipher_type_t aes_icm;
-  cipher_t *c;
-  octet_t key[30] = {
-    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 GCM
+    extern srtp_cipher_type_t srtp_aes_gcm_128;
+    extern srtp_cipher_type_t srtp_aes_gcm_256;
+#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");
 
-  for (i=0; i < 2500; i++)
-    buffer[i] = 0;
+    v128_set_to_zero(&nonce);
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
 
-  /* run tests */
-  printf("running stat_tests on all-null buffer, expecting failure\n");
-  printf("monobit %d\n", stat_test_monobit(buffer));
-  printf("poker   %d\n", stat_test_poker(buffer));
-  printf("runs    %d\n", stat_test_runs(buffer));
+    /* run tests */
+    printf("running stat_tests on all-null buffer, expecting failure\n");
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
 
-  for (i=0; i < 2500; i++)
-    buffer[i] = random();
-  printf("running stat_tests on random(), 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));
+    srtp_cipher_rand_for_tests(buffer, 2500);
+    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(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("running stat_tests on AES-128-ICM, expecting success\n");
+    /* set buffer to cipher output */
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
+    err_check(srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
+                                     SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
+    err_check(srtp_cipher_init(c, key));
+    err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+    err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+    /* run tests on cipher outout */
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
 
-  printf("runs test (please be patient): ");
-  fflush(stdout);
-  num_fail = 0;
-  v128_set_to_zero(&nonce);
-  for(j=0; j < num_trials; j++) {
-    for (i=0; i < 2500; i++)
-      buffer[i] = 0;
-    nonce.v32[3] = i;
-    err_check(cipher_set_iv(c, &nonce));
-    err_check(cipher_encrypt(c, buffer, &buf_len));
-    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(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        if (stat_test_runs(buffer)) {
+            num_fail++;
+        }
     }
-  }
 
-  printf("%d failures in %d tests\n", num_fail, num_trials);
-  printf("(nota bene: a small fraction of stat_test failures does not \n"
-	 "indicate that the random source is invalid)\n");
+    printf("%d failures in %d tests\n", num_fail, num_trials);
+    printf("(nota bene: a small fraction of stat_test failures does not \n"
+           "indicate that the random source is invalid)\n");
 
-  return 0;
+    err_check(srtp_cipher_dealloc(c));
+
+    printf("running stat_tests on AES-256-ICM, expecting success\n");
+    /* set buffer to cipher output */
+    for (i = 0; i < 2500; i++)
+        buffer[i] = 0;
+    err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
+                                     SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
+    err_check(srtp_cipher_init(c, key));
+    err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+    err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+    /* run tests on cipher outout */
+    printf("monobit %d\n", stat_test_monobit(buffer));
+    printf("poker   %d\n", stat_test_poker(buffer));
+    printf("runs    %d\n", stat_test_runs(buffer));
+
+    printf("runs test (please be patient): ");
+    fflush(stdout);
+    num_fail = 0;
+    v128_set_to_zero(&nonce);
+    for (j = 0; j < num_trials; j++) {
+        for (i = 0; i < 2500; i++)
+            buffer[i] = 0;
+        nonce.v32[3] = i;
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        if (stat_test_runs(buffer)) {
+            num_fail++;
+        }
+    }
+
+#ifdef GCM
+    {
+        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, &c,
+                                         SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
+        err_check(srtp_cipher_init(c, key));
+        err_check(
+            srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
+        err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+        /* run tests on cipher outout */
+        printf("monobit %d\n", stat_test_monobit(buffer));
+        printf("poker   %d\n", stat_test_poker(buffer));
+        printf("runs    %d\n", stat_test_runs(buffer));
+        fflush(stdout);
+        num_fail = 0;
+        v128_set_to_zero(&nonce);
+        for (j = 0; j < num_trials; j++) {
+            for (i = 0; i < 2500; i++) {
+                buffer[i] = 0;
+            }
+            nonce.v32[3] = i;
+            err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
+                                         srtp_direction_encrypt));
+            err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
+            buf_len = 2500;
+            if (stat_test_runs(buffer)) {
+                num_fail++;
+            }
+        }
+
+        printf("running stat_tests on AES-256-GCM, expecting success\n");
+        /* set buffer to cipher output */
+        for (i = 0; i < 2500; i++) {
+            buffer[i] = 0;
+        }
+        err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256, &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");
+
+    err_check(srtp_cipher_dealloc(c));
+
+    return 0;
 }
diff --git a/doc/Doxyfile b/doc/Doxyfile
deleted file mode 100644
index 98a4e74..0000000
--- a/doc/Doxyfile
+++ /dev/null
@@ -1,1042 +0,0 @@
-# Doxyfile 1.3-rc3
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# General configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = libSRTP
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 1.3.22
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = 
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
-# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
-# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, 
-# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these class will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = NO
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show
-# all inherited members of a class in the documentation of that class
-# as if those members were ordinary class members. Constructors,
-# destructors and assignment operators of the base classes will not be
-# shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH        = 
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower case letters. If set to YES upper case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# users are adviced to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments  will behave just like the Qt-style comments (thus requiring an 
-# explict @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# reimplements.
-
-INHERIT_DOCS           = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 3
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consist of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
-# only. Doxygen will then generate output that is more tailored for C. 
-# For instance some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
-# only. Doxygen will then generate output that is more tailored for Java. 
-# For instance namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../include/err.h ../crypto/include/crypto_kernel.h  crypto_kernel.txt 
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
-# *.h++ *.idl *.odl
-
-FILE_PATTERNS          = 
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
-# that are symbolic links (a Unix filesystem feature) are excluded from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories.
-
-EXCLUDE_PATTERNS       = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.
-
-INPUT_FILTER           = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = NO
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output dir.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non empty doxygen will try to run 
-# the html help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the Html help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = YES
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = letter 
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = header.tex
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimised for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assigments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_XML           = NO
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse the 
-# parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tagfiles.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or 
-# super classes. Setting the tag to NO turns the diagrams off. Note that this 
-# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
-# recommended to install and use dot, since it yield more powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermedate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
-
-# The CGI_NAME tag should be the name of the CGI script that 
-# starts the search engine (doxysearch) with the correct parameters. 
-# A script with this name will be generated by doxygen.
-
-CGI_NAME               = search.cgi
-
-# The CGI_URL tag should be the absolute URL to the directory where the 
-# cgi binaries are located. See the documentation of your http daemon for 
-# details.
-
-CGI_URL                = 
-
-# The DOC_URL tag should be the absolute URL to the directory where the 
-# documentation is located. If left blank the absolute path to the 
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL                = 
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the 
-# documentation is located. If left blank the directory on the local machine 
-# will be used.
-
-DOC_ABSPATH            = 
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
-# is installed.
-
-BIN_ABSPATH            = /usr/local/bin/
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
-# documentation generated for other projects. This allows doxysearch to search 
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS          = 
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
new file mode 100644
index 0000000..129a03d
--- /dev/null
+++ b/doc/Doxyfile.in
@@ -0,0 +1,2412 @@
+# Doxyfile 1.8.11
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = libSRTP
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = LIBSRTPVERSIONNUMBER
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = ../README.md \
+                         ../include/srtp.h \
+                         ../crypto/include/auth.h \
+                         ../crypto/include/cipher.h \
+                         ../crypto/include/crypto_types.h \
+                         ../crypto/include/err.h \
+                         crypto_kernel.txt
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
+# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = README.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = NO
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = docs.css
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index bd6ef5d..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# Makefile for libSRTP documentation
-#
-# David A. McGrew
-# Cisco Systems, Inc.
-#
-# This makefile does not use the autoconf system; we don't really need
-# it.  We just run doxygen then latex.  If you don't have either of
-# these, then there is no way that you can make your own
-# documentation.  Of course, you can just go online at pick up the
-# documentation from http://srtp.sourceforge.net.
-
-.PHONY: libsrtpdoc cryptodoc clean
-libsrtpdoc: clean
-	doxygen
-	sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp
-	mv latex/index.tmp latex/index.tex
-	cd latex; make
-	cp latex/refman.pdf libsrtp.pdf
-
-
-cryptodoc: clean
-	doxygen crypto.dox
-	# sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp
-	# mv latex/index.tmp latex/index.tex
-	cd latex; make
-	cp latex/refman.pdf crypto.pdf
-
-clean:
-	rm -rf latex/ 
-	for a in * ; do			                \
-              if [ -f "$$a~" ] ; then rm -f $$a~; fi;	\
-        done;
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..830ccbb
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,32 @@
+# Makefile for libSRTP documentation
+#
+# David A. McGrew
+# Cisco Systems, Inc.
+#
+# This makefile does not use the autoconf system; we don't really need
+# it. We just run doxygen.
+# The most up to date documentation can be found at www.github.com/cisco/libsrtp
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+# Determine the version of the library
+
+version = $(shell cat $(top_srcdir)/VERSION)
+
+.PHONY: libsrtpdoc clean
+libsrtpdoc:
+	@if test ! -e Doxyfile.in; then \
+		echo "*** Sorry, can't build doc outside source dir"; exit 1; \
+	fi
+	sed 's/LIBSRTPVERSIONNUMBER/$(version)/' Doxyfile.in > Doxyfile
+	doxygen
+
+clean:
+
+	rm -rf html/ Doxyfile
+	for a in * ; do							\
+			  if [ -f "$$a~" ] ; then rm -f $$a~; fi;	\
+		done;
diff --git a/doc/crypto_kernel.txt b/doc/crypto_kernel.txt
index e0f97ed..b0d033f 100644
--- a/doc/crypto_kernel.txt
+++ b/doc/crypto_kernel.txt
@@ -35,7 +35,7 @@
  */
 
 err_status_t
-cipher_init(cipher_t *cipher, const octet_t *key);
+cipher_init(cipher_t *cipher, const uint8_t *key);
 
 /**
  * @brief Sets the initialization vector of a given cipher.
@@ -58,7 +58,7 @@
  * @warning May be implemented as a macro.
  */
 err_status_t 
-cipher_output(cipher_t *c, octet_t *buffer, int num_octets_to_output);
+cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);
 
 /**
  * @brief Deallocates a cipher.
diff --git a/doc/docs.css b/doc/docs.css
new file mode 100644
index 0000000..0361116
--- /dev/null
+++ b/doc/docs.css
@@ -0,0 +1,1479 @@
+/* The standard CSS for doxygen 1.8.11 */
+
+body, table, div, p, dl {
+    font: 400 14px/22px Roboto,sans-serif;
+}
+
+body {
+    max-width: 800px;
+    margin: 0 auto;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+	font-size: 150%;
+}
+
+.title {
+	font: 400 14px/28px Roboto,sans-serif;
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2.groupheader {
+	border-bottom: 1px solid #879ECB;
+	color: #354C7B;
+	font-size: 150%;
+	font-weight: normal;
+	margin-top: 1.75em;
+	padding-top: 8px;
+	padding-bottom: 4px;
+	width: 100%;
+}
+
+h3.groupheader {
+	font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	-webkit-transition: text-shadow 0.5s linear;
+	-moz-transition: text-shadow 0.5s linear;
+	-ms-transition: text-shadow 0.5s linear;
+	-o-transition: text-shadow 0.5s linear;
+	transition: text-shadow 0.5s linear;
+	margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+	text-shadow: 0 0 15px cyan;
+}
+
+dt {
+	font-weight: bold;
+}
+
+div.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+}
+
+p.startli, p.startdd {
+	margin-top: 2px;
+}
+
+p.starttd {
+	margin-top: 0px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+}
+
+div.qindex, div.navpath {
+	width: 100%;
+	line-height: 140%;
+}
+
+div.navtab {
+	margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+a.qindex {
+	font-weight: bold;
+}
+
+a.qindexHL {
+	font-weight: bold;
+	background-color: #9CAFD4;
+	color: #ffffff;
+	border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+	color: #4665A2; 
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+	color: #4665A2; 
+}
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+pre.fragment {
+        border: 1px solid #C4CFE5;
+        background-color: #FBFCFD;
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+        overflow: auto;
+        word-wrap: break-word;
+        font-size:  9pt;
+        line-height: 125%;
+        font-family: monospace, fixed;
+        font-size: 105%;
+}
+
+div.fragment {
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+	background-color: #FBFCFD;
+	border: 1px solid #C4CFE5;
+}
+
+div.line {
+	font-family: monospace, fixed;
+        font-size: 13px;
+	min-height: 13px;
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px;
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+div.line:after {
+    content:"\000A";
+    white-space: pre;
+}
+
+div.line.glow {
+	background-color: cyan;
+	box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+	padding-right: 4px;
+	text-align: right;
+	border-right: 2px solid #0F0;
+	background-color: #E8E8E8;
+        white-space: pre;
+}
+span.lineno a {
+	background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+	background-color: #C8C8C8;
+}
+
+div.ah, span.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #ffffff;
+    margin-bottom: 3px;
+    	margin-top: 3px;
+    padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%);
+}
+
+div.classindex ul {
+        list-style: none;
+        padding-left: 0;
+}
+
+div.classindex span.ai {
+        display: inline-block;
+}
+
+div.groupHeader {
+    margin-left: 16px;
+	   margin-top: 12px;
+    font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background-color: white;
+	color: black;
+}
+
+div.contents {
+	margin-top: 10px;
+	margin-left: 12px;
+	margin-right: 8px;
+}
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+        white-space: nowrap;
+        vertical-align: top;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+	
+}
+
+img.formulaInl {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit { 
+	color: #ff00ff 
+}
+
+span.vhdlchar { 
+	color: #000000 
+}
+
+span.vhdlkeyword { 
+	color: #700070 
+}
+
+span.vhdllogic { 
+	color: #ff0000 
+}
+
+blockquote {
+        background-color: #F7F8FB;
+        border-left: 2px solid #9CAFD4;
+        margin: 0 24px 0 4px;
+        padding: 0 12px 0 16px;
+}
+
+/* @end */
+
+
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+	background-color: cyan;
+	box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memSeparator {
+        border-bottom: 1px solid #DEE4F0;
+        line-height: 1px;
+        margin: 0px;
+        padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memItemRight {
+	width: 100%;
+}
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+	font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+    	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+    	margin-right: 5px;
+        -webkit-transition: box-shadow 0.5s linear;
+        -moz-transition: box-shadow 0.5s linear;
+        -ms-transition: box-shadow 0.5s linear;
+        -o-transition: box-shadow 0.5s linear;
+        transition: box-shadow 0.5s linear;
+        display: table !important;
+        width: 100%;
+}
+
+.memitem.glow {
+         box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memname td {
+	vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 4px;
+        -moz-border-radius-topleft: 4px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 4px;
+        -webkit-border-top-left-radius: 4px;
+
+}
+
+.memdoc, dl.reflist dd {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 6px 10px 2px 10px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        background-image:url('nav_g.png');
+        background-repeat:repeat-x;
+        background-color: #FFFFFF;
+        /* opera specific markup */
+        border-bottom-left-radius: 4px;
+        border-bottom-right-radius: 4px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 4px;
+        -moz-border-radius-bottomright: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 4px;
+        -webkit-border-bottom-right-radius: 4px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+        padding: 5px;
+}
+
+dl.reflist dd {
+        margin: 0px 0px 10px 0px;
+        padding: 5px;
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+.paramname code {
+        line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+        margin-left: 0px;
+        padding-left: 0px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+table.mlabels {
+	border-spacing: 0px;
+}
+
+td.mlabels-left {
+	width: 100%;
+	padding: 0px;
+}
+
+td.mlabels-right {
+	vertical-align: bottom;
+	padding: 0px;
+	white-space: nowrap;
+}
+
+span.mlabels {
+        margin-left: 8px;
+}
+
+span.mlabel {
+        background-color: #728DC1;
+        border-top:1px solid #5373B4;
+        border-left:1px solid #5373B4;
+        border-right:1px solid #C4CFE5;
+        border-bottom:1px solid #C4CFE5;
+	text-shadow: none;
+	color: white;
+	margin-right: 4px;
+	padding: 2px 3px;
+	border-radius: 3px;
+	font-size: 7pt;
+	white-space: nowrap;
+	vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+        margin: 10px 0px;
+        border-top: 1px solid #9CAFD4;
+        border-bottom: 1px solid #9CAFD4;
+        width: 100%;
+}
+
+.directory table {
+        border-collapse:collapse;
+}
+
+.directory td {
+        margin: 0px;
+        padding: 0px;
+	vertical-align: top;
+}
+
+.directory td.entry {
+        white-space: nowrap;
+        padding-right: 6px;
+	padding-top: 3px;
+}
+
+.directory td.entry a {
+        outline:none;
+}
+
+.directory td.entry a img {
+        border: none;
+}
+
+.directory td.desc {
+        width: 100%;
+        padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 3px;
+	border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+	padding-left: 6px;
+	background-color: #F7F8FB;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+.directory .levels {
+        white-space: nowrap;
+        width: 100%;
+        text-align: right;
+        font-size: 9pt;
+}
+
+.directory .levels span {
+        cursor: pointer;
+        padding-left: 2px;
+        padding-right: 2px;
+	color: #3D578C;
+}
+
+.arrow {
+    color: #9CAFD4;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    cursor: pointer;
+    font-size: 80%;
+    display: inline-block;
+    width: 16px;
+    height: 22px;
+}
+
+.icon {
+    font-family: Arial, Helvetica;
+    font-weight: bold;
+    font-size: 12px;
+    height: 14px;
+    width: 16px;
+    display: inline-block;
+    background-color: #728DC1;
+    color: white;
+    text-align: center;
+    border-radius: 4px;
+    margin-left: 2px;
+        margin-right: 2px;
+}
+
+.icona {
+    width: 24px;
+    height: 22px;
+    display: inline-block;
+}
+
+.iconfopen {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('folderopen.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.iconfclosed {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('folderclosed.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.icondoc {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('doc.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+table.directory {
+    font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable caption {
+	caption-side: top;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+        margin-top: 4px;
+        margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+}
+
+table.fieldtable {
+        width: 100%;
+        margin-bottom: 10px;
+        border: 1px solid #A8B8D9;
+        border-spacing: 0px;
+        -moz-border-radius: 4px;
+        -webkit-border-radius: 4px;
+        border-radius: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+        padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+        white-space: nowrap;
+        border-right: 1px solid #A8B8D9;
+        border-bottom: 1px solid #A8B8D9;
+        vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+        padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+        border-bottom: 1px solid #A8B8D9;
+        width: 100%;
+}
+
+.fieldtable td.fielddoc p:first-child {
+        margin-top: 0px;
+}       
+        
+.fieldtable td.fielddoc p:last-child {
+        margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+        border-bottom: none;
+}
+
+.fieldtable th {
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        font-size: 90%;
+        color: #253555;
+        padding-bottom: 4px;
+        padding-top: 5px;
+        text-align:left;
+        -moz-border-radius-topleft: 4px;
+        -moz-border-radius-topright: 4px;
+        -webkit-border-top-left-radius: 4px;
+        -webkit-border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        border-top-right-radius: 4px;
+        border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	background-position: 0 -5px;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+	color: #283A5D;
+	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+	text-decoration: none;        
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}       
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+table.classindex
+{
+        margin: 10px;
+        white-space: nowrap;
+        margin-left: 3%;
+        margin-right: 3%;
+        width: 94%;
+        border: 0;
+        border-spacing: 0; 
+        padding: 0;
+}
+
+div.ingroups
+{
+	font-size: 8pt;
+	width: 50%;
+	text-align: left;
+}
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
+dl.section
+{
+	margin-left: 0px;
+	padding-left: 0px;
+}
+
+dl.note
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #D0C000;
+}
+
+dl.warning, dl.attention
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #505050;
+}
+
+dl.todo
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        margin-left:-7px;
+        padding-left: 3px;
+        border-left:4px solid;
+        border-color: #C08050;
+}
+
+dl.section dd {
+	margin-bottom: 6px;
+}
+
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+ 
+#projectlogo img
+{ 
+	border: 0px none;
+}
+ 
+#projectalign
+{
+        vertical-align: middle;
+}
+
+#projectname
+{
+	font: 300% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+    
+#projectbrief
+{
+	font: 120% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+        text-align: center;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.diagraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
+div.zoom
+{
+	border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+        margin-bottom:50px;
+}
+
+dl.citelist dt {
+        color:#334975;
+        float:left;
+        font-weight:bold;
+        margin-right:10px;
+        padding:5px;
+}
+
+dl.citelist dd {
+        margin:2px 0;
+        padding:5px 0;
+}
+
+div.toc {
+        padding: 14px 25px;
+        background-color: #F4F6FA;
+        border: 1px solid #D8DFEE;
+        border-radius: 7px 7px 7px 7px;
+        float: right;
+        height: auto;
+        margin: 0 8px 10px 10px;
+        width: 200px;
+}
+
+div.toc li {
+        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+        margin-top: 5px;
+        padding-left: 10px;
+        padding-top: 2px;
+}
+
+div.toc h3 {
+        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+	color: #4665A2;
+        border-bottom: 0 none;
+        margin: 0;
+}
+
+div.toc ul {
+        list-style: none outside none;
+        border: medium none;
+        padding: 0px;
+}       
+
+div.toc li.level1 {
+        margin-left: 0px;
+}
+
+div.toc li.level2 {
+        margin-left: 15px;
+}
+
+div.toc li.level3 {
+        margin-left: 30px;
+}
+
+div.toc li.level4 {
+        margin-left: 45px;
+}
+
+.inherit_header {
+        font-weight: bold;
+        color: gray;
+        cursor: pointer;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.inherit_header td {
+        padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+        display: none;
+}
+
+tr.heading h2 {
+        margin-top: 12px;
+        margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+        position: absolute;
+        display: none;
+}
+
+#powerTip {
+	cursor: default;
+	white-space: nowrap;
+	background-color: white;
+	border: 1px solid gray;
+	border-radius: 4px 4px 4px 4px;
+	box-shadow: 1px 1px 7px gray;
+	display: none;
+	font-size: smaller;
+	max-width: 80%;
+	opacity: 0.9;
+	padding: 1ex 1em 1em;
+	position: absolute;
+	z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+        color: grey;
+	font-style: italic;
+}
+
+#powerTip div.ttname a {
+        font-weight: bold;
+}
+
+#powerTip div.ttname {
+        font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+        color: #006318;
+}
+
+#powerTip div {
+        margin: 0px;
+        padding: 0px;
+        font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+	content: "";
+	position: absolute;
+	margin: 0px;
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.w:after,  #powerTip.w:before,
+#powerTip.e:after,  #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	border: solid transparent;
+	content: " ";
+	height: 0;
+	width: 0;
+	position: absolute;
+}
+
+#powerTip.n:after,  #powerTip.s:after,
+#powerTip.w:after,  #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+	border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before,  #powerTip.s:before,
+#powerTip.w:before,  #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+	border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+	top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+	border-top-color: #ffffff;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+#powerTip.n:before {
+	border-top-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+	left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+	right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+	left: 14px;
+}
+
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+	border-bottom-color: #ffffff;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+	border-bottom-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+	left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+	right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+	left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+	left: 100%;
+}
+#powerTip.e:after {
+	border-left-color: #ffffff;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.e:before {
+	border-left-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+	right: 100%;
+}
+#powerTip.w:after {
+	border-right-color: #ffffff;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.w:before {
+	border-right-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+@media print
+{
+  #top { display: none; }
+  #side-nav { display: none; }
+  #nav-path { display: none; }
+  body { overflow:visible; }
+  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+  .summary { display: none; }
+  .memitem { page-break-inside: avoid; }
+  #doc-content
+  {
+    margin-left:0 !important;
+    height:auto !important;
+    width:auto !important;
+    overflow:inherit;
+    display:inline;
+  }
+}
+
diff --git a/doc/draft-irtf-cfrg-icm-00.txt b/doc/draft-irtf-cfrg-icm-00.txt
deleted file mode 100644
index ddfce33..0000000
--- a/doc/draft-irtf-cfrg-icm-00.txt
+++ /dev/null
Binary files differ
diff --git a/doc/header.tex b/doc/header.tex
deleted file mode 100644
index bcec762..0000000
--- a/doc/header.tex
+++ /dev/null
@@ -1,108 +0,0 @@
-% header.tex
-% 
-% header file for the libSRTP documentation - based on the header
-% file generated by doxygen, with the initial chapters of the 
-% original libSRTP documentation tacked on
-% 
-\documentclass[letterpaper]{book}
-\usepackage{makeidx}
-\usepackage{fancyhdr}
-\usepackage{graphicx}
-\usepackage{multicol}
-\usepackage{float}
-\usepackage{textcomp}
-\usepackage{alltt}
-\usepackage{times}
-\ifx\pdfoutput\undefined
-\usepackage[ps2pdf,
-            pagebackref=true,
-            colorlinks=true,
-            linkcolor=blue
-           ]{hyperref}
-\else
-\usepackage[pdftex,
-            pagebackref=true,
-            colorlinks=true,
-            linkcolor=blue
-           ]{hyperref}
-\fi
-\usepackage{doxygen}
-\makeindex
-\setcounter{tocdepth}{1}
-\setlength{\footrulewidth}{0.4pt}
-
-% these lengths are from DAM
-\textwidth = 6.5 in
-%\textheight = 9 in
-\oddsidemargin = 0.0 in
-\evensidemargin = 0.0 in
-\topmargin = 0.0 in
-\headheight = 0.0 in
-%\headsep = 0.0 in
-\parskip = 0.2in
-\parindent = 0.0in
-
-% these header and footer definitions from DAM
-\lhead{libSRTP}
-\chead{}
-\rhead{\rightmark}
-%\rhead{\slshape }
-\lfoot{}
-\cfoot{ \thepage }
-\rfoot{}
-%\fancyhead[LE,RO]{\rightmark }
-%\fancyhead[LO,RE]{\slshape }
-
-% let's use the palatino font
-\fontfamily{ppl}
-\selectfont
-
-
-\begin{document}
-\begin{titlepage}
-\vspace*{7cm}
-%\begin{center}
-{\Huge 
-libSRTP 1.4 Overview and Reference Manual\\
-  \hrulefill
-}\\
-\vspace*{1cm}
-\begin{flushright}
-{\Large David A. McGrew \\ \texttt{mcgrew@cisco.com} }\\
-\vspace*{0.5cm}
-\end{flushright}
-%\end{center}
-\end{titlepage}
-
-
-\clearemptydoublepage
-\vspace*{3cm}
-{\LARGE Preface}
-\vspace{1cm}
-
-The original implementation and documentation of libSRTP was written
-by David McGrew of Cisco Systems, Inc. in order to promote the use,
-understanding, and interoperability of Secure RTP.  Randell Jesup
-contributed a working SRTCP implementation and other fixes.  Alex
-Vanzella and Will Clark contributed changes so that the AES ICM
-implementation can be used for ISMA media encryption.  Steve Underwood
-contributed x86\_64 portability changes.  We also give thanks to Brian
-Weis, Mark Baugher, Jeff Chan, Bill Simon, Douglas Smith, Bill May,
-Richard Preistley, Joe Tardo and others for contributions, comments,
-and corrections.
-
-This reference material in this documenation was generated using the
-\texttt{doxygen} utility for automatic documentation of source code.
-
-\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc.
-\thispagestyle{empty}
-
-\clearemptydoublepage
-\pagenumbering{roman}
-\tableofcontents
-%\clearemptydoublepage
-
-\clearemptydoublepage
-\pagenumbering{arabic}
-
-
diff --git a/doc/intro.txt b/doc/intro.txt
deleted file mode 100644
index aa8435c..0000000
--- a/doc/intro.txt
+++ /dev/null
@@ -1,376 +0,0 @@
-/**
- 
-@mainpage Introduction to libSRTP
- 
-This document describes libSRTP, the Open Source Secure RTP library
-from Cisco Systems, Inc.  RTP is the Real-time Transport Protocol, an
-IETF standard for the transport of real-time data such as telephony,
-audio, and video, defined by RFC1889.  Secure RTP (SRTP) is an RTP
-profile for providing confidentiality to RTP data and authentication
-to the RTP header and payload.  SRTP is an IETF Proposed Standard, and
-is defined in RFC 3711, and was developed in the IETF Audio/Video
-Transport (AVT) Working Group.  This library supports all of the
-mandatory features of SRTP, but not all of the optional features.  See
-the @ref Features section for more detailed information.
- 
-This document is organized as follows.  The first chapter provides 
-background material on SRTP and overview of libSRTP.  The following
-chapters provide a detailed reference to the libSRTP API and related
-functions.  The reference material is created automatically (using the
-doxygen utility) from comments embedded in some of the C header
-files. The documentation is organized into modules in order to improve
-its clarity.  These modules do not directly correspond to files. An
-underlying cryptographic kernel provides much of the basic
-functionality of libSRTP, but is mostly undocumented because it does
-its work behind the scenes.
-
-@section LICENSE License and Disclaimer
-
-libSRTP is distributed under the following license, which is included
-in the source code distribution.  It is reproduced in the manual in
-case you got the library from another source.
-	
-@latexonly
-\begin{quote}
-Copyright (c) 2001-2005 Cisco Systems, Inc.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-\begin{itemize}
-\item  Redistributions of source code must retain the above copyright
-  notice, this list of conditions and the following disclaimer.
-\item Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the following
-  disclaimer in the documentation and/or other materials provided
-  with the distribution.
-\item Neither the name of the Cisco Systems, Inc. nor the names of its
-  contributors may be used to endorse or promote products derived
-  from this software without specific prior written permission.
-\end{itemize}
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
-\end{quote}
-@endlatexonly
-
-@section Features Supported Features
-
-This library supports all of the mandatory-to-implement features of
-SRTP (as defined by the most recent Internet Draft).  Some of these
-features can be selected (or de-selected) at run time by setting an
-appropriate policy; this is done using the structure srtp_policy_t.
-Some other behaviors of the protocol can be adapted by defining an
-approriate event handler for the exceptional events; see the @ref
-SRTPevents section.  
-
-Some options that are not included in the specification are supported.
-Most notably, the TMMH authentication function is included, though it
-was removed from the SRTP Internet Draft during the summer of 2002.
-
-
-@latexonly
-Some options that are described in the SRTP specification are not
-supported.  This includes 
-\begin{itemize}
-\item the Master Key Index (MKI),
-\item key derivation rates other than zero,
-\item the cipher F8,
-\item anti-replay lists with sizes other than 128,
-\item the use of the packet index to select between master keys.
-\end{itemize}
-@endlatexonly
- 
-The user should be aware that it is possible to misuse this libary,
-and that the result may be that the security level it provides is
-inadequate.  If you are implementing a feature using this library, you
-will want to read the Security Considerations section of the Internet
-Draft.  In addition, it is important that you read and understand the
-terms outlined in the @ref LICENSE section.
-
-
-@section Installing Installing and Building libSRTP
-
-@latexonly
-
-To install libSRTP, download the latest release of the distribution
-from \texttt{srtp.sourceforge.net}.  The format of the names of the
-distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the
-version number, \texttt{B} is the major release number, \texttt{C} is
-the minor release number, and \texttt{tgz} is the file
-extension\footnote{The extension \texttt{.tgz} is identical to
-\texttt{tar.gz}, and indicates a compressed tar file.}  You probably
-want to get the most recent release.  Unpack the distribution and
-extract the source files; the directory into which the soruce files
-will go is named \texttt{srtp}.
-
-libSRTP uses the GNU \texttt{autoconf} and \texttt{make}
-utilities\footnote{BSD make will not work; if both versions of make
-are on your platform, you can invoke GNU make as \texttt{gmake}.}.  In
-the \texttt{srtp} directory, run the configure script and then make:
-\begin{verbatim}
-  ./configure [ options ]       
-  make                          
-\end{verbatim}
-The configure script accepts the following options:
-\begin{quote}
-\begin{description}
-\item[--help]              provides a usage summary.
-\item[--disable-debug]     compiles libSRTP without the runtime 
-			   dynamic debugging system.
-\item[--enable-generic-aesicm] compile in changes for ismacryp
-\item[--enable-syslog]     use syslog for error reporting.
-\item[--disable-stdout]    diables stdout for error reporting.
-\item[--enable-console]    use \texttt{/dev/console} for error reporting
-\item[--gdoi]              use GDOI key management (disabled at present).
-\end{description}
-\end{quote}
-
-By default, dynamic debbuging is enabled and stdout is used for
-debugging.  You can use the configure options to have the debugging
-output sent to syslog or the system console.  Alternatively, you can
-define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other
-file that can be opened by libSRTP, and debug messages will be sent to
-it.
-
-This package has been tested on the following platforms: Mac OS X
-(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
-(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and
-OpenBSD (sparc-unknown-openbsd2.7).
-
-
-@endlatexonly
-
-@section Applications Applications
-
-@latexonly
-
-Several test drivers and a simple and portable srtp application are
-included in the \texttt{test/} subdirectory.
-
-\begin{center}
-\begin{tabular}{ll}
-\hline
-Test driver    	& Function tested	\\
-\hline
-kernel\_driver   & crypto kernel (ciphers, auth funcs, rng) \\
-srtp\_driver	& srtp in-memory tests (does not use the network) \\
-rdbx\_driver	& rdbx (extended replay database) \\
-roc\_driver	& extended sequence number functions \\ 
-replay\_driver	& replay database  \\
-cipher\_driver	& ciphers  \\
-auth\_driver	& hash functions \\
-\hline
-\end{tabular}
-\end{center}
-
-The app rtpw is a simple rtp application which reads words from
-/usr/dict/words and then sends them out one at a time using [s]rtp.
-Manual srtp keying uses the -k option; automated key management
-using gdoi will be added later.
-
-The usage for rtpw is
-
-\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip
-dest\_port][-l]}
-
-Either the -s (sender) or -r (receiver) option must be chosen.  The
-values dest\_ip, dest\_port are the IP address and UDP port to which
-the dictionary will be sent, respectively.  The options are:
-\begin{center}
-\begin{tabular}{ll}
-  -s		& (S)RTP sender - causes app to send words \\
-  -r		& (S)RTP receive - causes app to 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 the avaliable debug modules \\
-  -d $<$debug$>$    & turn on debugging for module $<$debug$>$ \\
-\end{tabular}
-\end{center}
-
-In order to get a random 30-byte value for use as a key/salt pair, you
-can use the \texttt{rand\_gen} utility in the \texttt{test/}
-subdirectory.
-
-An example of an SRTP session using two rtpw programs follows:
-
-\begin{verbatim}
-[sh1] set k=`test/rand_gen -n 30`
-[sh1] echo $k
-c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
-[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999 
-Security services: confidentiality message authentication
-set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
-setting SSRC to 2078917053
-sending word: A
-sending word: a
-sending word: aa
-sending word: aal
-sending word: aalii
-sending word: aam
-sending word: Aani
-sending word: aardvark
-...
-
-[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
-[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999 
-security services: confidentiality message authentication
-set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
-19 octets received from SSRC 2078917053 word: A
-19 octets received from SSRC 2078917053 word: a
-20 octets received from SSRC 2078917053 word: aa
-21 octets received from SSRC 2078917053 word: aal
-...
-\end{verbatim}
-
-
-@endlatexonly
-
-
-@section Review Secure RTP Background
-
-In this section we review SRTP and introduce some terms that are used
-in libSRTP.  An RTP session is defined by a pair of destination
-transport addresses, that is, a network address plus a pair of UDP
-ports for RTP and RTCP.  RTCP, the RTP control protocol, is used to
-coordinate between the participants in an RTP session, e.g. to provide
-feedback from receivers to senders.  An @e SRTP @e session is
-similarly defined; it is just an RTP session for which the SRTP
-profile is being used.  An SRTP session consists of the traffic sent
-to the SRTP or SRTCP destination transport addresses.  Each
-participant in a session is identified by a synchronization source
-(SSRC) identifier.  Some participants may not send any SRTP traffic;
-they are called receivers, even though they send out SRTCP traffic,
-such as receiver reports.
-
-RTP allows multiple sources to send RTP and RTCP traffic during the
-same session.  The synchronization source identifier (SSRC) is used to
-distinguish these sources.  In libSRTP, we call the SRTP and SRTCP
-traffic from a particular source a @e stream.  Each stream has its own
-SSRC, sequence number, rollover counter, and other data.  A particular
-choice of options, cryptographic mechanisms, and keys is called a @e
-policy.  Each stream within a session can have a distinct policy
-applied to it.  A session policy is a collection of stream policies.
-
-A single policy can be used for all of the streams in a given session,
-though the case in which a single @e key is shared across multiple
-streams requires care.  When key sharing is used, the SSRC values that
-identify the streams @b must be distinct.  This requirement can be
-enforced by using the convention that each SRTP and SRTCP key is used
-for encryption by only a single sender.  In other words, the key is
-shared only across streams that originate from a particular device (of
-course, other SRTP participants will need to use the key for
-decryption).  libSRTP supports this enforcement by detecting the case
-in which a key is used for both inbound and outbound data.
-
-
-@section Overview libSRTP Overview
-
-libSRTP provides functions for protecting RTP and RTCP.  RTP packets
-can be encrypted and authenticated (using the srtp_protect()
-function), turning them into SRTP packets.  Similarly, SRTP packets
-can be decrypted and have their authentication verified (using the
-srtp_unprotect() function), turning them into RTP packets.  Similar
-functions apply security to RTCP packets.
-
-The typedef srtp_stream_t points to a structure holding all of the
-state associated with an SRTP stream, including the keys and
-parameters for cipher and message authentication functions and the
-anti-replay data.  A particular srtp_stream_t holds the information
-needed to protect a particular RTP and RTCP stream.  This datatype
-is intentionally opaque in order to better seperate the libSRTP
-API from its implementation.
-
-Within an SRTP session, there can be multiple streams, each
-originating from a particular sender.  Each source uses a distinct
-stream context to protect the RTP and RTCP stream that it is
-originating.  The typedef srtp_t points to a structure holding all of
-the state associated with an SRTP session.  There can be multiple
-stream contexts associated with a single srtp_t.  A stream context
-cannot exist indepent from an srtp_t, though of course an srtp_t can
-be created that contains only a single stream context.  A device
-participating in an SRTP session must have a stream context for each
-source in that session, so that it can process the data that it
-receives from each sender.
-
-
-In libSRTP, a session is created using the function srtp_create().
-The policy to be implemented in the session is passed into this
-function as an srtp_policy_t structure.  A single one of these
-structures describes the policy of a single stream.  These structures
-can also be linked together to form an entire session policy.  A linked
-list of srtp_policy_t structures is equivalent to a session policy.  
-In such a policy, we refer to a single srtp_policy_t as an @e element.
-
-An srtp_policy_t strucutre contains two crypto_policy_t structures
-that describe the cryptograhic policies for RTP and RTCP, as well as
-the SRTP master key and the SSRC value.  The SSRC describes what to
-protect (e.g. which stream), and the crypto_policy_t structures
-describe how to protect it.  The key is contained in a policy element
-because it simplifies the interface to the library.  In many cases, it
-is desirable to use the same cryptographic policies across all of the
-streams in a session, but to use a distinct key for each stream.  A
-crypto_policy_t structure can be initialized by using either the
-crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default()
-functions, which set a crypto policy structure to the default policies
-for RTP and RTCP protection, respectively.
-				   
-@section Example Example Code
-
-This section provides a simple example of how to use libSRTP.  The
-example code lacks error checking, but is functional.  Here we assume
-that the value ssrc is already set to describe the SSRC of the stream
-that we are sending, and that the functions get_rtp_packet() and
-send_srtp_packet() are available to us.  The former puts an RTP packet
-into the buffer and returns the number of octets written to that
-buffer.  The latter sends the RTP packet in the buffer, given the
-length as its second argument.
-
-@verbatim
-   srtp_t session;   
-   srtp_policy_t policy;
-   octet_t key[30];
-
-   /* initialize libSRTP */
-   srtp_init();                                  
-
-   /* set policy to describe a policy for an SRTP stream */
-   crypto_policy_set_rtp_default(&policy.rtp);   
-   crypto_policy_set_rtcp_default(&policy.rtcp); 
-   policy.ssrc = ssrc;                            
-   policy.key  = key;
-   policy.next = NULL;
-
-   /* set key to random value */
-   crypto_get_random(key, 30);          
-
-   /* allocate and initialize the SRTP session */
-   srtp_create(&session, policy);  
-   
-   /* main loop: get rtp packets, send srtp packets */
-   while (1) {
-      char rtp_buffer[2048];
-      unsigned len;
-
-      len = get_rtp_packet(rtp_buffer);
-      srtp_protect(session, rtp_buffer, &len);
-      send_srtp_packet(rtp_buffer, len);
-   }
-@endverbatim
-
-
- */
diff --git a/doc/libsrtp.pdf b/doc/libsrtp.pdf
deleted file mode 100644
index 491964f..0000000
--- a/doc/libsrtp.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/references.txt b/doc/references.txt
deleted file mode 100644
index 2ec9d43..0000000
--- a/doc/references.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-SRTP and ICM References 
-September, 2005
-
-This document provides references for the various cryptographic
-functions used in libSRTP and libaesicm.
-
-Secure RTP is defined in RFC 3711, which is included in this
-distribution for convenience.  The counter mode definition is in
-Section 4.1.1 of the SRTP draft.
-
-SHA-1 is defined in FIPS-180-1, available online at the NIST website.
-
-HMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available
-in RFC2202, which are available online at http://www.ietf.org/rfc/
-
-ICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in
-ISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and
-Authentication) is defined in that specification.  It is available
-from http://www.isma.tv/.
-
-
diff --git a/doc/rfc3711.txt b/doc/rfc3711.txt
deleted file mode 100644
index ecc0648..0000000
--- a/doc/rfc3711.txt
+++ /dev/null
@@ -1,3139 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         M. Baugher
-Request for Comments: 3711                                     D. McGrew
-Category: Standards Track                            Cisco Systems, Inc.
-                                                              M. Naslund
-                                                              E. Carrara
-                                                              K. Norrman
-                                                       Ericsson Research
-                                                              March 2004
-
-
-             The Secure Real-time Transport Protocol (SRTP)
-
-Status of this Memo
-
-   This document specifies an Internet standards track protocol for the
-   Internet community, and requests discussion and suggestions for
-   improvements.  Please refer to the current edition of the "Internet
-   Official Protocol Standards" (STD 1) for the standardization state
-   and status of this protocol.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) The Internet Society (2004).  All Rights Reserved.
-
-Abstract
-
-   This document describes the Secure Real-time Transport Protocol
-   (SRTP), a profile of the Real-time Transport Protocol (RTP), which
-   can provide confidentiality, message authentication, and replay
-   protection to the RTP traffic and to the control traffic for RTP, the
-   Real-time Transport Control Protocol (RTCP).
-
-Table of Contents
-
-   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
-       1.1.  Notational Conventions . . . . . . . . . . . . . . . . .  3
-   2.  Goals and Features . . . . . . . . . . . . . . . . . . . . . .  4
-       2.1.  Features . . . . . . . . . . . . . . . . . . . . . . . .  5
-   3.  SRTP Framework . . . . . . . . . . . . . . . . . . . . . . . .  5
-       3.1.  Secure RTP . . . . . . . . . . . . . . . . . . . . . . .  6
-       3.2.  SRTP Cryptographic Contexts. . . . . . . . . . . . . . .  7
-             3.2.1.  Transform-independent parameters . . . . . . . .  8
-             3.2.2.  Transform-dependent parameters . . . . . . . . . 10
-             3.2.3.  Mapping SRTP Packets to Cryptographic Contexts . 10
-       3.3.  SRTP Packet Processing . . . . . . . . . . . . . . . . . 11
-             3.3.1.  Packet Index Determination, and ROC, s_l Update. 13
-             3.3.2.  Replay Protection. . . . . . . . . . . . . . . . 15
-      3.4.  Secure RTCP . . . . . . . . . . . . . . . . . . . . . . . 15
-
-
-
-Baugher, et al.             Standards Track                     [Page 1]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   4.  Pre-Defined Cryptographic Transforms . . . . . . . . . . . . . 19
-       4.1.  Encryption . . . . . . . . . . . . . . . . . . . . . . . 19
-             4.1.1.  AES in Counter Mode. . . . . . . . . . . . . . . 21
-             4.1.2.  AES in f8-mode . . . . . . . . . . . . . . . . . 22
-             4.1.3.  NULL Cipher. . . . . . . . . . . . . . . . . . . 25
-       4.2.  Message Authentication and Integrity . . . . . . . . . . 25
-             4.2.1.  HMAC-SHA1. . . . . . . . . . . . . . . . . . . . 25
-       4.3.  Key Derivation . . . . . . . . . . . . . . . . . . . . . 26
-             4.3.1.  Key Derivation Algorithm . . . . . . . . . . . . 26
-             4.3.2.  SRTCP Key Derivation . . . . . . . . . . . . . . 28
-             4.3.3.  AES-CM PRF . . . . . . . . . . . . . . . . . . . 28
-   5.  Default and mandatory-to-implement Transforms. . . . . . . . . 28
-       5.1.  Encryption: AES-CM and NULL. . . . . . . . . . . . . . . 29
-       5.2.  Message Authentication/Integrity: HMAC-SHA1. . . . . . . 29
-       5.3.  Key Derivation: AES-CM PRF . . . . . . . . . . . . . . . 29
-   6.  Adding SRTP Transforms . . . . . . . . . . . . . . . . . . . . 29
-   7.  Rationale. . . . . . . . . . . . . . . . . . . . . . . . . . . 30
-       7.1.  Key derivation . . . . . . . . . . . . . . . . . . . . . 30
-       7.2.  Salting key. . . . . . . . . . . . . . . . . . . . . . . 30
-       7.3.  Message Integrity from Universal Hashing . . . . . . . . 31
-       7.4.  Data Origin Authentication Considerations. . . . . . . . 31
-       7.5.  Short and Zero-length Message Authentication . . . . . . 32
-   8.  Key Management Considerations. . . . . . . . . . . . . . . . . 33
-       8.1.  Re-keying  . . . . . . . . . . . . . . . . . . . . . . . 34
-             8.1.1.  Use of the <From, To> for re-keying. . . . . . . 34
-       8.2.  Key Management parameters. . . . . . . . . . . . . . . . 35
-   9.  Security Considerations. . . . . . . . . . . . . . . . . . . . 37
-       9.1.  SSRC collision and two-time pad. . . . . . . . . . . . . 37
-       9.2.  Key Usage. . . . . . . . . . . . . . . . . . . . . . . . 38
-       9.3.  Confidentiality of the RTP Payload . . . . . . . . . . . 39
-       9.4.  Confidentiality of the RTP Header. . . . . . . . . . . . 40
-       9.5.  Integrity of the RTP payload and header. . . . . . . . . 40
-             9.5.1. Risks of Weak or Null Message Authentication. . . 42
-             9.5.2.  Implicit Header Authentication . . . . . . . . . 43
-   10.  Interaction with Forward Error Correction mechanisms. . . . . 43
-   11.  Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . 43
-       11.1. Unicast. . . . . . . . . . . . . . . . . . . . . . . . . 43
-       11.2. Multicast (one sender) . . . . . . . . . . . . . . . . . 44
-       11.3. Re-keying and access control . . . . . . . . . . . . . . 45
-       11.4. Summary of basic scenarios . . . . . . . . . . . . . . . 46
-   12. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 46
-   13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 47
-   14. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47
-       14.1. Normative References . . . . . . . . . . . . . . . . . . 47
-       14.2. Informative References . . . . . . . . . . . . . . . . . 48
-   Appendix A: Pseudocode for Index Determination . . . . . . . . . . 51
-   Appendix B: Test Vectors . . . . . . . . . . . . . . . . . . . . . 51
-       B.1.  AES-f8 Test Vectors. . . . . . . . . . . . . . . . . . . 51
-
-
-
-Baugher, et al.             Standards Track                     [Page 2]
-
-RFC 3711                          SRTP                        March 2004
-
-
-       B.2.  AES-CM Test Vectors. . . . . . . . . . . . . . . . . . . 52
-       B.3.  Key Derivation Test Vectors. . . . . . . . . . . . . . . 53
-   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 55
-   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 56
-
-1.  Introduction
-
-   This document describes the Secure Real-time Transport Protocol
-   (SRTP), a profile of the Real-time Transport Protocol (RTP), which
-   can provide confidentiality, message authentication, and replay
-   protection to the RTP traffic and to the control traffic for RTP,
-   RTCP (the Real-time Transport Control Protocol) [RFC3350].
-
-   SRTP provides a framework for encryption and message authentication
-   of RTP and RTCP streams (Section 3).  SRTP defines a set of default
-   cryptographic transforms (Sections 4 and 5), and it allows new
-   transforms to be introduced in the future (Section 6).  With
-   appropriate key management (Sections 7 and 8), SRTP is secure
-   (Sections 9) for unicast and multicast RTP applications (Section 11).
-
-   SRTP can achieve high throughput and low packet expansion.  SRTP
-   proves to be a suitable protection for heterogeneous environments
-   (mix of wired and wireless networks).  To get such features, default
-   transforms are described, based on an additive stream cipher for
-   encryption, a keyed-hash based function for message authentication,
-   and an "implicit" index for sequencing/synchronization based on the
-   RTP sequence number for SRTP and an index number for Secure RTCP
-   (SRTCP).
-
-1.1.  Notational Conventions
-
-   The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-   document are to be interpreted as described in [RFC2119].  The
-   terminology conforms to [RFC2828] with the following exception.  For
-   simplicity we use the term "random" throughout the document to denote
-   randomly or pseudo-randomly generated values.  Large amounts of
-   random bits may be difficult to obtain, and for the security of SRTP,
-   pseudo-randomness is sufficient [RFC1750].
-
-   By convention, the adopted representation is the network byte order,
-   i.e., the left most bit (octet) is the most significant one.  By XOR
-   we mean bitwise addition modulo 2 of binary strings, and || denotes
-   concatenation.  In other words, if C = A || B, then the most
-   significant bits of C are the bits of A, and the least significant
-   bits of C equal the bits of B.  Hexadecimal numbers are prefixed by
-   0x.
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 3]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   The word "encryption" includes also use of the NULL algorithm (which
-   in practice does leave the data in the clear).
-
-   With slight abuse of notation, we use the terms "message
-   authentication" and "authentication tag" as is common practice, even
-   though in some circumstances, e.g., group communication, the service
-   provided is actually only integrity protection and not data origin
-   authentication.
-
-2.  Goals and Features
-
-   The security goals for SRTP are to ensure:
-
-   *  the confidentiality of the RTP and RTCP payloads, and
-
-   *  the integrity of the entire RTP and RTCP packets, together with
-      protection against replayed packets.
-
-   These security services are optional and independent from each other,
-   except that SRTCP integrity protection is mandatory (malicious or
-   erroneous alteration of RTCP messages could otherwise disrupt the
-   processing of the RTP stream).
-
-   Other, functional, goals for the protocol are:
-
-   *  a framework that permits upgrading with new cryptographic
-      transforms,
-
-   *  low bandwidth cost, i.e., a framework preserving RTP header
-      compression efficiency,
-
-   and, asserted by the pre-defined transforms:
-
-   *  a low computational cost,
-
-   *  a small footprint (i.e., small code size and data memory for
-      keying information and replay lists),
-
-   *  limited packet expansion to support the bandwidth economy goal,
-
-   *  independence from the underlying transport, network, and physical
-      layers used by RTP, in particular high tolerance to packet loss
-      and re-ordering.
-
-   These properties ensure that SRTP is a suitable protection scheme for
-   RTP/RTCP in both wired and wireless scenarios.
-
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 4]
-
-RFC 3711                          SRTP                        March 2004
-
-
-2.1.  Features
-
-   Besides the above mentioned direct goals, SRTP provides for some
-   additional features.  They have been introduced to lighten the burden
-   on key management and to further increase security.  They include:
-
-   *  A single "master key" can provide keying material for
-      confidentiality and integrity protection, both for the SRTP stream
-      and the corresponding SRTCP stream.  This is achieved with a key
-      derivation function (see Section 4.3), providing "session keys"
-      for the respective security primitive, securely derived from the
-      master key.
-
-   *  In addition, the key derivation can be configured to periodically
-      refresh the session keys, which limits the amount of ciphertext
-      produced by a fixed key, available for an adversary to
-      cryptanalyze.
-
-   *  "Salting keys" are used to protect against pre-computation and
-      time-memory tradeoff attacks [MF00] [BS00].
-
-   Detailed rationale for these features can be found in Section 7.
-
-3.  SRTP Framework
-
-   RTP is the Real-time Transport Protocol [RFC3550].  We define SRTP as
-   a profile of RTP.  This profile is an extension to the RTP
-   Audio/Video Profile [RFC3551].  Except where explicitly noted, all
-   aspects of that profile apply, with the addition of the SRTP security
-   features.  Conceptually, we consider SRTP to be a "bump in the stack"
-   implementation which resides between the RTP application and the
-   transport layer.  SRTP intercepts RTP packets and then forwards an
-   equivalent SRTP packet on the sending side, and intercepts SRTP
-   packets and passes an equivalent RTP packet up the stack on the
-   receiving side.
-
-   Secure RTCP (SRTCP) provides the same security services to RTCP as
-   SRTP does to RTP.  SRTCP message authentication is MANDATORY and
-   thereby protects the RTCP fields to keep track of membership, provide
-   feedback to RTP senders, or maintain packet sequence counters.  SRTCP
-   is described in Section 3.4.
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 5]
-
-RFC 3711                          SRTP                        March 2004
-
-
-3.1.  Secure RTP
-
-      The format of an SRTP packet is illustrated in Figure 1.
-
-        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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
-     |V=2|P|X|  CC   |M|     PT      |       sequence number         | |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-     |                           timestamp                           | |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-     |           synchronization source (SSRC) identifier            | |
-     +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
-     |            contributing source (CSRC) identifiers             | |
-     |                               ....                            | |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-     |                   RTP extension (OPTIONAL)                    | |
-   +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | |                          payload  ...                         | |
-   | |                               +-------------------------------+ |
-   | |                               | RTP padding   | RTP pad count | |
-   +>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
-   | ~                     SRTP MKI (OPTIONAL)                       ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | :                 authentication tag (RECOMMENDED)              : |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   |                                                                   |
-   +- Encrypted Portion*                      Authenticated Portion ---+
-
-   Figure 1.  The format of an SRTP packet.  *Encrypted Portion is the
-   same size as the plaintext for the Section 4 pre-defined transforms.
-
-   The "Encrypted Portion" of an SRTP packet consists of the encryption
-   of the RTP payload (including RTP padding when present) of the
-   equivalent RTP packet.  The Encrypted Portion MAY be the exact size
-   of the plaintext or MAY be larger.  Figure 1 shows the RTP payload
-   including any possible padding for RTP [RFC3550].
-
-   None of the pre-defined encryption transforms uses any padding; for
-   these, the RTP and SRTP payload sizes match exactly.  New transforms
-   added to SRTP (following Section 6) may require padding, and may
-   hence produce larger payloads.  RTP provides its own padding format
-   (as seen in Fig. 1), which due to the padding indicator in the RTP
-   header has merits in terms of compactness relative to paddings using
-   prefix-free codes.  This RTP padding SHALL be the default method for
-   transforms requiring padding.  Transforms MAY specify other padding
-   methods, and MUST then specify the amount, format, and processing of
-   their padding.  It is important to note that encryption transforms
-
-
-
-Baugher, et al.             Standards Track                     [Page 6]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   that use padding are vulnerable to subtle attacks, especially when
-   message authentication is not used [V02].  Each specification for a
-   new encryption transform needs to carefully consider and describe the
-   security implications of the padding that it uses.  Message
-   authentication codes define their own padding, so this default does
-   not apply to authentication transforms.
-
-   The OPTIONAL MKI and the RECOMMENDED authentication tag are the only
-   fields defined by SRTP that are not in RTP.  Only 8-bit alignment is
-   assumed.
-
-      MKI (Master Key Identifier): configurable length, OPTIONAL.  The
-              MKI is defined, signaled, and used by key management.  The
-              MKI identifies the master key from which the session
-              key(s) were derived that authenticate and/or encrypt the
-              particular packet.  Note that the MKI SHALL NOT identify
-              the SRTP cryptographic context, which is identified
-              according to Section 3.2.3.  The MKI MAY be used by key
-              management for the purposes of re-keying, identifying a
-              particular master key within the cryptographic context
-              (Section 3.2.1).
-
-      Authentication tag: configurable length, RECOMMENDED.  The
-              authentication tag is used to carry message authentication
-              data.  The Authenticated Portion of an SRTP packet
-              consists of the RTP header followed by the Encrypted
-              Portion of the SRTP packet.  Thus, if both encryption and
-              authentication are applied, encryption SHALL be applied
-              before authentication on the sender side and conversely on
-              the receiver side.  The authentication tag provides
-              authentication of the RTP header and payload, and it
-              indirectly provides replay protection by authenticating
-              the sequence number.  Note that the MKI is not integrity
-              protected as this does not provide any extra protection.
-
-3.2.  SRTP Cryptographic Contexts
-
-   Each SRTP stream requires the sender and receiver to maintain
-   cryptographic state information.  This information is called the
-   "cryptographic context".
-
-   SRTP uses two types of keys: session keys and master keys.  By a
-   "session key", we mean a key which is used directly in a
-   cryptographic transform (e.g., encryption or message authentication),
-   and by a "master key", we mean a random bit string (given by the key
-   management protocol) from which session keys are derived in a
-
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 7]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   cryptographically secure way.  The master key(s) and other parameters
-   in the cryptographic context are provided by key management
-   mechanisms external to SRTP, see Section 8.
-
-3.2.1.  Transform-independent parameters
-
-   Transform-independent parameters are present in the cryptographic
-   context independently of the particular encryption or authentication
-   transforms that are used.  The transform-independent parameters of
-   the cryptographic context for SRTP consist of:
-
-   *  a 32-bit unsigned rollover counter (ROC), which records how many
-      times the 16-bit RTP sequence number has been reset to zero after
-      passing through 65,535.  Unlike the sequence number (SEQ), which
-      SRTP extracts from the RTP packet header, the ROC is maintained by
-      SRTP as described in Section 3.3.1.
-
-      We define the index of the SRTP packet corresponding to a given
-      ROC and RTP sequence number to be the 48-bit quantity
-
-            i = 2^16 * ROC + SEQ.
-
-   *  for the receiver only, a 16-bit sequence number s_l, which can be
-      thought of as the highest received RTP sequence number (see
-      Section 3.3.1 for its handling), which SHOULD be authenticated
-      since message authentication is RECOMMENDED,
-
-   *  an identifier for the encryption algorithm, i.e., the cipher and
-      its mode of operation,
-
-   *  an identifier for the message authentication algorithm,
-
-   *  a replay list, maintained by the receiver only (when
-      authentication and replay protection are provided), containing
-      indices of recently received and authenticated SRTP packets,
-
-   *  an MKI indicator (0/1) as to whether an MKI is present in SRTP and
-      SRTCP packets,
-
-   *  if the MKI indicator is set to one, the length (in octets) of the
-      MKI field, and (for the sender) the actual value of the currently
-      active MKI (the value of the MKI indicator and length MUST be kept
-      fixed for the lifetime of the context),
-
-   *  the master key(s), which MUST be random and kept secret,
-
-
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 8]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   *  for each master key, there is a counter of the number of SRTP
-      packets that have been processed (sent) with that master key
-      (essential for security, see Sections 3.3.1 and 9),
-
-   *  non-negative integers n_e, and n_a, determining the length of the
-      session keys for encryption, and message authentication.
-
-   In addition, for each master key, an SRTP stream MAY use the
-   following associated values:
-
-   *  a master salt, to be used in the key derivation of session keys.
-      This value, when used, MUST be random, but MAY be public.  Use of
-      master salt is strongly RECOMMENDED, see Section 9.2.  A "NULL"
-      salt is treated as 00...0.
-
-   *  an integer in the set {1,2,4,...,2^24}, the "key_derivation_rate",
-      where an unspecified value is treated as zero.  The constraint to
-      be a power of 2 simplifies the session-key derivation
-      implementation, see Section 4.3.
-
-   *  an MKI value,
-
-   *  <From, To> values, specifying the lifetime for a master key,
-      expressed in terms of the two 48-bit index values inside whose
-      range (including the range end-points) the master key is valid.
-      For the use of <From, To>, see Section 8.1.1.  <From, To> is an
-      alternative to the MKI and assumes that a master key is in one-
-      to-one correspondence with the SRTP session key on which the
-      <From, To> range is defined.
-
-   SRTCP SHALL by default share the crypto context with SRTP, except:
-
-   *  no rollover counter and s_l-value need to be maintained as the
-      RTCP index is explicitly carried in each SRTCP packet,
-
-   *  a separate replay list is maintained (when replay protection is
-      provided),
-
-   *  SRTCP maintains a separate counter for its master key (even if the
-      master key is the same as that for SRTP, see below), as a means to
-      maintain a count of the number of SRTCP packets that have been
-      processed with that key.
-
-   Note in particular that the master key(s) MAY be shared between SRTP
-   and the corresponding SRTCP, if the pre-defined transforms (including
-   the key derivation) are used but the session key(s) MUST NOT be so
-   shared.
-
-
-
-
-Baugher, et al.             Standards Track                     [Page 9]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   In addition, there can be cases (see Sections 8 and 9.1) where
-   several SRTP streams within a given RTP session, identified by their
-   synchronization source (SSRCs, which is part of the RTP header),
-   share most of the crypto context parameters (including possibly
-   master and session keys).  In such cases, just as in the normal
-   SRTP/SRTCP parameter sharing above, separate replay lists and packet
-   counters for each stream (SSRC) MUST still be maintained.  Also,
-   separate SRTP indices MUST then be maintained.
-
-   A summary of parameters, pre-defined transforms, and default values
-   for the above parameters (and other SRTP parameters) can be found in
-   Sections 5 and 8.2.
-
-3.2.2.  Transform-dependent parameters
-
-   All encryption, authentication/integrity, and key derivation
-   parameters are defined in the transforms section (Section 4).
-   Typical examples of such parameters are block size of ciphers,
-   session keys, data for the Initialization Vector (IV) formation, etc.
-   Future SRTP transform specifications MUST include a section to list
-   the additional cryptographic context's parameters for that transform,
-   if any.
-
-3.2.3.  Mapping SRTP Packets to Cryptographic Contexts
-
-   Recall that an RTP session for each participant is defined [RFC3550]
-   by a pair of destination transport addresses (one network address
-   plus a port pair for RTP and RTCP), and that a multimedia session is
-   defined as a collection of RTP sessions.  For example, a particular
-   multimedia session could include an audio RTP session, a video RTP
-   session, and a text RTP session.
-
-   A cryptographic context SHALL be uniquely identified by the triplet
-   context identifier:
-
-   context id = <SSRC, destination network address, destination
-   transport port number>
-
-   where the destination network address and the destination transport
-   port are the ones in the SRTP packet.  It is assumed that, when
-   presented with this information, the key management returns a context
-   with the information as described in Section 3.2.
-
-   As noted above, SRTP and SRTCP by default share the bulk of the
-   parameters in the cryptographic context.  Thus, retrieving the crypto
-   context parameters for an SRTCP stream in practice may imply a
-   binding to the correspondent SRTP crypto context.  It is up to the
-   implementation to assure such binding, since the RTCP port may not be
-
-
-
-Baugher, et al.             Standards Track                    [Page 10]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   directly deducible from the RTP port only.  Alternatively, the key
-   management may choose to provide separate SRTP- and SRTCP- contexts,
-   duplicating the common parameters (such as master key(s)).  The
-   latter approach then also enables SRTP and SRTCP to use, e.g.,
-   distinct transforms, if so desired.  Similar considerations arise
-   when multiple SRTP streams, forming part of one single RTP session,
-   share keys and other parameters.
-
-   If no valid context can be found for a packet corresponding to a
-   certain context identifier, that packet MUST be discarded.
-
-3.3.  SRTP Packet Processing
-
-   The following applies to SRTP.  SRTCP is described in Section 3.4.
-
-   Assuming initialization of the cryptographic context(s) has taken
-   place via key management, the sender SHALL do the following to
-   construct an SRTP packet:
-
-   1. Determine which cryptographic context to use as described in
-      Section 3.2.3.
-
-   2. Determine the index of the SRTP packet using the rollover counter,
-      the highest sequence number in the cryptographic context, and the
-      sequence number in the RTP packet, as described in Section 3.3.1.
-
-   3. Determine the master key and master salt.  This is done using the
-      index determined in the previous step or the current MKI in the
-      cryptographic context, according to Section 8.1.
-
-   4. Determine the session keys and session salt (if they are used by
-      the transform) as described in Section 4.3, using master key,
-      master salt, key_derivation_rate, and session key-lengths in the
-      cryptographic context with the index, determined in Steps 2 and 3.
-
-   5. Encrypt the RTP payload to produce the Encrypted Portion of the
-      packet (see Section 4.1, for the defined ciphers).  This step uses
-      the encryption algorithm indicated in the cryptographic context,
-      the session encryption key and the session salt (if used) found in
-      Step 4 together with the index found in Step 2.
-
-   6. If the MKI indicator is set to one, append the MKI to the packet.
-
-   7. For message authentication, compute the authentication tag for the
-      Authenticated Portion of the packet, as described in Section 4.2.
-      This step uses the current rollover counter, the authentication
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 11]
-
-RFC 3711                          SRTP                        March 2004
-
-
-      algorithm indicated in the cryptographic context, and the session
-      authentication key found in Step 4.  Append the authentication tag
-      to the packet.
-
-   8. If necessary, update the ROC as in Section 3.3.1, using the packet
-      index determined in Step 2.
-
-   To authenticate and decrypt an SRTP packet, the receiver SHALL do the
-   following:
-
-   1. Determine which cryptographic context to use as described in
-      Section 3.2.3.
-
-   2. Run the algorithm in Section 3.3.1 to get the index of the SRTP
-      packet.  The algorithm uses the rollover counter and highest
-      sequence number in the cryptographic context with the sequence
-      number in the SRTP packet, as described in Section 3.3.1.
-
-   3. Determine the master key and master salt.  If the MKI indicator in
-      the context is set to one, use the MKI in the SRTP packet,
-      otherwise use the index from the previous step, according to
-      Section 8.1.
-
-   4. Determine the session keys, and session salt (if used by the
-      transform) as described in Section 4.3, using master key, master
-      salt, key_derivation_rate and session key-lengths in the
-      cryptographic context with the index, determined in Steps 2 and 3.
-
-   5. For message authentication and replay protection, first check if
-      the packet has been replayed (Section 3.3.2), using the Replay
-      List and the index as determined in Step 2.  If the packet is
-      judged to be replayed, then the packet MUST be discarded, and the
-      event SHOULD be logged.
-
-      Next, perform verification of the authentication tag, using the
-      rollover counter from Step 2, the authentication algorithm
-      indicated in the cryptographic context, and the session
-      authentication key from Step 4.  If the result is "AUTHENTICATION
-      FAILURE" (see Section 4.2), the packet MUST be discarded from
-      further processing and the event SHOULD be logged.
-
-   6. Decrypt the Encrypted Portion of the packet (see Section 4.1, for
-      the defined ciphers), using the decryption algorithm indicated in
-      the cryptographic context, the session encryption key and salt (if
-      used) found in Step 4 with the index from Step 2.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 12]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   7. Update the rollover counter and highest sequence number, s_l, in
-      the cryptographic context as in Section 3.3.1, using the packet
-      index estimated in Step 2.  If replay protection is provided, also
-      update the Replay List as described in Section 3.3.2.
-
-   8. When present, remove the MKI and authentication tag fields from
-      the packet.
-
-3.3.1.  Packet Index Determination, and ROC, s_l Update
-
-   SRTP implementations use an "implicit" packet index for sequencing,
-   i.e., not all of the index is explicitly carried in the SRTP packet.
-   For the pre-defined transforms, the index i is used in replay
-   protection (Section 3.3.2), encryption (Section 4.1), message
-   authentication (Section 4.2), and for the key derivation (Section
-   4.3).
-
-   When the session starts, the sender side MUST set the rollover
-   counter, ROC, to zero.  Each time the RTP sequence number, SEQ, wraps
-   modulo 2^16, the sender side MUST increment ROC by one, modulo 2^32
-   (see security aspects below).  The sender's packet index is then
-   defined as
-
-      i = 2^16 * ROC + SEQ.
-
-   Receiver-side implementations use the RTP sequence number to
-   determine the correct index of a packet, which is the location of the
-   packet in the sequence of all SRTP packets.  A robust approach for
-   the proper use of a rollover counter requires its handling and use to
-   be well defined.  In particular, out-of-order RTP packets with
-   sequence numbers close to 2^16 or zero must be properly handled.
-
-   The index estimate is based on the receiver's locally maintained ROC
-   and s_l values.  At the setup of the session, the ROC MUST be set to
-   zero.  Receivers joining an on-going session MUST be given the
-   current ROC value using out-of-band signaling such as key-management
-   signaling.  Furthermore, the receiver SHALL initialize s_l to the RTP
-   sequence number (SEQ) of the first observed SRTP packet (unless the
-   initial value is provided by out of band signaling such as key
-   management).
-
-   On consecutive SRTP packets, the receiver SHOULD estimate the index
-   as
-         i = 2^16 * v + SEQ,
-
-   where v is chosen from the set { ROC-1, ROC, ROC+1 } (modulo 2^32)
-   such that i is closest (in modulo 2^48 sense) to the value 2^16 * ROC
-   + s_l (see Appendix A for pseudocode).
-
-
-
-Baugher, et al.             Standards Track                    [Page 13]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   After the packet has been processed and authenticated (when enabled
-   for SRTP packets for the session), the receiver MUST use v to
-   conditionally update its s_l and ROC variables as follows.  If
-   v=(ROC-1) mod 2^32, then there is no update to s_l or ROC.  If v=ROC,
-   then s_l is set to SEQ if and only if SEQ is larger than the current
-   s_l; there is no change to ROC.  If v=(ROC+1) mod 2^32, then s_l is
-   set to SEQ and ROC is set to v.
-
-   After a re-keying occurs (changing to a new master key), the rollover
-   counter always maintains its sequence of values, i.e., it MUST NOT be
-   reset to zero.
-
-   As the rollover counter is 32 bits long and the sequence number is 16
-   bits long, the maximum number of packets belonging to a given SRTP
-   stream that can be secured with the same key is 2^48 using the pre-
-   defined transforms.  After that number of SRTP packets have been sent
-   with a given (master or session) key, the sender MUST NOT send any
-   more packets with that key.  (There exists a similar limit for SRTCP,
-   which in practice may be more restrictive, see Section 9.2.)  This
-   limitation enforces a security benefit by providing an upper bound on
-   the amount of traffic that can pass before cryptographic keys are
-   changed.  Re-keying (see Section 8.1) MUST be triggered, before this
-   amount of traffic, and MAY be triggered earlier, e.g., for increased
-   security and access control to media.  Recurring key derivation by
-   means of a non-zero key_derivation_rate (see Section 4.3), also gives
-   stronger security but does not change the above absolute maximum
-   value.
-
-   On the receiver side, there is a caveat to updating s_l and ROC: if
-   message authentication is not present, neither the initialization of
-   s_l, nor the ROC update can be made completely robust.  The
-   receiver's "implicit index" approach works for the pre-defined
-   transforms as long as the reorder and loss of the packets are not too
-   great and bit-errors do not occur in unfortunate ways.  In
-   particular, 2^15 packets would need to be lost, or a packet would
-   need to be 2^15 packets out of sequence before synchronization is
-   lost.  Such drastic loss or reorder is likely to disrupt the RTP
-   application itself.
-
-   The algorithm for the index estimate and ROC update is a matter of
-   implementation, and should take into consideration the environment
-   (e.g., packet loss rate) and the cases when synchronization is likely
-   to be lost, e.g., when the initial sequence number (randomly chosen
-   by RTP) is not known in advance (not sent in the key management
-   protocol) but may be near to wrap modulo 2^16.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 14]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   A more elaborate and more robust scheme than the one given above is
-   the handling of RTP's own "rollover counter", see Appendix A.1 of
-   [RFC3550].
-
-3.3.2.  Replay Protection
-
-   Secure replay protection is only possible when integrity protection
-   is present.  It is RECOMMENDED to use replay protection, both for RTP
-   and RTCP, as integrity protection alone cannot assure security
-   against replay attacks.
-
-   A packet is "replayed" when it is stored by an adversary, and then
-   re-injected into the network.  When message authentication is
-   provided, SRTP protects against such attacks through a Replay List.
-   Each SRTP receiver maintains a Replay List, which conceptually
-   contains the indices of all of the packets which have been received
-   and authenticated.  In practice, the list can use a "sliding window"
-   approach, so that a fixed amount of storage suffices for replay
-   protection.  Packet indices which lag behind the packet index in the
-   context by more than SRTP-WINDOW-SIZE can be assumed to have been
-   received, where SRTP-WINDOW-SIZE is a receiver-side, implementation-
-   dependent parameter and MUST be at least 64, but which MAY be set to
-   a higher value.
-
-   The receiver checks the index of an incoming packet against the
-   replay list and the window.  Only packets with index ahead of the
-   window, or, inside the window but not already received, SHALL be
-   accepted.
-
-   After the packet has been authenticated (if necessary the window is
-   first moved ahead), the replay list SHALL be updated with the new
-   index.
-
-   The Replay List can be efficiently implemented by using a bitmap to
-   represent which packets have been received, as described in the
-   Security Architecture for IP [RFC2401].
-
-3.4.  Secure RTCP
-
-   Secure RTCP follows the definition of Secure RTP.  SRTCP adds three
-   mandatory new fields (the SRTCP index, an "encrypt-flag", and the
-   authentication tag) and one optional field (the MKI) to the RTCP
-   packet definition.  The three mandatory fields MUST be appended to an
-   RTCP packet in order to form an equivalent SRTCP packet.  The added
-   fields follow any other profile-specific extensions.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 15]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   According to Section 6.1 of [RFC3550], there is a REQUIRED packet
-   format for compound packets.  SRTCP MUST be given packets according
-   to that requirement in the sense that the first part MUST be a sender
-   report or a receiver report.  However, the RTCP encryption prefix (a
-   random 32-bit quantity) specified in that Section MUST NOT be used
-   since, as is stated there, it is only applicable to the encryption
-   method specified in [RFC3550] and is not needed by the cryptographic
-   mechanisms used in SRTP.
-
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
-     |V=2|P|    RC   |   PT=SR or RR   |             length          | |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-     |                         SSRC of sender                        | |
-   +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
-   | ~                          sender info                          ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | ~                         report block 1                        ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | ~                         report block 2                        ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | ~                              ...                              ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | |V=2|P|    SC   |  PT=SDES=202  |             length            | |
-   | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
-   | |                          SSRC/CSRC_1                          | |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | ~                           SDES items                          ~ |
-   | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
-   | ~                              ...                              ~ |
-   +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
-   | |E|                         SRTCP index                         | |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
-   | ~                     SRTCP MKI (OPTIONAL)                      ~ |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   | :                     authentication tag                        : |
-   | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
-   |                                                                   |
-   +-- Encrypted Portion                    Authenticated Portion -----+
-
-
-   Figure 2.  An example of the format of a Secure RTCP packet,
-   consisting of an underlying RTCP compound packet with a Sender Report
-   and SDES packet.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 16]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   The Encrypted Portion of an SRTCP packet consists of the encryption
-   (Section 4.1) of the RTCP payload of the equivalent compound RTCP
-   packet, from the first RTCP packet, i.e., from the ninth (9) octet to
-   the end of the compound packet.  The Authenticated Portion of an
-   SRTCP packet consists of the entire equivalent (eventually compound)
-   RTCP packet, the E flag, and the SRTCP index (after any encryption
-   has been applied to the payload).
-
-   The added fields are:
-
-   E-flag: 1 bit, REQUIRED
-            The E-flag indicates if the current SRTCP packet is
-            encrypted or unencrypted.  Section 9.1 of [RFC3550] allows
-            the split of a compound RTCP packet into two lower-layer
-            packets, one to be encrypted and one to be sent in the
-            clear.  The E bit set to "1" indicates encrypted packet, and
-            "0" indicates non-encrypted packet.
-
-   SRTCP index: 31 bits, REQUIRED
-            The SRTCP index is a 31-bit counter for the SRTCP packet.
-            The index is explicitly included in each packet, in contrast
-            to the "implicit" index approach used for SRTP.  The SRTCP
-            index MUST be set to zero before the first SRTCP packet is
-            sent, and MUST be incremented by one, modulo 2^31, after
-            each SRTCP packet is sent.  In particular, after a re-key,
-            the SRTCP index MUST NOT be reset to zero again.
-
-   Authentication Tag: configurable length, REQUIRED
-            The authentication tag is used to carry message
-            authentication data.
-
-   MKI: configurable length, OPTIONAL
-            The MKI is the Master Key Indicator, and functions according
-            to the MKI definition in Section 3.
-
-   SRTCP uses the cryptographic context parameters and packet processing
-   of SRTP by default, with the following changes:
-
-   *  The receiver does not need to "estimate" the index, as it is
-      explicitly signaled in the packet.
-
-   *  Pre-defined SRTCP encryption is as specified in Section 4.1, but
-      using the definition of the SRTCP Encrypted Portion given in this
-      section, and using the SRTCP index as the index i.  The encryption
-      transform and related parameters SHALL by default be the same
-      selected for the protection of the associated SRTP stream(s),
-      while the NULL algorithm SHALL be applied to the RTCP packets not
-      to be encrypted.  SRTCP may have a different encryption transform
-
-
-
-Baugher, et al.             Standards Track                    [Page 17]
-
-RFC 3711                          SRTP                        March 2004
-
-
-      than the one used by the corresponding SRTP.  The expected use for
-      this feature is when the former has NULL-encryption and the latter
-      has a non NULL-encryption.
-
-   The E-flag is assigned a value by the sender depending on whether the
-   packet was encrypted or not.
-
-   *  SRTCP decryption is performed as in Section 4, but only if the E
-      flag is equal to 1.  If so, the Encrypted Portion is decrypted,
-      using the SRTCP index as the index i.  In case the E-flag is 0,
-      the payload is simply left unmodified.
-
-   *  SRTCP replay protection is as defined in Section 3.3.2, but using
-      the SRTCP index as the index i and a separate Replay List that is
-      specific to SRTCP.
-
-   *  The pre-defined SRTCP authentication tag is specified as in
-      Section 4.2, but with the Authenticated Portion of the SRTCP
-      packet given in this section (which includes the index).  The
-      authentication transform and related parameters (e.g., key size)
-      SHALL by default be the same as selected for the protection of the
-      associated SRTP stream(s).
-
-   *  In the last step of the processing, only the sender needs to
-      update the value of the SRTCP index by incrementing it modulo 2^31
-      and for security reasons the sender MUST also check the number of
-      SRTCP packets processed, see Section 9.2.
-
-   Message authentication for RTCP is REQUIRED, as it is the control
-   protocol (e.g., it has a BYE packet) for RTP.
-
-   Precautions must be taken so that the packet expansion in SRTCP (due
-   to the added fields) does not cause SRTCP messages to use more than
-   their share of RTCP bandwidth.  To avoid this, the following two
-   measures MUST be taken:
-
-   1. When initializing the RTCP variable "avg_rtcp_size" defined in
-      chapter 6.3 of [RFC3550], it MUST include the size of the fields
-      that will be added by SRTCP (index, E-bit, authentication tag, and
-      when present, the MKI).
-
-   2. When updating the "avg_rtcp_size" using the variable "packet_size"
-      (section 6.3.3 of [RFC3550]), the value of "packet_size" MUST
-      include the size of the additional fields added by SRTCP.
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 18]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   With these measures in place the SRTCP messages will not use more
-   than the allotted bandwidth.  The effect of the size of the added
-   fields on the SRTCP traffic will be that messages will be sent with
-   longer packet intervals.  The increase in the intervals will be
-   directly proportional to size of the added fields.  For the pre-
-   defined transforms, the size of the added fields will be at least 14
-   octets, and upper bounded depending on MKI and the authentication tag
-   sizes.
-
-4.  Pre-Defined Cryptographic Transforms
-
-   While there are numerous encryption and message authentication
-   algorithms that can be used in SRTP, below we define default
-   algorithms in order to avoid the complexity of specifying the
-   encodings for the signaling of algorithm and parameter identifiers.
-   The defined algorithms have been chosen as they fulfill the goals
-   listed in Section 2.  Recommendations on how to extend SRTP with new
-   transforms are given in Section 6.
-
-4.1.  Encryption
-
-   The following parameters are common to both pre-defined, non-NULL,
-   encryption transforms specified in this section.
-
-   *  BLOCK_CIPHER-MODE indicates the block cipher used and its mode of
-      operation
-   *  n_b is the bit-size of the block for the block cipher
-   *  k_e is the session encryption key
-   *  n_e is the bit-length of k_e
-   *  k_s is the session salting key
-   *  n_s is the bit-length of k_s
-   *  SRTP_PREFIX_LENGTH is the octet length of the keystream prefix, a
-      non-negative integer, specified by the message authentication code
-      in use.
-
-   The distinct session keys and salts for SRTP/SRTCP are by default
-   derived as specified in Section 4.3.
-
-   The encryption transforms defined in SRTP map the SRTP packet index
-   and secret key into a pseudo-random keystream segment.  Each
-   keystream segment encrypts a single RTP packet.  The process of
-   encrypting a packet consists of generating the keystream segment
-   corresponding to the packet, and then bitwise exclusive-oring that
-   keystream segment onto the payload of the RTP packet to produce the
-   Encrypted Portion of the SRTP packet.  In case the payload size is
-   not an integer multiple of n_b bits, the excess (least significant)
-   bits of the keystream are simply discarded.  Decryption is done the
-   same way, but swapping the roles of the plaintext and ciphertext.
-
-
-
-Baugher, et al.             Standards Track                    [Page 19]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   +----+   +------------------+---------------------------------+
-   | KG |-->| Keystream Prefix |          Keystream Suffix       |---+
-   +----+   +------------------+---------------------------------+   |
-                                                                     |
-                               +---------------------------------+   v
-                               |     Payload of RTP Packet       |->(*)
-                               +---------------------------------+   |
-                                                                     |
-                               +---------------------------------+   |
-                               | Encrypted Portion of SRTP Packet|<--+
-                               +---------------------------------+
-
-   Figure 3: Default SRTP Encryption Processing.  Here KG denotes the
-   keystream generator, and (*) denotes bitwise exclusive-or.
-
-   The definition of how the keystream is generated, given the index,
-   depends on the cipher and its mode of operation.  Below, two such
-   keystream generators are defined.  The NULL cipher is also defined,
-   to be used when encryption of RTP is not required.
-
-   The SRTP definition of the keystream is illustrated in Figure 3.  The
-   initial octets of each keystream segment MAY be reserved for use in a
-   message authentication code, in which case the keystream used for
-   encryption starts immediately after the last reserved octet.  The
-   initial reserved octets are called the "keystream prefix" (not to be
-   confused with the "encryption prefix" of [RFC3550, Section 6.1]), and
-   the remaining octets are called the "keystream suffix".  The
-   keystream prefix MUST NOT be used for encryption.  The process is
-   illustrated in Figure 3.
-
-   The number of octets in the keystream prefix is denoted as
-   SRTP_PREFIX_LENGTH.  The keystream prefix is indicated by a positive,
-   non-zero value of SRTP_PREFIX_LENGTH.  This means that, even if
-   confidentiality is not to be provided, the keystream generator output
-   may still need to be computed for packet authentication, in which
-   case the default keystream generator (mode) SHALL be used.
-
-   The default cipher is the Advanced Encryption Standard (AES) [AES],
-   and we define two modes of running AES, (1) Segmented Integer Counter
-   Mode AES and (2) AES in f8-mode.  In the remainder of this section,
-   let E(k,x) be AES applied to key k and input block x.
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 20]
-
-RFC 3711                          SRTP                        March 2004
-
-
-4.1.1.  AES in Counter Mode
-
-   Conceptually, counter mode [AES-CTR] consists of encrypting
-   successive integers.  The actual definition is somewhat more
-   complicated, in order to randomize the starting point of the integer
-   sequence.  Each packet is encrypted with a distinct keystream
-   segment, which SHALL be computed as follows.
-
-   A keystream segment SHALL be the concatenation of the 128-bit output
-   blocks of the AES cipher in the encrypt direction, using key k = k_e,
-   in which the block indices are in increasing order.  Symbolically,
-   each keystream segment looks like
-
-      E(k, IV) || E(k, IV + 1 mod 2^128) || E(k, IV + 2 mod 2^128) ...
-
-   where the 128-bit integer value IV SHALL be defined by the SSRC, the
-   SRTP packet index i, and the SRTP session salting key k_s, as below.
-
-      IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16)
-
-   Each of the three terms in the XOR-sum above is padded with as many
-   leading zeros as needed to make the operation well-defined,
-   considered as a 128-bit value.
-
-   The inclusion of the SSRC allows the use of the same key to protect
-   distinct SRTP streams within the same RTP session, see the security
-   caveats in Section 9.1.
-
-   In the case of SRTCP, the SSRC of the first header of the compound
-   packet MUST be used, i SHALL be the 31-bit SRTCP index and k_e, k_s
-   SHALL be replaced by the SRTCP encryption session key and salt.
-
-   Note that the initial value, IV, is fixed for each packet and is
-   formed by "reserving" 16 zeros in the least significant bits for the
-   purpose of the counter.  The number of blocks of keystream generated
-   for any fixed value of IV MUST NOT exceed 2^16 to avoid keystream
-   re-use, see below.  The AES has a block size of 128 bits, so 2^16
-   output blocks are sufficient to generate the 2^23 bits of keystream
-   needed to encrypt the largest possible RTP packet (except for IPv6
-   "jumbograms" [RFC2675], which are not likely to be used for RTP-based
-   multimedia traffic).  This restriction on the maximum bit-size of the
-   packet that can be encrypted ensures the security of the encryption
-   method by limiting the effectiveness of probabilistic attacks [BDJR].
-
-   For a particular Counter Mode key, each IV value used as an input
-   MUST be distinct, in order to avoid the security exposure of a two-
-   time pad situation (Section 9.1).  To satisfy this constraint, an
-   implementation MUST ensure that the combination of the SRTP packet
-
-
-
-Baugher, et al.             Standards Track                    [Page 21]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   index of ROC || SEQ, and the SSRC used in the construction of the IV
-   are distinct for any particular key.  The failure to ensure this
-   uniqueness could be catastrophic for Secure RTP.  This is in contrast
-   to the situation for RTP itself, which may be able to tolerate such
-   failures.  It is RECOMMENDED that, if a dedicated security module is
-   present, the RTP sequence numbers and SSRC either be generated or
-   checked by that module (i.e., sequence-number and SSRC processing in
-   an SRTP system needs to be protected as well as the key).
-
-4.1.2.  AES in f8-mode
-
-   To encrypt UMTS (Universal Mobile Telecommunications System, as 3G
-   networks) data, a solution (see [f8-a] [f8-b]) known as the f8-
-   algorithm has been developed.  On a high level, the proposed scheme
-   is a variant of Output Feedback Mode (OFB) [HAC], with a more
-   elaborate initialization and feedback function.  As in normal OFB,
-   the core consists of a block cipher.  We also define here the use of
-   AES as a block cipher to be used in what we shall call "f8-mode of
-   operation" RTP encryption.  The AES f8-mode SHALL use the same
-   default sizes for session key and salt as AES counter mode.
-
-   Figure 4 shows the structure of block cipher, E, running in f8-mode.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 22]
-
-RFC 3711                          SRTP                        March 2004
-
-
-                    IV
-                    |
-                    v
-                +------+
-                |      |
-           +--->|  E   |
-           |    +------+
-           |        |
-     m -> (*)       +-----------+-------------+--  ...     ------+
-           |    IV' |           |             |                  |
-           |        |   j=1 -> (*)    j=2 -> (*)   ...  j=L-1 ->(*)
-           |        |           |             |                  |
-           |        |      +-> (*)       +-> (*)   ...      +-> (*)
-           |        |      |    |        |    |             |    |
-           |        v      |    v        |    v             |    v
-           |    +------+   | +------+    | +------+         | +------+
-    k_e ---+--->|  E   |   | |  E   |    | |  E   |         | |  E   |
-                |      |   | |      |    | |      |         | |      |
-                +------+   | +------+    | +------+         | +------+
-                    |      |    |        |    |             |    |
-                    +------+    +--------+    +--  ...  ----+    |
-                    |           |             |                  |
-                    v           v             v                  v
-                   S(0)        S(1)          S(2)  . . .       S(L-1)
-
-   Figure 4.  f8-mode of operation (asterisk, (*), denotes bitwise XOR).
-   The figure represents the KG in Figure 3, when AES-f8 is used.
-
-4.1.2.1.  f8 Keystream Generation
-
-   The Initialization Vector (IV) SHALL be determined as described in
-   Section 4.1.2.2 (and in Section 4.1.2.3 for SRTCP).
-
-   Let IV', S(j), and m denote n_b-bit blocks.  The keystream,
-   S(0) ||... || S(L-1), for an N-bit message SHALL be defined by
-   setting IV' = E(k_e XOR m, IV), and S(-1) = 00..0.  For
-   j = 0,1,..,L-1 where L = N/n_b (rounded up to nearest integer if it
-   is not already an integer) compute
-
-            S(j) = E(k_e, IV' XOR j XOR S(j-1))
-
-   Notice that the IV is not used directly.  Instead it is fed through E
-   under another key to produce an internal, "masked" value (denoted
-   IV') to prevent an attacker from gaining known input/output pairs.
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 23]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   The role of the internal counter, j, is to prevent short keystream
-   cycles.  The value of the key mask m SHALL be
-
-           m = k_s || 0x555..5,
-
-   i.e., the session salting key, appended by the binary pattern 0101..
-   to fill out the entire desired key size, n_e.
-
-   The sender SHOULD NOT generate more than 2^32 blocks, which is
-   sufficient to generate 2^39 bits of keystream.  Unlike counter mode,
-   there is no absolute threshold above (below) which f8 is guaranteed
-   to be insecure (secure).  The above bound has been chosen to limit,
-   with sufficient security margin, the probability of degenerative
-   behavior in the f8 keystream generation.
-
-4.1.2.2.  f8 SRTP IV Formation
-
-   The purpose of the following IV formation is to provide a feature
-   which we call implicit header authentication (IHA), see Section 9.5.
-
-   The SRTP IV for 128-bit block AES-f8 SHALL be formed in the following
-   way:
-
-        IV = 0x00 || M || PT || SEQ || TS || SSRC || ROC
-
-   M, PT, SEQ, TS, SSRC SHALL be taken from the RTP header; ROC is from
-   the cryptographic context.
-
-   The presence of the SSRC as part of the IV allows AES-f8 to be used
-   when a master key is shared between multiple streams within the same
-   RTP session, see Section 9.1.
-
-4.1.2.3.  f8 SRTCP IV Formation
-
-   The SRTCP IV for 128-bit block AES-f8 SHALL be formed in the
-   following way:
-
-   IV= 0..0 || E || SRTCP index || V || P || RC || PT || length || SSRC
-
-   where V, P, RC, PT, length, SSRC SHALL be taken from the first header
-   in the RTCP compound packet.  E and SRTCP index are the 1-bit and
-   31-bit fields added to the packet.
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 24]
-
-RFC 3711                          SRTP                        March 2004
-
-
-4.1.3.  NULL Cipher
-
-   The NULL cipher is used when no confidentiality for RTP/RTCP is
-   requested.  The keystream can be thought of as "000..0", i.e., the
-   encryption SHALL simply copy the plaintext input into the ciphertext
-   output.
-
-4.2.  Message Authentication and Integrity
-
-   Throughout this section, M will denote data to be integrity
-   protected.  In the case of SRTP, M SHALL consist of the Authenticated
-   Portion of the packet (as specified in Figure 1) concatenated with
-   the ROC, M = Authenticated Portion || ROC; in the case of SRTCP, M
-   SHALL consist of the Authenticated Portion (as specified in Figure 2)
-   only.
-
-   Common parameters:
-
-   *  AUTH_ALG is the authentication algorithm
-   *  k_a is the session message authentication key
-   *  n_a is the bit-length of the authentication key
-   *  n_tag is the bit-length of the output authentication tag
-   *  SRTP_PREFIX_LENGTH is the octet length of the keystream prefix as
-      defined above, a parameter of AUTH_ALG
-
-   The distinct session authentication keys for SRTP/SRTCP are by
-   default derived as specified in Section 4.3.
-
-   The values of n_a, n_tag, and SRTP_PREFIX_LENGTH MUST be fixed for
-   any particular fixed value of the key.
-
-   We describe the process of computing authentication tags as follows.
-   The sender computes the tag of M and appends it to the packet.  The
-   SRTP receiver verifies a message/authentication tag pair by computing
-   a new authentication tag over M using the selected algorithm and key,
-   and then compares it to the tag associated with the received message.
-   If the two tags are equal, then the message/tag pair is valid;
-   otherwise, it is invalid and the error audit message "AUTHENTICATION
-   FAILURE" MUST be returned.
-
-4.2.1.  HMAC-SHA1
-
-   The pre-defined authentication transform for SRTP is HMAC-SHA1
-   [RFC2104].  With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL
-   be 0.  For SRTP (respectively SRTCP), the HMAC SHALL be applied to
-   the session authentication key and M as specified above, i.e.,
-   HMAC(k_a, M).  The HMAC output SHALL then be truncated to the n_tag
-   left-most bits.
-
-
-
-Baugher, et al.             Standards Track                    [Page 25]
-
-RFC 3711                          SRTP                        March 2004
-
-
-4.3.  Key Derivation
-
-4.3.1.  Key Derivation Algorithm
-
-   Regardless of the encryption or message authentication transform that
-   is employed (it may be an SRTP pre-defined transform or newly
-   introduced according to Section 6), interoperable SRTP
-   implementations MUST use the SRTP key derivation to generate session
-   keys.  Once the key derivation rate is properly signaled at the start
-   of the session, there is no need for extra communication between the
-   parties that use SRTP key derivation.
-
-                         packet index ---+
-                                         |
-                                         v
-               +-----------+ master  +--------+ session encr_key
-               | ext       | key     |        |---------->
-               | key mgmt  |-------->|  key   | session auth_key
-               | (optional |         | deriv  |---------->
-               | rekey)    |-------->|        | session salt_key
-               |           | master  |        |---------->
-               +-----------+ salt    +--------+
-
-   Figure 5: SRTP key derivation.
-
-   At least one initial key derivation SHALL be performed by SRTP, i.e.,
-   the first key derivation is REQUIRED.  Further applications of the
-   key derivation MAY be performed, according to the
-   "key_derivation_rate" value in the cryptographic context.  The key
-   derivation function SHALL initially be invoked before the first
-   packet and then, when r > 0, a key derivation is performed whenever
-   index mod r equals zero.  This can be thought of as "refreshing" the
-   session keys.  The value of "key_derivation_rate" MUST be kept fixed
-   for the lifetime of the associated master key.
-
-   Interoperable SRTP implementations MAY also derive session salting
-   keys for encryption transforms, as is done in both of the pre-
-   defined transforms.
-
-   Let m and n be positive integers.  A pseudo-random function family is
-   a set of keyed functions {PRF_n(k,x)} such that for the (secret)
-   random key k, given m-bit x, PRF_n(k,x) is an n-bit string,
-   computationally indistinguishable from random n-bit strings, see
-   [HAC].  For the purpose of key derivation in SRTP, a secure PRF with
-   m = 128 (or more) MUST be used, and a default PRF transform is
-   defined in Section 4.3.3.
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 26]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Let "a DIV t" denote integer division of a by t, rounded down, and
-   with the convention that "a DIV 0 = 0" for all a.  We also make the
-   convention of treating "a DIV t" as a bit string of the same length
-   as a, and thus "a DIV t" will in general have leading zeros.
-
-   Key derivation SHALL be defined as follows in terms of <label>, an
-   8-bit constant (see below), master_salt and key_derivation_rate, as
-   determined in the cryptographic context, and index, the packet index
-   (i.e., the 48-bit ROC || SEQ for SRTP):
-
-   *  Let r = index DIV key_derivation_rate (with DIV as defined above).
-
-   *  Let key_id = <label> || r.
-
-   *  Let x = key_id XOR master_salt, where key_id and master_salt are
-      aligned so that their least significant bits agree (right-
-      alignment).
-
-   <label> MUST be unique for each type of key to be derived.  We
-   currently define <label> 0x00 to 0x05 (see below), and future
-   extensions MAY specify new values in the range 0x06 to 0xff for other
-   purposes.  The n-bit SRTP key (or salt) for this packet SHALL then be
-   derived from the master key, k_master as follows:
-
-      PRF_n(k_master, x).
-
-   (The PRF may internally specify additional formatting and padding of
-   x, see e.g., Section 4.3.3 for the default PRF.)
-
-   The session keys and salt SHALL now be derived using:
-
-   - k_e (SRTP encryption): <label> = 0x00, n = n_e.
-
-   - k_a (SRTP message authentication): <label> = 0x01, n = n_a.
-
-   - k_s (SRTP salting key): <label> = 0x02, n = n_s.
-
-   where n_e, n_s, and n_a are from the cryptographic context.
-
-   The master key and master salt MUST be random, but the master salt
-   MAY be public.
-
-   Note that for a key_derivation_rate of 0, the application of the key
-   derivation SHALL take place exactly once.
-
-   The definition of DIV above is purely for notational convenience.
-   For a non-zero t among the set of allowed key derivation rates, "a
-   DIV t" can be implemented as a right-shift by the base-2 logarithm of
-
-
-
-Baugher, et al.             Standards Track                    [Page 27]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   t.  The derivation operation is further facilitated if the rates are
-   chosen to be powers of 256, but that granularity was considered too
-   coarse to be a requirement of this specification.
-
-   The upper limit on the number of packets that can be secured using
-   the same master key (see Section 9.2) is independent of the key
-   derivation.
-
-4.3.2.  SRTCP Key Derivation
-
-   SRTCP SHALL by default use the same master key (and master salt) as
-   SRTP.  To do this securely, the following changes SHALL be done to
-   the definitions in Section 4.3.1 when applying session key derivation
-   for SRTCP.
-
-   Replace the SRTP index by the 32-bit quantity: 0 || SRTCP index
-   (i.e., excluding the E-bit, replacing it with a fixed 0-bit), and use
-   <label> = 0x03 for the SRTCP encryption key, <label> = 0x04 for the
-   SRTCP authentication key, and, <label> = 0x05 for the SRTCP salting
-   key.
-
-4.3.3.  AES-CM PRF
-
-   The currently defined PRF, keyed by 128, 192, or 256 bit master key,
-   has input block size m = 128 and can produce n-bit outputs for n up
-   to 2^23.  PRF_n(k_master,x) SHALL be AES in Counter Mode as described
-   in Section 4.1.1, applied to key k_master, and IV equal to (x*2^16),
-   and with the output keystream truncated to the n first (left-most)
-   bits.  (Requiring n/128, rounded up, applications of AES.)
-
-5.  Default and mandatory-to-implement Transforms
-
-   The default transforms also are mandatory-to-implement transforms in
-   SRTP.  Of course, "mandatory-to-implement" does not imply
-   "mandatory-to-use".  Table 1 summarizes the pre-defined transforms.
-   The default values below are valid for the pre-defined transforms.
-
-                         mandatory-to-impl.   optional     default
-
-   encryption            AES-CM, NULL         AES-f8       AES-CM
-   message integrity     HMAC-SHA1              -          HMAC-SHA1
-   key derivation (PRF)  AES-CM                 -          AES-CM
-
-   Table 1: Mandatory-to-implement, optional and default transforms in
-   SRTP and SRTCP.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 28]
-
-RFC 3711                          SRTP                        March 2004
-
-
-5.1.  Encryption: AES-CM and NULL
-
-   AES running in Segmented Integer Counter Mode, as defined in Section
-   4.1.1, SHALL be the default encryption algorithm.  The default key
-   lengths SHALL be 128-bit for the session encryption key (n_e).  The
-   default session salt key-length (n_s) SHALL be 112 bits.
-
-   The NULL cipher SHALL also be mandatory-to-implement.
-
-5.2.  Message Authentication/Integrity: HMAC-SHA1
-
-   HMAC-SHA1, as defined in Section 4.2.1, SHALL be the default message
-   authentication code.  The default session authentication key-length
-   (n_a) SHALL be 160 bits, the default authentication tag length
-   (n_tag) SHALL be 80 bits, and the SRTP_PREFIX_LENGTH SHALL be zero
-   for HMAC-SHA1.  In addition, for SRTCP, the pre-defined HMAC-SHA1
-   MUST NOT be applied with a value of n_tag, nor n_a, that are smaller
-   than these defaults.  For SRTP, smaller values are NOT RECOMMENDED,
-   but MAY be used after careful consideration of the issues in Section
-   7.5 and 9.5.
-
-5.3.  Key Derivation: AES-CM PRF
-
-   The AES Counter Mode based key derivation and PRF defined in Sections
-   4.3.1 to 4.3.3, using a 128-bit master key, SHALL be the default
-   method for generating session keys.  The default master salt length
-   SHALL be 112 bits and the default key-derivation rate SHALL be zero.
-
-6.  Adding SRTP Transforms
-
-   Section 4 provides examples of the level of detail needed for
-   defining transforms.  Whenever a new transform is to be added to
-   SRTP, a companion standard track RFC MUST be written to exactly
-   define how the new transform can be used with SRTP (and SRTCP).  Such
-   a companion RFC SHOULD avoid overlap with the SRTP protocol document.
-   Note however, that it MAY be necessary to extend the SRTP or SRTCP
-   cryptographic context definition with new parameters (including fixed
-   or default values), add steps to the packet processing, or even add
-   fields to the SRTP/SRTCP packets.  The companion RFC SHALL explain
-   any known issues regarding interactions between the transform and
-   other aspects of SRTP.
-
-   Each new transform document SHOULD specify its key attributes, e.g.,
-   size of keys (minimum, maximum, recommended), format of keys,
-   recommended/required processing of input keying material,
-   requirements/recommendations on key lifetime, re-keying and key
-   derivation, whether sharing of keys between SRTP and SRTCP is allowed
-   or not, etc.
-
-
-
-Baugher, et al.             Standards Track                    [Page 29]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   An added message integrity transform SHOULD define a minimum
-   acceptable key/tag size for SRTCP, equivalent in strength to the
-   minimum values as defined in Section 5.2.
-
-7.  Rationale
-
-   This section explains the rationale behind several important features
-   of SRTP.
-
-7.1.  Key derivation
-
-   Key derivation reduces the burden on the key establishment.  As many
-   as six different keys are needed per crypto context (SRTP and SRTCP
-   encryption keys and salts, SRTP and SRTCP authentication keys), but
-   these are derived from a single master key in a cryptographically
-   secure way.  Thus, the key management protocol needs to exchange only
-   one master key (plus master salt when required), and then SRTP itself
-   derives all the necessary session keys (via the first, mandatory
-   application of the key derivation function).
-
-   Multiple applications of the key derivation function are optional,
-   but will give security benefits when enabled.  They prevent an
-   attacker from obtaining large amounts of ciphertext produced by a
-   single fixed session key.  If the attacker was able to collect a
-   large amount of ciphertext for a certain session key, he might be
-   helped in mounting certain attacks.
-
-   Multiple applications of the key derivation function provide
-   backwards and forward security in the sense that a compromised
-   session key does not compromise other session keys derived from the
-   same master key.  This means that the attacker who is able to recover
-   a certain session key, is anyway not able to have access to messages
-   secured under previous and later session keys (derived from the same
-   master key).  (Note that, of course, a leaked master key reveals all
-   the session keys derived from it.)
-
-   Considerations arise with high-rate key refresh, especially in large
-   multicast settings, see Section 11.
-
-7.2.  Salting key
-
-   The master salt guarantees security against off-line key-collision
-   attacks on the key derivation that might otherwise reduce the
-   effective key size [MF00].
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 30]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   The derived session salting key used in the encryption, has been
-   introduced to protect against some attacks on additive stream
-   ciphers, see Section 9.2.  The explicit inclusion method of the salt
-   in the IV has been selected for ease of hardware implementation.
-
-7.3.  Message Integrity from Universal Hashing
-
-   The particular definition of the keystream given in Section 4.1 (the
-   keystream prefix) is to give provision for particular universal hash
-   functions, suitable for message authentication in the Wegman-Carter
-   paradigm [WC81].  Such functions are provably secure, simple, quick,
-   and especially appropriate for Digital Signal Processors and other
-   processors with a fast multiply operation.
-
-   No authentication transforms are currently provided in SRTP other
-   than HMAC-SHA1.  Future transforms, like the above mentioned
-   universal hash functions, MAY be added following the guidelines in
-   Section 6.
-
-7.4.  Data Origin Authentication Considerations
-
-   Note that in pair-wise communications, integrity and data origin
-   authentication are provided together.  However, in group scenarios
-   where the keys are shared between members, the MAC tag only proves
-   that a member of the group sent the packet, but does not prevent
-   against a member impersonating another.  Data origin authentication
-   (DOA) for multicast and group RTP sessions is a hard problem that
-   needs a solution; while some promising proposals are being
-   investigated [PCST1] [PCST2], more work is needed to rigorously
-   specify these technologies.  Thus SRTP data origin authentication in
-   groups is for further study.
-
-   DOA can be done otherwise using signatures.  However, this has high
-   impact in terms of bandwidth and processing time, therefore we do not
-   offer this form of authentication in the pre-defined packet-integrity
-   transform.
-
-   The presence of mixers and translators does not allow data origin
-   authentication in case the RTP payload and/or the RTP header are
-   manipulated.  Note that these types of middle entities also disrupt
-   end-to-end confidentiality (as the IV formation depends e.g., on the
-   RTP header preservation).  A certain trust model may choose to trust
-   the mixers/translators to decrypt/re-encrypt the media (this would
-   imply breaking the end-to-end security, with related security
-   implications).
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 31]
-
-RFC 3711                          SRTP                        March 2004
-
-
-7.5.  Short and Zero-length Message Authentication
-
-   As shown in Figure 1, the authentication tag is RECOMMENDED in SRTP.
-   A full 80-bit authentication-tag SHOULD be used, but a shorter tag or
-   even a zero-length tag (i.e., no message authentication) MAY be used
-   under certain conditions to support either of the following two
-   application environments.
-
-      1. Strong authentication can be impractical in environments where
-         bandwidth preservation is imperative.  An important special
-         case is wireless communication systems, in which bandwidth is a
-         scarce and expensive resource.  Studies have shown that for
-         certain applications and link technologies, additional bytes
-         may result in a significant decrease in spectrum efficiency
-         [SWO].  Considerable effort has been made to design IP header
-         compression techniques to improve spectrum efficiency
-         [RFC3095].  A typical voice application produces 20 byte
-         samples, and the RTP, UDP and IP headers need to be jointly
-         compressed to one or two bytes on average in order to obtain
-         acceptable wireless bandwidth economy [RFC3095].  In this case,
-         strong authentication would impose nearly fifty percent
-         overhead.
-
-      2. Authentication is impractical for applications that use data
-         links with fixed-width fields that cannot accommodate the
-         expansion due to the authentication tag.  This is the case for
-         some important existing wireless channels.  For example, zero-
-         byte header compression is used to adapt EVRC/SMV voice with
-         the legacy IS-95 bearer channel in CDMA2000 VoIP services.  It
-         was found that not a single additional octet could be added to
-         the data, which motivated the creation of a zero-byte profile
-         for ROHC [RFC3242].
-
-   A short tag is secure for a restricted set of applications.  Consider
-   a voice telephony application, for example, such as a G.729 audio
-   codec with a 20-millisecond packetization interval, protected by a
-   32-bit message authentication tag.  The likelihood of any given
-   packet being successfully forged is only one in 2^32.  Thus an
-   adversary can control no more than 20 milliseconds of audio output
-   during a 994-day period, on average.  In contrast, the effect of a
-   single forged packet can be much larger if the application is
-   stateful.  A codec that uses relative or predictive compression
-   across packets will propagate the maliciously generated state,
-   affecting a longer duration of output.
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 32]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Certainly not all SRTP or telephony applications meet the criteria
-   for short or zero-length authentication tags.  Section 9.5.1
-   discusses the risks of weak or no message authentication, and section
-   9.5 describes the circumstances when it is acceptable and when it is
-   unacceptable.
-
-8.  Key Management Considerations
-
-   There are emerging key management standards [MIKEY] [KEYMGT] [SDMS]
-   for establishing an SRTP cryptographic context (e.g., an SRTP master
-   key).  Both proprietary and open-standard key management methods are
-   likely to be used for telephony applications [MIKEY] [KINK] and
-   multicast applications [GDOI].  This section provides guidance for
-   key management systems that service SRTP session.
-
-   For initialization, an interoperable SRTP implementation SHOULD be
-   given the SSRC and MAY be given the initial RTP sequence number for
-   the RTP stream by key management (thus, key management has a
-   dependency on RTP operational parameters).  Sending the RTP sequence
-   number in the key management may be useful e.g., when the initial
-   sequence number is close to wrapping (to avoid synchronization
-   problems), and to communicate the current sequence number to a
-   joining endpoint (to properly initialize its replay list).
-
-   If the pre-defined transforms are used, SRTP allows sharing of the
-   same master key between SRTP/SRTCP streams belonging to the same RTP
-   session.
-
-   First, sharing between SRTP streams belonging to the same RTP session
-   is secure if the design of the synchronization mechanism, i.e., the
-   IV, avoids keystream re-use (the two-time pad, Section 9.1).  This is
-   taken care of by the fact that RTP provides for unique SSRCs for
-   streams belonging to the same RTP session.  See Section 9.1 for
-   further discussion.
-
-   Second, sharing between SRTP and the corresponding SRTCP is secure.
-   The fact that an SRTP stream and its associated SRTCP stream both
-   carry the same SSRC does not constitute a problem for the two-time
-   pad due to the key derivation.  Thus, SRTP and SRTCP corresponding to
-   one RTP session MAY share master keys (as they do by default).
-
-   Note that message authentication also has a dependency on SSRC
-   uniqueness that is unrelated to the problem of keystream reuse: SRTP
-   streams authenticated under the same key MUST have a distinct SSRC in
-   order to identify the sender of the message.  This requirement is
-   needed because the SSRC is the cryptographically authenticated field
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 33]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   used to distinguish between different SRTP streams.  Were two streams
-   to use identical SSRC values, then an adversary could substitute
-   messages from one stream into the other without detection.
-
-   SRTP/SRTCP MUST NOT share master keys under any other circumstances
-   than the ones given above, i.e., between SRTP and its corresponding
-   SRTCP, and, between streams belonging to the same RTP session.
-
-8.1.  Re-keying
-
-   The recommended way for a particular key management system to provide
-   re-key within SRTP is by associating a master key in a crypto context
-   with an MKI.
-
-   This provides for easy master key retrieval (see Scenarios in Section
-   11), but has the disadvantage of adding extra bits to each packet.
-   As noted in Section 7.5, some wireless links do not cater for added
-   bits, therefore SRTP also defines a more economic way of triggering
-   re-keying, via use of <From, To>, which works in some specific,
-   simple scenarios (see Section 8.1.1).
-
-   SRTP senders SHALL count the amount of SRTP and SRTCP traffic being
-   used for a master key and invoke key management to re-key if needed
-   (Section 9.2).  These interactions are defined by the key management
-   interface to SRTP and are not defined by this protocol specification.
-
-8.1.1.  Use of the <From, To> for re-keying
-
-   In addition to the use of the MKI, SRTP defines another optional
-   mechanism for master key retrieval, the <From, To>.  The <From, To>
-   specifies the range of SRTP indices (a pair of sequence number and
-   ROC) within which a certain master key is valid, and is (when used)
-   part of the crypto context.  By looking at the 48-bit SRTP index of
-   the current SRTP packet, the corresponding master key can be found by
-   determining which From-To interval it belongs to.  For SRTCP, the
-   most recently observed/used SRTP index (which can be obtained from
-   the cryptographic context) is used for this purpose, even though
-   SRTCP has its own (31-bit) index (see caveat below).
-
-   This method, compared to the MKI, has the advantage of identifying
-   the master key and defining its lifetime without adding extra bits to
-   each packet.  This could be useful, as already noted, for some
-   wireless links that do not cater for added bits.  However, its use
-   SHOULD be limited to specific, very simple scenarios.  We recommend
-   to limit its use when the RTP session is a simple unidirectional or
-   bi-directional stream.  This is because in case of multiple streams,
-   it is difficult to trigger the re-key based on the <From, To> of a
-   single RTP stream. For example, if several streams share a master
-
-
-
-Baugher, et al.             Standards Track                    [Page 34]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   key, there is no simple one-to-one correspondence between the index
-   sequence space of a certain stream, and the index sequence space on
-   which the <From, To> values are based.  Consequently, when a master
-   key is shared between streams, one of these streams MUST be
-   designated by key management as the one whose index space defines the
-   re-keying points.  Also, the re-key triggering on SRTCP is based on
-   the correspondent SRTP stream, i.e., when the SRTP stream changes the
-   master key, so does the correspondent SRTCP.  This becomes obviously
-   more and more complex with multiple streams.
-
-   The default values for the <From, To> are "from the first observed
-   packet" and "until further notice".  However, the maximum limit of
-   SRTP/SRTCP packets that are sent under each given master/session key
-   (Section 9.2) MUST NOT be exceeded.
-
-   In case the <From, To> is used as key retrieval, then the MKI is not
-   inserted in the packet (and its indicator in the crypto context is
-   zero).  However, using the MKI does not exclude using <From, To> key
-   lifetime simultaneously.  This can for instance be useful to signal
-   at the sender side at which point in time an MKI is to be made
-   active.
-
-8.2.  Key Management parameters
-
-   The table below lists all SRTP parameters that key management can
-   supply.  For reference, it also provides a summary of the default and
-   mandatory-to-support values for an SRTP implementation as described
-   in Section 5.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 35]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Parameter                     Mandatory-to-support    Default
-   ---------                     --------------------    -------
-
-   SRTP and SRTCP encr transf.       AES_CM, NULL         AES_CM
-   (Other possible values: AES_f8)
-
-   SRTP and SRTCP auth transf.       HMAC-SHA1           HMAC-SHA1
-
-   SRTP and SRTCP auth params:
-     n_tag (tag length)                 80                 80
-     SRTP prefix_length                  0                  0
-
-   Key derivation PRF                 AES_CM              AES_CM
-
-   Key material params
-   (for each master key):
-     master key length                 128                128
-     n_e (encr session key length)     128                128
-     n_a (auth session key length)     160                160
-     master salt key
-     length of the master salt         112                112
-     n_s (session salt key length)     112                112
-     key derivation rate                 0                  0
-
-     key lifetime
-        SRTP-packets-max-lifetime      2^48               2^48
-        SRTCP-packets-max-lifetime     2^31               2^31
-        from-to-lifetime <From, To>
-     MKI indicator                       0                 0
-     length of the MKI                   0                 0
-     value of the MKI
-
-   Crypto context index params:
-     SSRC value
-     ROC
-     SEQ
-     SRTCP Index
-     Transport address
-     Port number
-
-   Relation to other RTP profiles:
-     sender's order between FEC and SRTP FEC-SRTP      FEC-SRTP
-     (see Section 10)
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 36]
-
-RFC 3711                          SRTP                        March 2004
-
-
-9. Security Considerations
-
-9.1.  SSRC collision and two-time pad
-
-   Any fixed keystream output, generated from the same key and index
-   MUST only be used to encrypt once.  Re-using such keystream (jokingly
-   called a "two-time pad" system by cryptographers), can seriously
-   compromise security.  The NSA's VENONA project [C99] provides a
-   historical example of such a compromise.  It is REQUIRED that
-   automatic key management be used for establishing and maintaining
-   SRTP and SRTCP keying material; this requirement is to avoid
-   keystream reuse, which is more likely to occur with manual key
-   management.  Furthermore, in SRTP, a "two-time pad" is avoided by
-   requiring the key, or some other parameter of cryptographic
-   significance, to be unique per RTP/RTCP stream and packet.  The pre-
-   defined SRTP transforms accomplish packet-uniqueness by including the
-   packet index and stream-uniqueness by inclusion of the SSRC.
-
-   The pre-defined transforms (AES-CM and AES-f8) allow master keys to
-   be shared across streams belonging to the same RTP session by the
-   inclusion of the SSRC in the IV.  A master key MUST NOT be shared
-   among different RTP sessions.
-
-   Thus, the SSRC MUST be unique between all the RTP streams within the
-   same RTP session that share the same master key.  RTP itself provides
-   an algorithm for detecting SSRC collisions within the same RTP
-   session.  Thus, temporary collisions could lead to temporary two-time
-   pad, in the unfortunate event that SSRCs collide at a point in time
-   when the streams also have identical sequence numbers (occurring with
-   probability roughly 2^(-48)).  Therefore, the key management SHOULD
-   take care of avoiding such SSRC collisions by including the SSRCs to
-   be used in the session as negotiation parameters, proactively
-   assuring their uniqueness.  This is a strong requirements in
-   scenarios where for example, there are multiple senders that can
-   start to transmit simultaneously, before SSRC collision are detected
-   at the RTP level.
-
-   Note also that even with distinct SSRCs, extensive use of the same
-   key might improve chances of probabilistic collision and time-
-   memory-tradeoff attacks succeeding.
-
-   As described, master keys MAY be shared between streams belonging to
-   the same RTP session, but it is RECOMMENDED that each SSRC have its
-   own master key.  When master keys are shared among SSRC participants
-   and SSRCs are managed by a key management module as recommended
-   above, the RECOMMENDED policy for an SSRC collision error is for the
-   participant to leave the SRTP session as it is a sign of malfunction.
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 37]
-
-RFC 3711                          SRTP                        March 2004
-
-
-9.2.  Key Usage
-
-   The effective key size is determined (upper bounded) by the size of
-   the master key and, for encryption, the size of the salting key.  Any
-   additive stream cipher is vulnerable to attacks that use statistical
-   knowledge about the plaintext source to enable key collision and
-   time-memory tradeoff attacks [MF00] [H80] [BS00].  These attacks take
-   advantage of commonalities among plaintexts, and provide a way for a
-   cryptanalyst to amortize the computational effort of decryption over
-   many keys, or over many bytes of output, thus reducing the effective
-   key size of the cipher.  A detailed analysis of these attacks and
-   their applicability to the encryption of Internet traffic is provided
-   in [MF00].  In summary, the effective key size of SRTP when used in a
-   security system in which m distinct keys are used, is equal to the
-   key size of the cipher less the logarithm (base two) of m.
-   Protection against such attacks can be provided simply by increasing
-   the size of the keys used, which here can be accomplished by the use
-   of the salting key.  Note that the salting key MUST be random but MAY
-   be public.  A salt size of (the suggested) size 112 bits protects
-   against attacks in scenarios where at most 2^112 keys are in use.
-   This is sufficient for all practical purposes.
-
-   Implementations SHOULD use keys that are as large as possible.
-   Please note that in many cases increasing the key size of a cipher
-   does not affect the throughput of that cipher.
-
-   The use of the SRTP and SRTCP indices in the pre-defined transforms
-   fixes the maximum number of packets that can be secured with the same
-   key.  This limit is fixed to 2^48 SRTP packets for an SRTP stream,
-   and 2^31 SRTCP packets, when SRTP and SRTCP are considered
-   independently.  Due to for example re-keying, reaching this limit may
-   or may not coincide with wrapping of the indices, and thus the sender
-   MUST keep packet counts.  However, when the session keys for related
-   SRTP and SRTCP streams are derived from the same master key (the
-   default behavior, Section 4.3), the upper bound that has to be
-   considered is in practice the minimum of the two quantities.  That
-   is, when 2^48 SRTP packets or 2^31 SRTCP packets have been secured
-   with the same key (whichever occurs before), the key management MUST
-   be called to provide new master key(s) (previously stored and used
-   keys MUST NOT be used again), or the session MUST be terminated.  If
-   a sender of RTCP discovers that the sender of SRTP (or SRTCP) has not
-   updated the master or session key prior to sending 2^48 SRTP (or 2^31
-   SRTCP) packets belonging to the same SRTP (SRTCP) stream, it is up to
-   the security policy of the RTCP sender how to behave, e.g., whether
-   an RTCP BYE-packet should be sent and/or if the event should be
-   logged.
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 38]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Note: in most typical applications (assuming at least one RTCP packet
-   for every 128,000 RTP packets), it will be the SRTCP index that first
-   reaches the upper limit, although the time until this occurs is very
-   long: even at 200 SRTCP packets/sec, the 2^31 index space of SRTCP is
-   enough to secure approximately 4 months of communication.
-
-   Note that if the master key is to be shared between SRTP streams
-   within the same RTP session (Section 9.1), although the above bounds
-   are on a per stream (i.e., per SSRC) basis, the sender MUST base re-
-   key decision on the stream whose sequence number space is the first
-   to be exhausted.
-
-   Key derivation limits the amount of plaintext that is encrypted with
-   a fixed session key, and made available to an attacker for analysis,
-   but key derivation does not extend the master key's lifetime.  To see
-   this, simply consider our requirements to avoid two-time pad:  two
-   distinct packets MUST either be processed with distinct IVs, or with
-   distinct session keys, and both the distinctness of IV and of the
-   session keys are (for the pre-defined transforms) dependent on the
-   distinctness of the packet indices.
-
-   Note that with the key derivation, the effective key size is at most
-   that of the master key, even if the derived session key is
-   considerably longer.  With the pre-defined authentication transform,
-   the session authentication key is 160 bits, but the master key by
-   default is only 128 bits.  This design choice was made to comply with
-   certain recommendations in [RFC2104] so that an existing HMAC
-   implementation can be plugged into SRTP without problems.  Since the
-   default tag size is 80 bits, it is, for the applications in mind,
-   also considered acceptable from security point of view.  Users having
-   concerns about this are RECOMMENDED to instead use a 192 bit master
-   key in the key derivation.  It was, however, chosen not to mandate
-   192-bit keys since existing AES implementations to be used in the
-   key-derivation may not always support key-lengths other than 128
-   bits.  Since AES is not defined (or properly analyzed) for use with
-   160 bit keys it is NOT RECOMMENDED that ad-hoc key-padding schemes
-   are used to pad shorter keys to 192 or 256 bits.
-
-9.3.  Confidentiality of the RTP Payload
-
-   SRTP's pre-defined ciphers are "seekable" stream ciphers, i.e.,
-   ciphers able to efficiently seek to arbitrary locations in their
-   keystream (so that the encryption or decryption of one packet does
-   not depend on preceding packets).  By using seekable stream ciphers,
-   SRTP avoids the denial of service attacks that are possible on stream
-   ciphers that lack this property.  It is important to be aware that,
-   as with any stream cipher, the exact length of the payload is
-   revealed by the encryption.  This means that it may be possible to
-
-
-
-Baugher, et al.             Standards Track                    [Page 39]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   deduce certain "formatting bits" of the payload, as the length of the
-   codec output might vary due to certain parameter settings etc.  This,
-   in turn, implies that the corresponding bit of the keystream can be
-   deduced.  However, if the stream cipher is secure (counter mode and
-   f8 are provably secure under certain assumptions [BDJR] [KSYH] [IK]),
-   knowledge of a few bits of the keystream will not aid an attacker in
-   predicting subsequent keystream bits.  Thus, the payload length (and
-   information deducible from this) will leak, but nothing else.
-
-   As some RTP packet could contain highly predictable data, e.g., SID,
-   it is important to use a cipher designed to resist known plaintext
-   attacks (which is the current practice).
-
-9.4.  Confidentiality of the RTP Header
-
-   In SRTP, RTP headers are sent in the clear to allow for header
-   compression.  This means that data such as payload type,
-   synchronization source identifier, and timestamp are available to an
-   eavesdropper.  Moreover, since RTP allows for future extensions of
-   headers, we cannot foresee what kind of possibly sensitive
-   information might also be "leaked".
-
-   SRTP is a low-cost method, which allows header compression to reduce
-   bandwidth.  It is up to the endpoints' policies to decide about the
-   security protocol to employ.  If one really needs to protect headers,
-   and is allowed to do so by the surrounding environment, then one
-   should also look at alternatives, e.g., IPsec [RFC2401].
-
-9.5.  Integrity of the RTP payload and header
-
-   SRTP messages are subject to attacks on their integrity and source
-   identification, and these risks are discussed in Section 9.5.1.  To
-   protect against these attacks, each SRTP stream SHOULD be protected
-   by HMAC-SHA1 [RFC2104] with an 80-bit output tag and a 160-bit key,
-   or a message authentication code with equivalent strength.  Secure
-   RTP SHOULD NOT be used without message authentication, except under
-   the circumstances described in this section.  It is important to note
-   that encryption algorithms, including AES Counter Mode and f8, do not
-   provide message authentication.  SRTCP MUST NOT be used with weak (or
-   NULL) authentication.
-
-   SRTP MAY be used with weak authentication (e.g., a 32-bit
-   authentication tag), or with no authentication (the NULL
-   authentication algorithm).  These options allow SRTP to be used to
-   provide confidentiality in situations where
-
-    * weak or null authentication is an acceptable security risk, and
-    * it is impractical to provide strong message authentication.
-
-
-
-Baugher, et al.             Standards Track                    [Page 40]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   These conditions are described below and in Section 7.5.  Note that
-   both conditions MUST hold in order for weak or null authentication to
-   be used.  The risks associated with exercising the weak or null
-   authentication options need to be considered by a security audit
-   prior to their use for a particular application or environment given
-   the risks, which are discussed in Section 9.5.1.
-
-   Weak authentication is acceptable when the RTP application is such
-   that the effect of a small fraction of successful forgeries is
-   negligible.  If the application is stateless, then the effect of a
-   single forged RTP packet is limited to the decoding of that
-   particular packet.  Under this condition, the size of the
-   authentication tag MUST ensure that only a negligible fraction of the
-   packets passed to the RTP application by the SRTP receiver can be
-   forgeries.  This fraction is negligible when an adversary, if given
-   control of the forged packets, is not able to make a significant
-   impact on the output of the RTP application (see the example of
-   Section 7.5).
-
-   Weak or null authentication MAY be acceptable when it is unlikely
-   that an adversary can modify ciphertext so that it decrypts to an
-   intelligible value.  One important case is when it is difficult for
-   an adversary to acquire the RTP plaintext data, since for many
-   codecs, an adversary that does not know the input signal cannot
-   manipulate the output signal in a controlled way.  In many cases it
-   may be difficult for the adversary to determine the actual value of
-   the plaintext.  For example, a hidden snooping device might be
-   required in order to know a live audio or video signal.  The
-   adversary's signal must have a quality equivalent to or greater than
-   that of the signal under attack, since otherwise the adversary would
-   not have enough information to encode that signal with the codec used
-   by the victim.  Plaintext prediction may also be especially difficult
-   for an interactive application such as a telephone call.
-
-   Weak or null authentication MUST NOT be used when the RTP application
-   makes data forwarding or access control decisions based on the RTP
-   data.  In such a case, an attacker may be able to subvert
-   confidentiality by causing the receiver to forward data to an
-   attacker.  See Section 3 of [B96] for a real-life example of such
-   attacks.
-
-   Null authentication MUST NOT be used when a replay attack, in which
-   an adversary stores packets then replays them later in the session,
-   could have a non-negligible impact on the receiver.  An example of a
-   successful replay attack is the storing of the output of a
-   surveillance camera for a period of time, later followed by the
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 41]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   injection of that output to the monitoring station to avoid
-   surveillance.  Encryption does not protect against this attack, and
-   non-null authentication is REQUIRED in order to defeat it.
-
-   If existential message forgery is an issue, i.e., when the accuracy
-   of the received data is of non-negligible importance, null
-   authentication MUST NOT be used.
-
-9.5.1.  Risks of Weak or Null Message Authentication
-
-   During a security audit considering the use of weak or null
-   authentication, it is important to keep in mind the following attacks
-   which are possible when no message authentication algorithm is used.
-
-   An attacker who cannot predict the plaintext is still always able to
-   modify the message sent between the sender and the receiver so that
-   it decrypts to a random plaintext value, or to send a stream of bogus
-   packets to the receiver that will decrypt to random plaintext values.
-   This attack is essentially a denial of service attack, though in the
-   absence of message authentication, the RTP application will have
-   inputs that are bit-wise correlated with the true value.  Some
-   multimedia codecs and common operating systems will crash when such
-   data are accepted as valid video data.  This denial of service attack
-   may be a much larger threat than that due to an attacker dropping,
-   delaying, or re-ordering packets.
-
-   An attacker who cannot predict the plaintext can still replay a
-   previous message with certainty that the receiver will accept it.
-   Applications with stateless codecs might be robust against this type
-   of attack, but for other, more complex applications these attacks may
-   be far more grave.
-
-   An attacker who can predict the plaintext can modify the ciphertext
-   so that it will decrypt to any value of her choosing.  With an
-   additive stream cipher, an attacker will always be able to change
-   individual bits.
-
-   An attacker may be able to subvert confidentiality due to the lack of
-   authentication when a data forwarding or access control decision is
-   made on decrypted but unauthenticated plaintext.  This is because the
-   receiver may be fooled into forwarding data to an attacker, leading
-   to an indirect breach of confidentiality (see Section 3 of [B96]).
-   This is because data-forwarding decisions are made on the decrypted
-   plaintext; information in the plaintext will determine to what subnet
-   (or process) the plaintext is forwarded in ESP [RFC2401] tunnel mode
-   (respectively, transport mode).  When Secure RTP is used without
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 42]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   message authentication, it should be verified that the application
-   does not make data forwarding or access control decisions based on
-   the decrypted plaintext.
-
-   Some cipher modes of operation that require padding, e.g., standard
-   cipher block chaining (CBC) are very sensitive to attacks on
-   confidentiality if certain padding types are used in the absence of
-   integrity.  The attack [V02] shows that this is indeed the case for
-   the standard RTP padding as discussed in reference to Figure 1, when
-   used together with CBC mode.  Later transform additions to SRTP MUST
-   therefore carefully consider the risk of using this padding without
-   proper integrity protection.
-
-9.5.2.  Implicit Header Authentication
-
-   The IV formation of the f8-mode gives implicit authentication (IHA)
-   of the RTP header, even when message authentication is not used.
-   When IHA is used, an attacker that modifies the value of the RTP
-   header will cause the decryption process at the receiver to produce
-   random plaintext values.  While this protection is not equivalent to
-   message authentication, it may be useful for some applications.
-
-10.  Interaction with Forward Error Correction mechanisms
-
-   The default processing when using Forward Error Correction (e.g., RFC
-   2733) processing with SRTP SHALL be to perform FEC processing prior
-   to SRTP processing on the sender side and to perform SRTP processing
-   prior to FEC processing on the receiver side.  Any change to this
-   ordering (reversing it, or, placing FEC between SRTP encryption and
-   SRTP authentication) SHALL be signaled out of band.
-
-11.  Scenarios
-
-   SRTP can be used as security protocol for the RTP/RTCP traffic in
-   many different scenarios.  SRTP has a number of configuration
-   options, in particular regarding key usage, and can have impact on
-   the total performance of the application according to the way it is
-   used.  Hence, the use of SRTP is dependent on the kind of scenario
-   and application it is used with.  In the following, we briefly
-   illustrate some use cases for SRTP, and give some guidelines for
-   recommended setting of its options.
-
-11.1.  Unicast
-
-   A typical example would be a voice call or video-on-demand
-   application.
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 43]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Consider one bi-directional RTP stream, as one RTP session.  It is
-   possible for the two parties to share the same master key in the two
-   directions according to the principles of Section 9.1.  The first
-   round of the key derivation splits the master key into any or all of
-   the following session keys (according to the provided security
-   functions):
-
-   SRTP_encr_key, SRTP_auth_key, SRTCP_encr_key, and SRTCP_auth key.
-
-   (For simplicity, we omit discussion of the salts, which are also
-   derived.)  In this scenario, it will in most cases suffice to have a
-   single master key with the default lifetime.  This guarantees
-   sufficiently long lifetime of the keys and a minimum set of keys in
-   place for most practical purposes.  Also, in this case RTCP
-   protection can be applied smoothly.  Under these assumptions, use of
-   the MKI can be omitted.  As the key-derivation in combination with
-   large difference in the packet rate in the respective directions may
-   require simultaneous storage of several session keys, if storage is
-   an issue, we recommended to use low-rate key derivation.
-
-   The same considerations can be extended to the unicast scenario with
-   multiple RTP sessions, where each session would have a distinct
-   master key.
-
-11.2.  Multicast (one sender)
-
-   Just as with (unprotected) RTP, a scalability issue arises in big
-   groups due to the possibly very large amount of SRTCP Receiver
-   Reports that the sender might need to process.  In SRTP, the sender
-   may have to keep state (the cryptographic context) for each receiver,
-   or more precisely, for the SRTCP used to protect Receiver Reports.
-   The overhead increases proportionally to the size of the group.  In
-   particular, re-keying requires special concern, see below.
-
-   Consider first a small group of receivers.  There are a few possible
-   setups with the distribution of master keys among the receivers.
-   Given a single RTP session, one possibility is that the receivers
-   share the same master key as per Section 9.1 to secure all their
-   respective RTCP traffic.  This shared master key could then be the
-   same one used by the sender to protect its outbound SRTP traffic.
-   Alternatively, it could be a master key shared only among the
-   receivers and used solely for their SRTCP traffic.  Both alternatives
-   require the receivers to trust each other.
-
-   Considering SRTCP and key storage, it is recommended to use low-rate
-   (or zero) key_derivation (except the mandatory initial one), so that
-   the sender does not need to store too many session keys (each SRTCP
-   stream might otherwise have a different session key at a given point
-
-
-
-Baugher, et al.             Standards Track                    [Page 44]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   in time, as the SRTCP sources send at different times).  Thus, in
-   case key derivation is wanted for SRTP, the cryptographic context for
-   SRTP can be kept separate from the SRTCP crypto context, so that it
-   is possible to have a key_derivation_rate of 0 for SRTCP and a non-
-   zero value for SRTP.
-
-   Use of the MKI for re-keying is RECOMMENDED for most applications
-   (see Section 8.1).
-
-   If there are more than one SRTP/SRTCP stream (within the same RTP
-   session) that share the master key, the upper limit of 2^48 SRTP
-   packets / 2^31 SRTCP packets means that, before one of the streams
-   reaches its maximum number of packets, re-keying MUST be triggered on
-   ALL streams sharing the master key.  (From strict security point of
-   view, only the stream reaching the maximum would need to be re-keyed,
-   but then the streams would no longer be sharing master key, which is
-   the intention.)  A local policy at the sender side should force
-   rekeying in a way that the maximum packet limit is not reached on any
-   of the streams.  Use of the MKI for re-keying is RECOMMENDED.
-
-   In large multicast with one sender, the same considerations as for
-   the small group multicast hold.  The biggest issue in this scenario
-   is the additional load placed at the sender side, due to the state
-   (cryptographic contexts) that has to be maintained for each receiver,
-   sending back RTCP Receiver Reports.  At minimum, a replay window
-   might need to be maintained for each RTCP source.
-
-11.3.  Re-keying and access control
-
-   Re-keying may occur due to access control (e.g., when a member is
-   removed during a multicast RTP session), or for pure cryptographic
-   reasons (e.g., the key is at the end of its lifetime).  When using
-   SRTP default transforms, the master key MUST be replaced before any
-   of the index spaces are exhausted for any of the streams protected by
-   one and the same master key.
-
-   How key management re-keys SRTP implementations is out of scope, but
-   it is clear that there are straightforward ways to manage keys for a
-   multicast group.  In one-sender multicast, for example, it is
-   typically the responsibility of the sender to determine when a new
-   key is needed.  The sender is the one entity that can keep track of
-   when the maximum number of packets has been sent, as receivers may
-   join and leave the session at any time, there may be packet loss and
-   delay etc.  In scenarios other than one-sender multicast, other
-   methods can be used.  Here, one must take into consideration that key
-   exchange can be a costly operation, taking several seconds for a
-   single exchange.  Hence, some time before the master key is
-   exhausted/expires, out-of-band key management is initiated, resulting
-
-
-
-Baugher, et al.             Standards Track                    [Page 45]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   in a new master key that is shared with the receiver(s).  In any
-   event, to maintain synchronization when switching to the new key,
-   group policy might choose between using the MKI and the <From, To>,
-   as described in Section 8.1.
-
-   For access control purposes, the <From, To> periods are set at the
-   desired granularity, dependent on the packet rate.  High rate re-
-   keying can be problematic for SRTCP in some large-group scenarios.
-   As mentioned, there are potential problems in using the SRTP index,
-   rather than the SRTCP index, for determining the master key.  In
-   particular, for short periods during switching of master keys, it may
-   be the case that SRTCP packets are not under the current master key
-   of the correspondent SRTP.  Therefore, using the MKI for re-keying in
-   such scenarios will produce better results.
-
-11.4.  Summary of basic scenarios
-
-   The description of these scenarios highlights some recommendations on
-   the use of SRTP, mainly related to re-keying and large scale
-   multicast:
-
-   - Do not use fast re-keying with the <From, To> feature.  It may, in
-     particular, give problems in retrieving the correct SRTCP key, if
-     an SRTCP packet arrives close to the re-keying time.  The MKI
-     SHOULD be used in this case.
-
-   - If multiple SRTP streams in the same RTP session share the same
-     master key, also moderate rate re-keying MAY have the same
-     problems, and the MKI SHOULD be used.
-
-   - Though offering increased security, a non-zero key_derivation_rate
-     is NOT RECOMMENDED when trying to minimize the number of keys in
-     use with multiple streams.
-
-12.  IANA Considerations
-
-   The RTP specification establishes a registry of profile names for use
-   by higher-level control protocols, such as the Session Description
-   Protocol (SDP), to refer to transport methods.  This profile
-   registers the name "RTP/SAVP".
-
-   SRTP uses cryptographic transforms which a key management protocol
-   signals.  It is the task of each particular key management protocol
-   to register the cryptographic transforms or suites of transforms with
-   IANA.  The key management protocol conveys these protocol numbers,
-   not SRTP, and each key management protocol chooses the numbering
-   scheme and syntax that it requires.
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 46]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Specification of a key management protocol for SRTP is out of scope
-   here.  Section 8.2, however, provides guidance on the parameters that
-   need to be defined for the default and mandatory transforms.
-
-13.  Acknowledgements
-
-   David Oran (Cisco) and Rolf Blom (Ericsson) are co-authors of this
-   document but their valuable contributions are acknowledged here to
-   keep the length of the author list down.
-
-   The authors would in addition like to thank Magnus Westerlund, Brian
-   Weis, Ghyslain Pelletier, Morgan Lindqvist, Robert Fairlie-
-   Cuninghame, Adrian Perrig, the AVT WG and in particular the chairmen
-   Colin Perkins and Stephen Casner, the Transport and Security Area
-   Directors, and Eric Rescorla for their reviews and support.
-
-14.  References
-
-14.1.  Normative References
-
-   [AES]     NIST, "Advanced Encryption Standard (AES)", FIPS PUB 197,
-             http://www.nist.gov/aes/
-
-   [RFC2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
-             Hashing for Message Authentication", RFC 2104, February
-             1997.
-
-   [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
-             Requirement Levels", BCP 14, RFC 2119, March 1997.
-
-   [RFC2401] Kent, S. and R. Atkinson, "Security Architecture for
-             Internet Protocol", RFC 2401, November 1998.
-
-   [RFC2828] Shirey, R., "Internet Security Glossary", FYI 36, RFC 2828,
-             May 2000.
-
-   [RFC3550] Schulzrinne, H., Casner, S., Frederick, R. and V. Jacobson,
-             "RTP: A Transport Protocol for Real-time Applications", RFC
-             3550, July 2003.
-
-   [RFC3551] Schulzrinne, H. and S. Casner, "RTP Profile for Audio and
-             Video Conferences with Minimal Control",  RFC 3551, July
-             2003.
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 47]
-
-RFC 3711                          SRTP                        March 2004
-
-
-14.2.  Informative References
-
-   [AES-CTR] Lipmaa, H., Rogaway, P. and D. Wagner, "CTR-Mode
-             Encryption", NIST, http://csrc.nist.gov/encryption/modes/
-             workshop1/papers/lipmaa-ctr.pdf
-
-   [B96]     Bellovin, S., "Problem Areas for the IP Security
-             Protocols," in Proceedings of the Sixth Usenix Unix
-             Security Symposium, pp. 1-16, San Jose, CA, July 1996
-             (http://www.research.att.com/~smb/papers/index.html).
-
-   [BDJR]    Bellare, M., Desai, A., Jokipii, E. and P. Rogaway, "A
-             Concrete Treatment of Symmetric Encryption: Analysis of DES
-             Modes of Operation", Proceedings 38th IEEE FOCS, pp. 394-
-             403, 1997.
-
-   [BS00]    Biryukov, A. and A. Shamir, "Cryptanalytic Time/Memory/Data
-             Tradeoffs for Stream Ciphers", Proceedings, ASIACRYPT 2000,
-             LNCS 1976, pp. 1-13, Springer Verlag.
-
-   [C99]     Crowell, W. P., "Introduction to the VENONA Project",
-             http://www.nsa.gov:8080/docs/venona/index.html.
-
-   [CTR]     Dworkin, M., NIST Special Publication 800-38A,
-             "Recommendation for Block Cipher Modes of Operation:
-             Methods and Techniques", 2001.
-             http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-
-             38a.pdf.
-
-   [f8-a]    3GPP TS 35.201 V4.1.0 (2001-12) Technical Specification 3rd
-             Generation Partnership Project; Technical Specification
-             Group Services and System Aspects; 3G Security;
-             Specification of the 3GPP Confidentiality and Integrity
-             Algorithms; Document 1: f8 and f9 Specification (Release
-             4).
-
-   [f8-b]    3GPP TR 33.908 V4.0.0 (2001-09) Technical Report 3rd
-             Generation Partnership Project; Technical Specification
-             Group Services and System Aspects; 3G Security; General
-             Report on the Design, Specification and Evaluation of 3GPP
-             Standard Confidentiality and Integrity Algorithms (Release
-             4).
-
-   [GDOI]    Baugher, M., Weis, B., Hardjono, T. and H. Harney, "The
-             Group Domain of Interpretation, RFC 3547, July 2003.
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 48]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   [HAC]     Menezes, A., Van Oorschot, P. and  S. Vanstone, "Handbook
-             of Applied Cryptography", CRC Press, 1997, ISBN 0-8493-
-             8523-7.
-
-   [H80]     Hellman, M. E., "A cryptanalytic time-memory trade-off",
-             IEEE Transactions on Information Theory, July 1980, pp.
-             401-406.
-
-   [IK]      T. Iwata and T. Kohno: "New Security Proofs for the 3GPP
-             Confidentiality and Integrity Algorithms", Proceedings of
-             FSE 2004.
-
-   [KINK]    Thomas, M. and J. Vilhuber, "Kerberized Internet
-             Negotiation of Keys (KINK)", Work in Progress.
-
-   [KEYMGT]  Arrko, J., et al., "Key Management Extensions for Session
-             Description Protocol (SDP) and Real Time Streaming Protocol
-             (RTSP)", Work in Progress.
-
-   [KSYH]    Kang, J-S., Shin, S-U., Hong, D. and O. Yi, "Provable
-             Security of KASUMI and 3GPP Encryption Mode f8",
-             Proceedings Asiacrypt 2001, Springer Verlag LNCS 2248, pp.
-             255-271, 2001.
-
-   [MIKEY]   Arrko, J., et. al., "MIKEY: Multimedia Internet KEYing",
-             Work in Progress.
-
-   [MF00]    McGrew, D. and S. Fluhrer, "Attacks on Encryption of
-             Redundant Plaintext and Implications on Internet Security",
-             the Proceedings of the Seventh Annual Workshop on Selected
-             Areas in Cryptography (SAC 2000), Springer-Verlag.
-
-   [PCST1]   Perrig, A., Canetti, R., Tygar, D. and D.  Song, "Efficient
-             and Secure Source Authentication for Multicast", in Proc.
-             of Network and Distributed System Security Symposium NDSS
-             2001, pp. 35-46, 2001.
-
-   [PCST2]   Perrig, A., Canetti, R., Tygar, D. and D. Song, "Efficient
-             Authentication and Signing of Multicast Streams over Lossy
-             Channels", in Proc. of IEEE Security and Privacy Symposium
-             S&P2000, pp. 56-73, 2000.
-
-   [RFC1750] Eastlake, D., Crocker, S. and J. Schiller, "Randomness
-             Recommendations for Security", RFC 1750, December 1994.
-
-   [RFC2675] Borman, D., Deering, S. and R. Hinden, "IPv6 Jumbograms",
-             RFC 2675, August 1999.
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 49]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   [RFC3095] Bormann, C., Burmeister, C., Degermark, M., Fukuhsima, H.,
-             Hannu, H., Jonsson, L-E., Hakenberg, R., Koren, T., Le, K.,
-             Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke,
-             T., Yoshimura, T. and H. Zheng, "RObust Header Compression:
-             Framework and Four Profiles: RTP, UDP, ESP, and
-             uncompressed (ROHC)", RFC 3095, July 2001.
-
-   [RFC3242] Jonsson, L-E. and G. Pelletier, "RObust Header Compression
-             (ROHC): A Link-Layer Assisted Profile for IP/UDP/RTP ", RFC
-             3242, April 2002.
-
-   [SDMS]    Andreasen, F., Baugher, M. and D. Wing, "Session
-             Description Protocol Security Descriptions for Media
-             Streams", Work in Progress.
-
-   [SWO]     Svanbro, K., Wiorek, J. and B. Olin, "Voice-over-IP-over-
-             wireless", Proc.  PIMRC 2000, London, Sept. 2000.
-
-   [V02]     Vaudenay, S., "Security Flaws Induced by CBC Padding -
-             Application to SSL, IPsec, WTLS...", Advances in
-             Cryptology, EUROCRYPT'02, LNCS 2332, pp. 534-545.
-
-   [WC81]    Wegman, M. N., and  J.L. Carter, "New Hash Functions and
-             Their Use in Authentication and Set Equality", JCSS 22,
-             265-279, 1981.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 50]
-
-RFC 3711                          SRTP                        March 2004
-
-
-Appendix A: Pseudocode for Index Determination
-
-   The following is an example of pseudo-code for the algorithm to
-   determine the index i of an SRTP packet with sequence number SEQ.  In
-   the following, signed arithmetic is assumed.
-
-         if (s_l < 32,768)
-            if (SEQ - s_l > 32,768)
-               set v to (ROC-1) mod 2^32
-            else
-               set v to ROC
-            endif
-         else
-            if (s_l - 32,768 > SEQ)
-               set v to (ROC+1) mod 2^32
-            else
-               set v to ROC
-            endif
-         endif
-         return SEQ + v*65,536
-
-Appendix B: Test Vectors
-
-   All values are in hexadecimal.
-
-B.1.  AES-f8 Test Vectors
-
-   SRTP PREFIX LENGTH  :   0
-
-   RTP packet header   :   806e5cba50681de55c621599
-
-   RTP packet payload  :   70736575646f72616e646f6d6e657373
-                           20697320746865206e65787420626573
-                           74207468696e67
-
-   ROC                 :   d462564a
-   key                 :   234829008467be186c3de14aae72d62c
-   salt key            :   32f2870d
-   key-mask (m)        :   32f2870d555555555555555555555555
-   key XOR key-mask    :   11baae0dd132eb4d3968b41ffb278379
-
-   IV                  :   006e5cba50681de55c621599d462564a
-   IV'                 :   595b699bbd3bc0df26062093c1ad8f73
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 51]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   j = 0
-   IV' xor j           :   595b699bbd3bc0df26062093c1ad8f73
-   S(-1)               :   00000000000000000000000000000000
-   IV' xor S(-1) xor j :   595b699bbd3bc0df26062093c1ad8f73
-   S(0)                :   71ef82d70a172660240709c7fbb19d8e
-   plaintext           :   70736575646f72616e646f6d6e657373
-   ciphertext          :   019ce7a26e7854014a6366aa95d4eefd
-
-   j = 1
-   IV' xor j           :   595b699bbd3bc0df26062093c1ad8f72
-   S(0)                :   71ef82d70a172660240709c7fbb19d8e
-   IV' xor S(0) xor j  :   28b4eb4cb72ce6bf020129543a1c12fc
-   S(1)                :   3abd640a60919fd43bd289a09649b5fc
-   plaintext           :   20697320746865206e65787420626573
-   ciphertext          :   1ad4172a14f9faf455b7f1d4b62bd08f
-
-   j = 2
-   IV' xor j           :   595b699bbd3bc0df26062093c1ad8f71
-   S(1)                :   3abd640a60919fd43bd289a09649b5fc
-   IV' xor S(1) xor j  :   63e60d91ddaa5f0b1dd4a93357e43a8d
-   S(2)                :   220c7a8715266565b09ecc8a2a62b11b
-   plaintext           :   74207468696e67
-   ciphertext          :   562c0eef7c4802
-
-B.2.  AES-CM Test Vectors
-
-    Keystream segment length: 1044512 octets (65282 AES blocks)
-    Session Key:      2B7E151628AED2A6ABF7158809CF4F3C
-    Rollover Counter: 00000000
-    Sequence Number:  0000
-    SSRC:             00000000
-    Session Salt:     F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000 (already shifted)
-    Offset:           F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000
-
-    Counter                            Keystream
-
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFD0000   E03EAD0935C95E80E166B16DD92B4EB4
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFD0001   D23513162B02D0F72A43A2FE4A5F97AB
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFD0002   41E95B3BB0A2E8DD477901E4FCA894C0
-    ...                                ...
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF   EC8CDF7398607CB0F2D21675EA9EA1E4
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF00   362B7C3C6773516318A077D7FC5073AE
-    F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF01   6A2CC3787889374FBEB4C81B17BA6C44
-
-   Nota Bene: this test case is contrived so that the latter part of the
-   keystream segment coincides with the test case in Section F.5.1 of
-   [CTR].
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 52]
-
-RFC 3711                          SRTP                        March 2004
-
-
-B.3.  Key Derivation Test Vectors
-
-   This section provides test data for the default key derivation
-   function, which uses AES-128 in Counter Mode.  In the following, we
-   walk through the initial key derivation for the AES-128 Counter Mode
-   cipher, which requires a 16 octet session encryption key and a 14
-   octet session salt, and an authentication function which requires a
-   94-octet session authentication key.  These values are called the
-   cipher key, the cipher salt, and the auth key in the following.
-   Since this is the initial key derivation and the key derivation rate
-   is equal to zero, the value of (index DIV key_derivation_rate) is
-   zero (actually, a six-octet string of zeros).  In the following, we
-   shorten key_derivation_rate to kdr.
-
-   The inputs to the key derivation function are the 16 octet master key
-   and the 14 octet master salt:
-
-      master key:  E1F97A0D3E018BE0D64FA32C06DE4139
-      master salt: 0EC675AD498AFEEBB6960B3AABE6
-
-   We first show how the cipher key is generated.  The input block for
-   AES-CM is generated by exclusive-oring the master salt with the
-   concatenation of the encryption key label 0x00 with (index DIV kdr),
-   then padding on the right with two null octets (which implements the
-   multiply-by-2^16 operation, see Section 4.3.3).  The resulting value
-   is then AES-CM- encrypted using the master key to get the cipher key.
-
-      index DIV kdr:                 000000000000
-      label:                       00
-      master salt:   0EC675AD498AFEEBB6960B3AABE6
-      -----------------------------------------------
-      xor:           0EC675AD498AFEEBB6960B3AABE6     (x, PRF input)
-
-      x*2^16:        0EC675AD498AFEEBB6960B3AABE60000 (AES-CM input)
-
-      cipher key:    C61E7A93744F39EE10734AFE3FF7A087 (AES-CM output)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 53]
-
-RFC 3711                          SRTP                        March 2004
-
-
-   Next, we show how the cipher salt is generated.  The input block for
-   AES-CM is generated by exclusive-oring the master salt with the
-   concatenation of the encryption salt label.  That value is padded and
-   encrypted as above.
-
-      index DIV kdr:                 000000000000
-      label:                       02
-      master salt:   0EC675AD498AFEEBB6960B3AABE6
-
-      ----------------------------------------------
-      xor:           0EC675AD498AFEE9B6960B3AABE6     (x, PRF input)
-
-      x*2^16:        0EC675AD498AFEE9B6960B3AABE60000 (AES-CM input)
-
-                     30CBBC08863D8C85D49DB34A9AE17AC6 (AES-CM ouptut)
-
-      cipher salt:   30CBBC08863D8C85D49DB34A9AE1
-
-   We now show how the auth key is generated.  The input block for AES-
-   CM is generated as above, but using the authentication key label.
-
-      index DIV kdr:                   000000000000
-      label:                         01
-      master salt:     0EC675AD498AFEEBB6960B3AABE6
-      -----------------------------------------------
-      xor:             0EC675AD498AFEEAB6960B3AABE6     (x, PRF input)
-
-      x*2^16:          0EC675AD498AFEEAB6960B3AABE60000 (AES-CM input)
-
-   Below, the auth key is shown on the left, while the corresponding AES
-   input blocks are shown on the right.
-
-   auth key                           AES input blocks
-   CEBE321F6FF7716B6FD4AB49AF256A15   0EC675AD498AFEEAB6960B3AABE60000
-   6D38BAA48F0A0ACF3C34E2359E6CDBCE   0EC675AD498AFEEAB6960B3AABE60001
-   E049646C43D9327AD175578EF7227098   0EC675AD498AFEEAB6960B3AABE60002
-   6371C10C9A369AC2F94A8C5FBCDDDC25   0EC675AD498AFEEAB6960B3AABE60003
-   6D6E919A48B610EF17C2041E47403576   0EC675AD498AFEEAB6960B3AABE60004
-   6B68642C59BBFC2F34DB60DBDFB2       0EC675AD498AFEEAB6960B3AABE60005
-
-
-
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 54]
-
-RFC 3711                          SRTP                        March 2004
-
-
-Authors' Addresses
-
-   Questions and comments should be directed to the authors and
-   avt@ietf.org:
-
-   Mark Baugher
-   Cisco Systems, Inc.
-   5510 SW Orchid Street
-   Portland, OR 97219 USA
-
-   Phone:  +1 408-853-4418
-   EMail:  mbaugher@cisco.com
-
-
-   Elisabetta Carrara
-   Ericsson Research
-   SE-16480 Stockholm
-   Sweden
-
-   Phone:  +46 8 50877040
-   EMail:  elisabetta.carrara@ericsson.com
-
-
-   David A. McGrew
-   Cisco Systems, Inc.
-   San Jose, CA 95134-1706
-   USA
-
-   Phone:  +1 301-349-5815
-   EMail:  mcgrew@cisco.com
-
-
-   Mats Naslund
-   Ericsson Research
-   SE-16480 Stockholm
-   Sweden
-
-   Phone:  +46 8 58533739
-   EMail:  mats.naslund@ericsson.com
-
-
-   Karl Norrman
-   Ericsson Research
-   SE-16480 Stockholm
-   Sweden
-
-   Phone:  +46 8 4044502
-   EMail:  karl.norrman@ericsson.com
-
-
-
-Baugher, et al.             Standards Track                    [Page 55]
-
-RFC 3711                          SRTP                        March 2004
-
-
-Full Copyright Statement
-
-   Copyright (C) The Internet Society (2004).  This document is subject
-   to the rights, licenses and restrictions contained in BCP 78 and
-   except as set forth therein, the authors retain all their rights.
-
-   This document and the information contained herein are provided on an
-   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
-   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
-   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
-   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
-   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-Intellectual Property
-
-   The IETF takes no position regarding the validity or scope of any
-   Intellectual Property Rights or other rights that might be claimed to
-   pertain to the implementation or use of the technology described in
-   this document or the extent to which any license under such rights
-   might or might not be available; nor does it represent that it has
-   made any independent effort to identify any such rights.  Information
-   on the procedures with respect to rights in RFC documents can be
-   found in BCP 78 and BCP 79.
-
-   Copies of IPR disclosures made to the IETF Secretariat and any
-   assurances of licenses to be made available, or the result of an
-   attempt made to obtain a general license or permission for the use of
-   such proprietary rights by implementers or users of this
-   specification can be obtained from the IETF on-line IPR repository at
-   http://www.ietf.org/ipr.
-
-   The IETF invites any interested party to bring to its attention any
-   copyrights, patents or patent applications, or other proprietary
-   rights that may cover technology that may be required to implement
-   this standard.  Please address the information to the IETF at ietf-
-   ipr@ietf.org.
-
-Acknowledgement
-
-   Funding for the RFC Editor function is currently provided by the
-   Internet Society.
-
-
-
-
-
-
-
-
-
-Baugher, et al.             Standards Track                    [Page 56]
-
diff --git a/exported_include/srtp2 b/exported_include/srtp2
new file mode 120000
index 0000000..f5030fe
--- /dev/null
+++ b/exported_include/srtp2
@@ -0,0 +1 @@
+../include
\ No newline at end of file
diff --git a/format.sh b/format.sh
new file mode 100755
index 0000000..fdf23ef
--- /dev/null
+++ b/format.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# format.sh
+#
+# run clang-format on each .c & .h file
+#
+# assumes git tree is clean when reporting status
+
+if [ -z "${CLANG_FORMAT}" ]; then
+    CLANG_FORMAT=clang-format
+fi
+
+a=`git ls-files '*.h' '*.c'`
+for x in $a; do
+    if [ $x != "config_in.h" ]; then
+        $CLANG_FORMAT -i -style=file $x
+    fi
+done
+
+m=`git ls-files -m`
+if [ -n "$m" ]; then
+    v=`$CLANG_FORMAT -version`
+    echo "Fromatting required when checking with $v"
+    echo
+    echo "The following files required formatting:"
+    for f in $m; do
+        echo $f
+    done
+    if [ "$1" = "-d" ]; then
+        echo
+        git diff
+    fi
+    exit 1
+fi
+exit 0
diff --git a/fuzzer/Makefile.in b/fuzzer/Makefile.in
new file mode 100644
index 0000000..cd107fa
--- /dev/null
+++ b/fuzzer/Makefile.in
@@ -0,0 +1,34 @@
+# Makefile for libSRTP fuzzer
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+CC	= @CC@
+CXX	= @CXX@
+INCDIR	= -Iinclude -I$(srcdir)/include -I$(top_srcdir)/include -I$(top_srcdir)/crypto/include/
+DEFS	= @DEFS@
+CPPFLAGS= @CPPFLAGS@ -g
+CXXFLAGS= @CXXFLAGS@ -g
+CFLAGS	= @CFLAGS@ -g
+LIBS	= @LIBS@
+COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
+COMPILECXX = $(CXX) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CXXFLAGS)
+CRYPTOLIB = -lsrtp2
+
+.PHONY: clean
+
+all : srtp-fuzzer
+
+mt19937.o: mt19937.cpp
+	$(COMPILECXX) -c -std=c++11 mt19937.cpp -o mt19937.o
+fuzzer.o: fuzzer.c fuzzer.h testmem.h
+	$(COMPILE) fuzzer.c -c -o fuzzer.o
+testmem.o: testmem.c
+	$(COMPILE) -O0 testmem.c -c -o testmem.o
+srtp-fuzzer: fuzzer.o mt19937.o testmem.o
+	$(COMPILECXX) -L. -L.. fuzzer.o mt19937.o testmem.o $(LIBFUZZER) $(CRYPTOLIB) $(LIBS) -o srtp-fuzzer
+
+clean:
+	rm -rf srtp-fuzzer *.o
diff --git a/fuzzer/README.md b/fuzzer/README.md
new file mode 100644
index 0000000..eee9579
--- /dev/null
+++ b/fuzzer/README.md
@@ -0,0 +1,88 @@
+# libsrt fuzzer
+
+By Guido Vranken <guidovranken@gmail.com> -- https://guidovranken.wordpress.com/
+
+This is an advanced fuzzer for libSRTP (https://github.com/cisco/libsrtp). It implements several special techniques, described below, that are not often found in fuzzers or elsewhere. All are encouraged to transpose these ideas to their own fuzzers for the betterment of software security.
+
+Feel free to contact me for business enquiries.
+
+## Building
+
+From the repository's root directory:
+
+```sh
+CC=clang CXX=clang++ CXXFLAGS="-fsanitize=fuzzer-no-link,address,undefined -g -O3" CFLAGS="-fsanitize=fuzzer-no-link,address,undefined -g -O3" LDFLAGS="-fsanitize=fuzzer-no-link,address,undefined" ./configure
+LIBFUZZER="-fsanitize=fuzzer" make srtp-fuzzer
+```
+
+## Features
+
+### Portable PRNG
+
+```mt19937.c``` exports the C++11 Mersenne Twister implementaton. Hence, a modern C++ compiler is required to compile this file.
+
+This approach has the following advantages:
+
+- rand() is fickle -- its behavior eg. the sequence of numbers that it generates for a given seed, may differ across systems and libc's.
+- C++11 mt19937 is portable, meaning that its behavior will be consistent across platforms. This is important to keep the fuzzing corpus portable.
+- No need to implement a portable PRNG ourselves, or risk license incompatability by importing it from other projects.
+
+### Size 0 allocations
+
+To test whether allocations of size 0 eg. ```malloc(0)``` are ever dereferenced and written to, the custom allocater will return an intentionally invalid pointer pointer address for these requests.
+
+For more information, see the comments in ```fuzz_alloc()```.
+
+### Random allocation failures
+
+The custom allocator will periodically return ```NULL``` for heap requests. This tests the library's resilience and correct operation in the event of global memory shortages.
+
+The interval of ```NULL``` return values is deterministic as it relies on the PRNG, so for a given fuzzer input (that encodes the PRNG seed as well), behavior of that input with regards to allocator behaviour is consistent, allowing for reliable reproduction of bugs.
+
+### Detecting inadequate pointer arithmetic
+
+This feature is only available on 32 bit builds.
+
+Unless the ```--no_mmap``` flag is given, the fuzzer will use a special allocation technique for some of the allocation requests. It will use ```mmap()``` to reserve memory at the extremities of the virtual address space -- sometimes at 0x00010000 and sometimes at 0xFFFF0000. This approach can assist in detecting invalid or inadequate pointer arithmetic. For example, consider the following code:
+
+```c
+if ( start + n < end ) {
+    memset(start, 0, n);
+}
+```
+
+where ```start``` and ```end``` demarcate a memory region, and ```n``` is some positive integer.
+If ```n``` is a sufficiently large value, a pointer addition overflow will occur, leading to a page fault. By routinely placing allocations at the high virtual address ```0xFFFF0000```, the chances of detecting this bug are increased. So let's say ```start``` was previously allocated at ```0xFFFF0000```, and ```end``` is ```0xFFFF1000```, and ```n``` is 0xFFFFF. Then the expression effectively becomes:
+
+```c
+if ( 0xFFFF0000 + 0x000FFFFF < 0xFFFF1000 ) {
+    memset(0xFFFF0000, 0, 0x000FFFF);
+}
+```
+
+The addition ```0xFFFF0000 + 0x000FFFFF``` overflows so the result is ```0x000EFFFF```. Hence:
+
+```c
+if ( 0x000EFFFF < 0xFFFF1000 ) { // Expression resolves as true !
+```
+
+The subsequent ```memset``` is executed contrary to the programmer's intentions, and a segmentation fault will occur.
+
+While this is a corner case, it can not be ruled out that it might occur in a production environment. What's more, the analyst examining the crash can reason about how the value of ```n``` comes about in the first place, and concoct a crafted input that leads to a very high ```n``` value, making the "exploit" succeed even with average virtual addresses.
+
+Aside from using ```mmap``` to allocate at address ```0xFFFF0000```, the fuzzer will also place allocations at the low virtual address ```0x00010000``` to detect invalid pointer arithmetic involving subtraction:
+
+```c
+if ( end - n > start ) {
+```
+
+### Output memory testing
+
+```testmem.c``` exports ```fuzz_testmem```. All this function does is copy the input buffer to a newly allocated heap region, and then free that heap region. If AddressSanitizer is enabled, this ensures that the input buffer to ```fuzz_testmem``` is a legal memory region.
+If MemorySanitizer is enabled, then ``fuzz_testmem``` calls ```fuzz_testmem_msan````. The latter function writes the data at hand to ```/dev/null```. This is an nice trick to make MemorySanitizer evaluate this data, and crash if it contains uninitialized bytes.
+This function has been implemented in a separate file for a reason: from the perspective of an optimizing compiler, this is a meaningless operation, and as such it might be optimized away. Hence, this file must be compiled without optimizations (```-O0``` flag).
+
+## Contributing
+
+When extending the current fuzzer, use variable types whose width is consistent across systems where possible. This is necessary to retain corpus portability. For example, use ```uint64_t``` rather than ```unsigned long```.
+
diff --git a/fuzzer/corpus/002478e8528b7057018106308a03382f9c60dd62 b/fuzzer/corpus/002478e8528b7057018106308a03382f9c60dd62
new file mode 100644
index 0000000..75e7f87
--- /dev/null
+++ b/fuzzer/corpus/002478e8528b7057018106308a03382f9c60dd62
Binary files differ
diff --git a/fuzzer/corpus/003573bfa48939dd1c2b3e875f1906b082662ea7 b/fuzzer/corpus/003573bfa48939dd1c2b3e875f1906b082662ea7
new file mode 100644
index 0000000..4eade05
--- /dev/null
+++ b/fuzzer/corpus/003573bfa48939dd1c2b3e875f1906b082662ea7
Binary files differ
diff --git a/fuzzer/corpus/0063584d99e559d95f7574303efaaa7d66aa1043 b/fuzzer/corpus/0063584d99e559d95f7574303efaaa7d66aa1043
new file mode 100644
index 0000000..cbc8e40
--- /dev/null
+++ b/fuzzer/corpus/0063584d99e559d95f7574303efaaa7d66aa1043
Binary files differ
diff --git a/fuzzer/corpus/0068209ec44b5bcc76df5fd390bee3451a931f75 b/fuzzer/corpus/0068209ec44b5bcc76df5fd390bee3451a931f75
new file mode 100644
index 0000000..4d03e32
--- /dev/null
+++ b/fuzzer/corpus/0068209ec44b5bcc76df5fd390bee3451a931f75
Binary files differ
diff --git a/fuzzer/corpus/00aba68e0b49a70a5d9bd4ee363eacf106519586 b/fuzzer/corpus/00aba68e0b49a70a5d9bd4ee363eacf106519586
new file mode 100644
index 0000000..b3bdad1
--- /dev/null
+++ b/fuzzer/corpus/00aba68e0b49a70a5d9bd4ee363eacf106519586
Binary files differ
diff --git a/fuzzer/corpus/00f65461899db1e20bcfbc27a9f6a0c2e563a70f b/fuzzer/corpus/00f65461899db1e20bcfbc27a9f6a0c2e563a70f
new file mode 100644
index 0000000..04b8a79
--- /dev/null
+++ b/fuzzer/corpus/00f65461899db1e20bcfbc27a9f6a0c2e563a70f
Binary files differ
diff --git a/fuzzer/corpus/01093511ce21ba2143348f1eb6cdc390b9d900ce b/fuzzer/corpus/01093511ce21ba2143348f1eb6cdc390b9d900ce
new file mode 100644
index 0000000..191e57f
--- /dev/null
+++ b/fuzzer/corpus/01093511ce21ba2143348f1eb6cdc390b9d900ce
Binary files differ
diff --git a/fuzzer/corpus/0191a956146c2b6eea8b009efb0f16589d44a856 b/fuzzer/corpus/0191a956146c2b6eea8b009efb0f16589d44a856
new file mode 100644
index 0000000..5e3fd65
--- /dev/null
+++ b/fuzzer/corpus/0191a956146c2b6eea8b009efb0f16589d44a856
Binary files differ
diff --git a/fuzzer/corpus/01980dea5a010187f31ea505fdf1b3f7e3e2c559 b/fuzzer/corpus/01980dea5a010187f31ea505fdf1b3f7e3e2c559
new file mode 100644
index 0000000..053cc6c
--- /dev/null
+++ b/fuzzer/corpus/01980dea5a010187f31ea505fdf1b3f7e3e2c559
Binary files differ
diff --git a/fuzzer/corpus/01b951775bc6cd4f54461597e65b84e44c292402 b/fuzzer/corpus/01b951775bc6cd4f54461597e65b84e44c292402
new file mode 100644
index 0000000..f5e2342
--- /dev/null
+++ b/fuzzer/corpus/01b951775bc6cd4f54461597e65b84e44c292402
Binary files differ
diff --git a/fuzzer/corpus/01cf3f39acd95472695e7a92b27b69e7cf1aff88 b/fuzzer/corpus/01cf3f39acd95472695e7a92b27b69e7cf1aff88
new file mode 100644
index 0000000..c53202d
--- /dev/null
+++ b/fuzzer/corpus/01cf3f39acd95472695e7a92b27b69e7cf1aff88
Binary files differ
diff --git a/fuzzer/corpus/02137ddc6d4c8a03cce587f0f295f8a14dc0e960 b/fuzzer/corpus/02137ddc6d4c8a03cce587f0f295f8a14dc0e960
new file mode 100644
index 0000000..1449439
--- /dev/null
+++ b/fuzzer/corpus/02137ddc6d4c8a03cce587f0f295f8a14dc0e960
Binary files differ
diff --git a/fuzzer/corpus/0225aedaaba06224630e8c7b641f9f987d38c29d b/fuzzer/corpus/0225aedaaba06224630e8c7b641f9f987d38c29d
new file mode 100644
index 0000000..80899db
--- /dev/null
+++ b/fuzzer/corpus/0225aedaaba06224630e8c7b641f9f987d38c29d
Binary files differ
diff --git a/fuzzer/corpus/02274d492863405f178860185520e380b9253dd1 b/fuzzer/corpus/02274d492863405f178860185520e380b9253dd1
new file mode 100644
index 0000000..814227c
--- /dev/null
+++ b/fuzzer/corpus/02274d492863405f178860185520e380b9253dd1
Binary files differ
diff --git a/fuzzer/corpus/02329129eb1b3647fcc65b670413e36fa6ffacd9 b/fuzzer/corpus/02329129eb1b3647fcc65b670413e36fa6ffacd9
new file mode 100644
index 0000000..58bb2a5
--- /dev/null
+++ b/fuzzer/corpus/02329129eb1b3647fcc65b670413e36fa6ffacd9
Binary files differ
diff --git a/fuzzer/corpus/0242c184029780608bd52c49883a188f333b90f5 b/fuzzer/corpus/0242c184029780608bd52c49883a188f333b90f5
new file mode 100644
index 0000000..f2e4e54
--- /dev/null
+++ b/fuzzer/corpus/0242c184029780608bd52c49883a188f333b90f5
Binary files differ
diff --git a/fuzzer/corpus/029c1bc38ee3a6a9e6d1cf95b421f06e868a8cc0 b/fuzzer/corpus/029c1bc38ee3a6a9e6d1cf95b421f06e868a8cc0
new file mode 100644
index 0000000..abd3c5f
--- /dev/null
+++ b/fuzzer/corpus/029c1bc38ee3a6a9e6d1cf95b421f06e868a8cc0
Binary files differ
diff --git a/fuzzer/corpus/02bed7d1b482d7b62be531eed715763b0872d6a5 b/fuzzer/corpus/02bed7d1b482d7b62be531eed715763b0872d6a5
new file mode 100644
index 0000000..d1920d8
--- /dev/null
+++ b/fuzzer/corpus/02bed7d1b482d7b62be531eed715763b0872d6a5
Binary files differ
diff --git a/fuzzer/corpus/02c705f93c1f075b5e473909f35b652a1fe5bf80 b/fuzzer/corpus/02c705f93c1f075b5e473909f35b652a1fe5bf80
new file mode 100644
index 0000000..9f03502
--- /dev/null
+++ b/fuzzer/corpus/02c705f93c1f075b5e473909f35b652a1fe5bf80
Binary files differ
diff --git a/fuzzer/corpus/02e43835c3874d724b186b0d024add681b1f9219 b/fuzzer/corpus/02e43835c3874d724b186b0d024add681b1f9219
new file mode 100644
index 0000000..6763e20
--- /dev/null
+++ b/fuzzer/corpus/02e43835c3874d724b186b0d024add681b1f9219
Binary files differ
diff --git a/fuzzer/corpus/02fb62ce864b7637f14818c411348cae30392a9e b/fuzzer/corpus/02fb62ce864b7637f14818c411348cae30392a9e
new file mode 100644
index 0000000..01b6c8b
--- /dev/null
+++ b/fuzzer/corpus/02fb62ce864b7637f14818c411348cae30392a9e
Binary files differ
diff --git a/fuzzer/corpus/030481afcfe047f8584391dc64b9307273590b6f b/fuzzer/corpus/030481afcfe047f8584391dc64b9307273590b6f
new file mode 100644
index 0000000..abf8334
--- /dev/null
+++ b/fuzzer/corpus/030481afcfe047f8584391dc64b9307273590b6f
Binary files differ
diff --git a/fuzzer/corpus/031e311800ff4e60382f18f854418870fd4aef13 b/fuzzer/corpus/031e311800ff4e60382f18f854418870fd4aef13
new file mode 100644
index 0000000..e705b6e
--- /dev/null
+++ b/fuzzer/corpus/031e311800ff4e60382f18f854418870fd4aef13
Binary files differ
diff --git a/fuzzer/corpus/0320551674956cf13d9827f99490b0339d59e672 b/fuzzer/corpus/0320551674956cf13d9827f99490b0339d59e672
new file mode 100644
index 0000000..56c0423
--- /dev/null
+++ b/fuzzer/corpus/0320551674956cf13d9827f99490b0339d59e672
Binary files differ
diff --git a/fuzzer/corpus/0339be7ee6c0a259d62bd533cc6bc1d94612d5ae b/fuzzer/corpus/0339be7ee6c0a259d62bd533cc6bc1d94612d5ae
new file mode 100644
index 0000000..3a137d5
--- /dev/null
+++ b/fuzzer/corpus/0339be7ee6c0a259d62bd533cc6bc1d94612d5ae
Binary files differ
diff --git a/fuzzer/corpus/034276781b173338c670d819af0ab4321d6aa50d b/fuzzer/corpus/034276781b173338c670d819af0ab4321d6aa50d
new file mode 100644
index 0000000..6ca109c
--- /dev/null
+++ b/fuzzer/corpus/034276781b173338c670d819af0ab4321d6aa50d
Binary files differ
diff --git a/fuzzer/corpus/03454e15dbc51d7de1126d1dfbaba101b483309c b/fuzzer/corpus/03454e15dbc51d7de1126d1dfbaba101b483309c
new file mode 100644
index 0000000..5d7e330
--- /dev/null
+++ b/fuzzer/corpus/03454e15dbc51d7de1126d1dfbaba101b483309c
Binary files differ
diff --git a/fuzzer/corpus/0385a3ffe2e5c799e479400669be2c29d6276531 b/fuzzer/corpus/0385a3ffe2e5c799e479400669be2c29d6276531
new file mode 100644
index 0000000..09b6af7
--- /dev/null
+++ b/fuzzer/corpus/0385a3ffe2e5c799e479400669be2c29d6276531
Binary files differ
diff --git a/fuzzer/corpus/039d62fcc18ecd8a91e8ba631c179911a8db340e b/fuzzer/corpus/039d62fcc18ecd8a91e8ba631c179911a8db340e
new file mode 100644
index 0000000..ac1c2af
--- /dev/null
+++ b/fuzzer/corpus/039d62fcc18ecd8a91e8ba631c179911a8db340e
Binary files differ
diff --git a/fuzzer/corpus/03b310f8e1c16c57e8f263c3d20448a9c0a1d00e b/fuzzer/corpus/03b310f8e1c16c57e8f263c3d20448a9c0a1d00e
new file mode 100644
index 0000000..4030139
--- /dev/null
+++ b/fuzzer/corpus/03b310f8e1c16c57e8f263c3d20448a9c0a1d00e
Binary files differ
diff --git a/fuzzer/corpus/03b7bc0ef864657df7756e2f38fc9c108f4edfa0 b/fuzzer/corpus/03b7bc0ef864657df7756e2f38fc9c108f4edfa0
new file mode 100644
index 0000000..deb391d
--- /dev/null
+++ b/fuzzer/corpus/03b7bc0ef864657df7756e2f38fc9c108f4edfa0
Binary files differ
diff --git a/fuzzer/corpus/04dfe903049df3eb0701a4785f5617a7a2d4735c b/fuzzer/corpus/04dfe903049df3eb0701a4785f5617a7a2d4735c
new file mode 100644
index 0000000..7e3cf24
--- /dev/null
+++ b/fuzzer/corpus/04dfe903049df3eb0701a4785f5617a7a2d4735c
Binary files differ
diff --git a/fuzzer/corpus/04e6dd5a888667bc225e7d9eac4e58b65045b42b b/fuzzer/corpus/04e6dd5a888667bc225e7d9eac4e58b65045b42b
new file mode 100644
index 0000000..65b7e4d
--- /dev/null
+++ b/fuzzer/corpus/04e6dd5a888667bc225e7d9eac4e58b65045b42b
Binary files differ
diff --git a/fuzzer/corpus/0500cd32ae315af1bf538eecd4572cc74ab94905 b/fuzzer/corpus/0500cd32ae315af1bf538eecd4572cc74ab94905
new file mode 100644
index 0000000..637ef51
--- /dev/null
+++ b/fuzzer/corpus/0500cd32ae315af1bf538eecd4572cc74ab94905
Binary files differ
diff --git a/fuzzer/corpus/050e91306cebc8f11b032eb9e9d662e862e92a3c b/fuzzer/corpus/050e91306cebc8f11b032eb9e9d662e862e92a3c
new file mode 100644
index 0000000..33203de
--- /dev/null
+++ b/fuzzer/corpus/050e91306cebc8f11b032eb9e9d662e862e92a3c
Binary files differ
diff --git a/fuzzer/corpus/051781418c3b4c91c3e84fe1c262d2a7e5aedf1b b/fuzzer/corpus/051781418c3b4c91c3e84fe1c262d2a7e5aedf1b
new file mode 100644
index 0000000..3391588
--- /dev/null
+++ b/fuzzer/corpus/051781418c3b4c91c3e84fe1c262d2a7e5aedf1b
Binary files differ
diff --git a/fuzzer/corpus/051df98d56e1664ca2179b51485bcb49728cd3be b/fuzzer/corpus/051df98d56e1664ca2179b51485bcb49728cd3be
new file mode 100644
index 0000000..3fb485b
--- /dev/null
+++ b/fuzzer/corpus/051df98d56e1664ca2179b51485bcb49728cd3be
Binary files differ
diff --git a/fuzzer/corpus/051f2e54bc804cc50fe9c2262e9d5ec67061ae65 b/fuzzer/corpus/051f2e54bc804cc50fe9c2262e9d5ec67061ae65
new file mode 100644
index 0000000..de9c4b4
--- /dev/null
+++ b/fuzzer/corpus/051f2e54bc804cc50fe9c2262e9d5ec67061ae65
Binary files differ
diff --git a/fuzzer/corpus/05539d721692acd0db015698981d31b923485a3d b/fuzzer/corpus/05539d721692acd0db015698981d31b923485a3d
new file mode 100644
index 0000000..71ce404
--- /dev/null
+++ b/fuzzer/corpus/05539d721692acd0db015698981d31b923485a3d
Binary files differ
diff --git a/fuzzer/corpus/055a309f795cc0d18fa936a70dc3fbdb20f16a0a b/fuzzer/corpus/055a309f795cc0d18fa936a70dc3fbdb20f16a0a
new file mode 100644
index 0000000..56fdb43
--- /dev/null
+++ b/fuzzer/corpus/055a309f795cc0d18fa936a70dc3fbdb20f16a0a
Binary files differ
diff --git a/fuzzer/corpus/056fe9accc18d702f74947a041dfa3528595a28e b/fuzzer/corpus/056fe9accc18d702f74947a041dfa3528595a28e
new file mode 100644
index 0000000..1cec1b7
--- /dev/null
+++ b/fuzzer/corpus/056fe9accc18d702f74947a041dfa3528595a28e
Binary files differ
diff --git a/fuzzer/corpus/058d2ffb707aa9a256f8a27b482c351dc59d9562 b/fuzzer/corpus/058d2ffb707aa9a256f8a27b482c351dc59d9562
new file mode 100644
index 0000000..453dbda
--- /dev/null
+++ b/fuzzer/corpus/058d2ffb707aa9a256f8a27b482c351dc59d9562
Binary files differ
diff --git a/fuzzer/corpus/0592773c7693fcb746fcccae36e018c816d72548 b/fuzzer/corpus/0592773c7693fcb746fcccae36e018c816d72548
new file mode 100644
index 0000000..d427efc
--- /dev/null
+++ b/fuzzer/corpus/0592773c7693fcb746fcccae36e018c816d72548
Binary files differ
diff --git a/fuzzer/corpus/0593930c933a73b0ae747d1c57f3e8ce1990d66c b/fuzzer/corpus/0593930c933a73b0ae747d1c57f3e8ce1990d66c
new file mode 100644
index 0000000..c6f026d
--- /dev/null
+++ b/fuzzer/corpus/0593930c933a73b0ae747d1c57f3e8ce1990d66c
Binary files differ
diff --git a/fuzzer/corpus/059c4168c4567d8ddace90563ae3d4faad8c5aad b/fuzzer/corpus/059c4168c4567d8ddace90563ae3d4faad8c5aad
new file mode 100644
index 0000000..0eeb076
--- /dev/null
+++ b/fuzzer/corpus/059c4168c4567d8ddace90563ae3d4faad8c5aad
Binary files differ
diff --git a/fuzzer/corpus/05a53ea6556822ee0ba50cf11477cdc82bca042b b/fuzzer/corpus/05a53ea6556822ee0ba50cf11477cdc82bca042b
new file mode 100644
index 0000000..79bf46e
--- /dev/null
+++ b/fuzzer/corpus/05a53ea6556822ee0ba50cf11477cdc82bca042b
Binary files differ
diff --git a/fuzzer/corpus/05ac2b295f457e6d82af70e03197058e243330a5 b/fuzzer/corpus/05ac2b295f457e6d82af70e03197058e243330a5
new file mode 100644
index 0000000..75c240f
--- /dev/null
+++ b/fuzzer/corpus/05ac2b295f457e6d82af70e03197058e243330a5
Binary files differ
diff --git a/fuzzer/corpus/05ba6eed3aaf1e11881f108e363705ea6684b5ee b/fuzzer/corpus/05ba6eed3aaf1e11881f108e363705ea6684b5ee
new file mode 100644
index 0000000..934d399
--- /dev/null
+++ b/fuzzer/corpus/05ba6eed3aaf1e11881f108e363705ea6684b5ee
Binary files differ
diff --git a/fuzzer/corpus/05de42787114bd230c00bc28974c2e0abc5276cd b/fuzzer/corpus/05de42787114bd230c00bc28974c2e0abc5276cd
new file mode 100644
index 0000000..12f6d3f
--- /dev/null
+++ b/fuzzer/corpus/05de42787114bd230c00bc28974c2e0abc5276cd
Binary files differ
diff --git a/fuzzer/corpus/05e4184169408bddef4e3ed9395b25b3307c0dc4 b/fuzzer/corpus/05e4184169408bddef4e3ed9395b25b3307c0dc4
new file mode 100644
index 0000000..2d10180
--- /dev/null
+++ b/fuzzer/corpus/05e4184169408bddef4e3ed9395b25b3307c0dc4
Binary files differ
diff --git a/fuzzer/corpus/05fd25c9e7186a048e4b048316725d7d8e2957f2 b/fuzzer/corpus/05fd25c9e7186a048e4b048316725d7d8e2957f2
new file mode 100644
index 0000000..1da61c8
--- /dev/null
+++ b/fuzzer/corpus/05fd25c9e7186a048e4b048316725d7d8e2957f2
Binary files differ
diff --git a/fuzzer/corpus/063561babc7dd125c0199ce988b2d9e3ecf5b166 b/fuzzer/corpus/063561babc7dd125c0199ce988b2d9e3ecf5b166
new file mode 100644
index 0000000..b092c71
--- /dev/null
+++ b/fuzzer/corpus/063561babc7dd125c0199ce988b2d9e3ecf5b166
Binary files differ
diff --git a/fuzzer/corpus/065e940fa5cec8b3198461acf8f5284ec45f588b b/fuzzer/corpus/065e940fa5cec8b3198461acf8f5284ec45f588b
new file mode 100644
index 0000000..d7b92e2
--- /dev/null
+++ b/fuzzer/corpus/065e940fa5cec8b3198461acf8f5284ec45f588b
Binary files differ
diff --git a/fuzzer/corpus/06766094522762e8f4c17953a7a437e5ff0ce2f5 b/fuzzer/corpus/06766094522762e8f4c17953a7a437e5ff0ce2f5
new file mode 100644
index 0000000..37c67a2
--- /dev/null
+++ b/fuzzer/corpus/06766094522762e8f4c17953a7a437e5ff0ce2f5
Binary files differ
diff --git a/fuzzer/corpus/067cc48411aaea493a14052eb1974ca2b3477846 b/fuzzer/corpus/067cc48411aaea493a14052eb1974ca2b3477846
new file mode 100644
index 0000000..497cddd
--- /dev/null
+++ b/fuzzer/corpus/067cc48411aaea493a14052eb1974ca2b3477846
Binary files differ
diff --git a/fuzzer/corpus/069e356aeb44c3384ac22309d6601d75337ce2d0 b/fuzzer/corpus/069e356aeb44c3384ac22309d6601d75337ce2d0
new file mode 100644
index 0000000..8fba9cb
--- /dev/null
+++ b/fuzzer/corpus/069e356aeb44c3384ac22309d6601d75337ce2d0
Binary files differ
diff --git a/fuzzer/corpus/06a8e02d0a2fa29cee49b44b1ae9a4c3fb4e2405 b/fuzzer/corpus/06a8e02d0a2fa29cee49b44b1ae9a4c3fb4e2405
new file mode 100644
index 0000000..a03eace
--- /dev/null
+++ b/fuzzer/corpus/06a8e02d0a2fa29cee49b44b1ae9a4c3fb4e2405
Binary files differ
diff --git a/fuzzer/corpus/06b8aeed1879d286b3e4234132fdd2169c693ae2 b/fuzzer/corpus/06b8aeed1879d286b3e4234132fdd2169c693ae2
new file mode 100644
index 0000000..8517c37
--- /dev/null
+++ b/fuzzer/corpus/06b8aeed1879d286b3e4234132fdd2169c693ae2
Binary files differ
diff --git a/fuzzer/corpus/06b9a8464c56257b2f7d51211da84cead2a5e171 b/fuzzer/corpus/06b9a8464c56257b2f7d51211da84cead2a5e171
new file mode 100644
index 0000000..9ebccc9
--- /dev/null
+++ b/fuzzer/corpus/06b9a8464c56257b2f7d51211da84cead2a5e171
Binary files differ
diff --git a/fuzzer/corpus/06c8e757034bdac3525e1155089b4dfc01386bb2 b/fuzzer/corpus/06c8e757034bdac3525e1155089b4dfc01386bb2
new file mode 100644
index 0000000..425bb27
--- /dev/null
+++ b/fuzzer/corpus/06c8e757034bdac3525e1155089b4dfc01386bb2
Binary files differ
diff --git a/fuzzer/corpus/07060875482510021e7e723e03d15b58b89d23ba b/fuzzer/corpus/07060875482510021e7e723e03d15b58b89d23ba
new file mode 100644
index 0000000..9a6ab4f
--- /dev/null
+++ b/fuzzer/corpus/07060875482510021e7e723e03d15b58b89d23ba
Binary files differ
diff --git a/fuzzer/corpus/070ebaae52ef308f39d3b6d2aec9d4987645dbfe b/fuzzer/corpus/070ebaae52ef308f39d3b6d2aec9d4987645dbfe
new file mode 100644
index 0000000..1419784
--- /dev/null
+++ b/fuzzer/corpus/070ebaae52ef308f39d3b6d2aec9d4987645dbfe
Binary files differ
diff --git a/fuzzer/corpus/0713046ee5b8569f6d68e44892a284cb8d07f1e6 b/fuzzer/corpus/0713046ee5b8569f6d68e44892a284cb8d07f1e6
new file mode 100644
index 0000000..182e237
--- /dev/null
+++ b/fuzzer/corpus/0713046ee5b8569f6d68e44892a284cb8d07f1e6
Binary files differ
diff --git a/fuzzer/corpus/072d3e69419fae30bb4d06f5b3b682998b413df3 b/fuzzer/corpus/072d3e69419fae30bb4d06f5b3b682998b413df3
new file mode 100644
index 0000000..983fcbb
--- /dev/null
+++ b/fuzzer/corpus/072d3e69419fae30bb4d06f5b3b682998b413df3
Binary files differ
diff --git a/fuzzer/corpus/0745fbf2076dd36e71d517486c51fbb29275fb99 b/fuzzer/corpus/0745fbf2076dd36e71d517486c51fbb29275fb99
new file mode 100644
index 0000000..4c37a36
--- /dev/null
+++ b/fuzzer/corpus/0745fbf2076dd36e71d517486c51fbb29275fb99
Binary files differ
diff --git a/fuzzer/corpus/077bfe79b6b8e2f07e5142cb0ff7f2af106c981d b/fuzzer/corpus/077bfe79b6b8e2f07e5142cb0ff7f2af106c981d
new file mode 100644
index 0000000..4a9100c
--- /dev/null
+++ b/fuzzer/corpus/077bfe79b6b8e2f07e5142cb0ff7f2af106c981d
Binary files differ
diff --git a/fuzzer/corpus/07814cbcb24e0b5546e9aa864e7f7aa9a168c564 b/fuzzer/corpus/07814cbcb24e0b5546e9aa864e7f7aa9a168c564
new file mode 100644
index 0000000..e007cf1
--- /dev/null
+++ b/fuzzer/corpus/07814cbcb24e0b5546e9aa864e7f7aa9a168c564
Binary files differ
diff --git a/fuzzer/corpus/0798cf7167b61ed2cfb1800011801bc68c65214d b/fuzzer/corpus/0798cf7167b61ed2cfb1800011801bc68c65214d
new file mode 100644
index 0000000..c28656a
--- /dev/null
+++ b/fuzzer/corpus/0798cf7167b61ed2cfb1800011801bc68c65214d
Binary files differ
diff --git a/fuzzer/corpus/07f6c6929eff77bd0d56e82ea4736ec28f7aea3a b/fuzzer/corpus/07f6c6929eff77bd0d56e82ea4736ec28f7aea3a
new file mode 100644
index 0000000..ade27f8
--- /dev/null
+++ b/fuzzer/corpus/07f6c6929eff77bd0d56e82ea4736ec28f7aea3a
Binary files differ
diff --git a/fuzzer/corpus/081ea4232ae7fdecc019ec13088c224a73b0b451 b/fuzzer/corpus/081ea4232ae7fdecc019ec13088c224a73b0b451
new file mode 100644
index 0000000..d89c54f
--- /dev/null
+++ b/fuzzer/corpus/081ea4232ae7fdecc019ec13088c224a73b0b451
Binary files differ
diff --git a/fuzzer/corpus/0840e6087046fc23e86e2c331aedfa68123108e2 b/fuzzer/corpus/0840e6087046fc23e86e2c331aedfa68123108e2
new file mode 100644
index 0000000..9369ec5
--- /dev/null
+++ b/fuzzer/corpus/0840e6087046fc23e86e2c331aedfa68123108e2
Binary files differ
diff --git a/fuzzer/corpus/0842d7d0c5f51d75658a8d060ce8b69dc5df61d5 b/fuzzer/corpus/0842d7d0c5f51d75658a8d060ce8b69dc5df61d5
new file mode 100644
index 0000000..a9d79af
--- /dev/null
+++ b/fuzzer/corpus/0842d7d0c5f51d75658a8d060ce8b69dc5df61d5
@@ -0,0 +1 @@
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿu*eÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/fuzzer/corpus/088764c1162b27b87d049bd2b4121aaa8f49d6e9 b/fuzzer/corpus/088764c1162b27b87d049bd2b4121aaa8f49d6e9
new file mode 100644
index 0000000..87db8a8
--- /dev/null
+++ b/fuzzer/corpus/088764c1162b27b87d049bd2b4121aaa8f49d6e9
Binary files differ
diff --git a/fuzzer/corpus/08898301ab36474b3dfb6462a699b1900b7fe6a3 b/fuzzer/corpus/08898301ab36474b3dfb6462a699b1900b7fe6a3
new file mode 100644
index 0000000..149d9fd
--- /dev/null
+++ b/fuzzer/corpus/08898301ab36474b3dfb6462a699b1900b7fe6a3
Binary files differ
diff --git a/fuzzer/corpus/08902272daf08e6bf1b54733ff959b2d6a15ba79 b/fuzzer/corpus/08902272daf08e6bf1b54733ff959b2d6a15ba79
new file mode 100644
index 0000000..b693de8
--- /dev/null
+++ b/fuzzer/corpus/08902272daf08e6bf1b54733ff959b2d6a15ba79
Binary files differ
diff --git a/fuzzer/corpus/089e1387a8ea73afd87f01bfa75af9327ddfe3c5 b/fuzzer/corpus/089e1387a8ea73afd87f01bfa75af9327ddfe3c5
new file mode 100644
index 0000000..e00f4bd
--- /dev/null
+++ b/fuzzer/corpus/089e1387a8ea73afd87f01bfa75af9327ddfe3c5
Binary files differ
diff --git a/fuzzer/corpus/08ba205bc389ee3a7e42a47a80489a6fc68b5922 b/fuzzer/corpus/08ba205bc389ee3a7e42a47a80489a6fc68b5922
new file mode 100644
index 0000000..478c9a2
--- /dev/null
+++ b/fuzzer/corpus/08ba205bc389ee3a7e42a47a80489a6fc68b5922
Binary files differ
diff --git a/fuzzer/corpus/08c4b15079e0c5a2eed4604535299d145a23c16c b/fuzzer/corpus/08c4b15079e0c5a2eed4604535299d145a23c16c
new file mode 100644
index 0000000..fc90325
--- /dev/null
+++ b/fuzzer/corpus/08c4b15079e0c5a2eed4604535299d145a23c16c
Binary files differ
diff --git a/fuzzer/corpus/08c4f6f4abfa6fbdf044775fc91dea997eca8da1 b/fuzzer/corpus/08c4f6f4abfa6fbdf044775fc91dea997eca8da1
new file mode 100644
index 0000000..118a5aa
--- /dev/null
+++ b/fuzzer/corpus/08c4f6f4abfa6fbdf044775fc91dea997eca8da1
Binary files differ
diff --git a/fuzzer/corpus/08f15fc50d84dc626a87437e3b6833d7b04d73e2 b/fuzzer/corpus/08f15fc50d84dc626a87437e3b6833d7b04d73e2
new file mode 100644
index 0000000..e9a6c69
--- /dev/null
+++ b/fuzzer/corpus/08f15fc50d84dc626a87437e3b6833d7b04d73e2
Binary files differ
diff --git a/fuzzer/corpus/08f7011dda2e8df54ed4a4c7932648f067d74b88 b/fuzzer/corpus/08f7011dda2e8df54ed4a4c7932648f067d74b88
new file mode 100644
index 0000000..5843877
--- /dev/null
+++ b/fuzzer/corpus/08f7011dda2e8df54ed4a4c7932648f067d74b88
Binary files differ
diff --git a/fuzzer/corpus/092d5acd482e169f1a35215856f8fbd5a1ebc358 b/fuzzer/corpus/092d5acd482e169f1a35215856f8fbd5a1ebc358
new file mode 100644
index 0000000..2abfbfd
--- /dev/null
+++ b/fuzzer/corpus/092d5acd482e169f1a35215856f8fbd5a1ebc358
Binary files differ
diff --git a/fuzzer/corpus/09348a438f44b9bbd2a9432bf8878d98ac2dd9ef b/fuzzer/corpus/09348a438f44b9bbd2a9432bf8878d98ac2dd9ef
new file mode 100644
index 0000000..e4a5e28
--- /dev/null
+++ b/fuzzer/corpus/09348a438f44b9bbd2a9432bf8878d98ac2dd9ef
Binary files differ
diff --git a/fuzzer/corpus/093c49bb9bccdac898ffb2d59c6a68b2e89f2f96 b/fuzzer/corpus/093c49bb9bccdac898ffb2d59c6a68b2e89f2f96
new file mode 100644
index 0000000..62a3234
--- /dev/null
+++ b/fuzzer/corpus/093c49bb9bccdac898ffb2d59c6a68b2e89f2f96
Binary files differ
diff --git a/fuzzer/corpus/09408a322bedf519a3c5d821133d722d88b21c58 b/fuzzer/corpus/09408a322bedf519a3c5d821133d722d88b21c58
new file mode 100644
index 0000000..cb1bba5
--- /dev/null
+++ b/fuzzer/corpus/09408a322bedf519a3c5d821133d722d88b21c58
Binary files differ
diff --git a/fuzzer/corpus/0941531e215dca2d25d3206ae458ac4f4d2d8d88 b/fuzzer/corpus/0941531e215dca2d25d3206ae458ac4f4d2d8d88
new file mode 100644
index 0000000..673719f
--- /dev/null
+++ b/fuzzer/corpus/0941531e215dca2d25d3206ae458ac4f4d2d8d88
Binary files differ
diff --git a/fuzzer/corpus/094aefe210ab041f01d93f25e77480ec1107843f b/fuzzer/corpus/094aefe210ab041f01d93f25e77480ec1107843f
new file mode 100644
index 0000000..929628c
--- /dev/null
+++ b/fuzzer/corpus/094aefe210ab041f01d93f25e77480ec1107843f
Binary files differ
diff --git a/fuzzer/corpus/096ede5656818a9b33329aeb1a6bf7265627b640 b/fuzzer/corpus/096ede5656818a9b33329aeb1a6bf7265627b640
new file mode 100644
index 0000000..cd274df
--- /dev/null
+++ b/fuzzer/corpus/096ede5656818a9b33329aeb1a6bf7265627b640
Binary files differ
diff --git a/fuzzer/corpus/0982c7135c8ad390b4f89c160825b6d98ab803a6 b/fuzzer/corpus/0982c7135c8ad390b4f89c160825b6d98ab803a6
new file mode 100644
index 0000000..704504e
--- /dev/null
+++ b/fuzzer/corpus/0982c7135c8ad390b4f89c160825b6d98ab803a6
Binary files differ
diff --git a/fuzzer/corpus/098c766ed84871e1fe0d55e342176141b88c6e18 b/fuzzer/corpus/098c766ed84871e1fe0d55e342176141b88c6e18
new file mode 100644
index 0000000..68f195e
--- /dev/null
+++ b/fuzzer/corpus/098c766ed84871e1fe0d55e342176141b88c6e18
Binary files differ
diff --git a/fuzzer/corpus/099a19243cad226b84fed1b8db1bfc3e5113c45f b/fuzzer/corpus/099a19243cad226b84fed1b8db1bfc3e5113c45f
new file mode 100644
index 0000000..708e8b6
--- /dev/null
+++ b/fuzzer/corpus/099a19243cad226b84fed1b8db1bfc3e5113c45f
Binary files differ
diff --git a/fuzzer/corpus/09ff328b37e723d6a52d6c5cad15e328a46d67cc b/fuzzer/corpus/09ff328b37e723d6a52d6c5cad15e328a46d67cc
new file mode 100644
index 0000000..17a58c6
--- /dev/null
+++ b/fuzzer/corpus/09ff328b37e723d6a52d6c5cad15e328a46d67cc
Binary files differ
diff --git a/fuzzer/corpus/0a08bdde597d95bef31b3f2f679ddcb1b816f11b b/fuzzer/corpus/0a08bdde597d95bef31b3f2f679ddcb1b816f11b
new file mode 100644
index 0000000..83459a8
--- /dev/null
+++ b/fuzzer/corpus/0a08bdde597d95bef31b3f2f679ddcb1b816f11b
Binary files differ
diff --git a/fuzzer/corpus/0a1f21f7bcee5a153c2bb0e5f9c194a997a90426 b/fuzzer/corpus/0a1f21f7bcee5a153c2bb0e5f9c194a997a90426
new file mode 100644
index 0000000..5c19311
--- /dev/null
+++ b/fuzzer/corpus/0a1f21f7bcee5a153c2bb0e5f9c194a997a90426
Binary files differ
diff --git a/fuzzer/corpus/0a23315ff62c0ec8a48c8e45de2e6409321e4ff5 b/fuzzer/corpus/0a23315ff62c0ec8a48c8e45de2e6409321e4ff5
new file mode 100644
index 0000000..45c6401
--- /dev/null
+++ b/fuzzer/corpus/0a23315ff62c0ec8a48c8e45de2e6409321e4ff5
Binary files differ
diff --git a/fuzzer/corpus/0a485c09b9b7116c12b0c09d76f34c43aae136aa b/fuzzer/corpus/0a485c09b9b7116c12b0c09d76f34c43aae136aa
new file mode 100644
index 0000000..d1e014e
--- /dev/null
+++ b/fuzzer/corpus/0a485c09b9b7116c12b0c09d76f34c43aae136aa
Binary files differ
diff --git a/fuzzer/corpus/0a5f6124c715f94dd5834b7f0117c8a367176117 b/fuzzer/corpus/0a5f6124c715f94dd5834b7f0117c8a367176117
new file mode 100644
index 0000000..dadf11c
--- /dev/null
+++ b/fuzzer/corpus/0a5f6124c715f94dd5834b7f0117c8a367176117
Binary files differ
diff --git a/fuzzer/corpus/0a83be702790967e92a681ae521e34f9dcb7032e b/fuzzer/corpus/0a83be702790967e92a681ae521e34f9dcb7032e
new file mode 100644
index 0000000..fb576e6
--- /dev/null
+++ b/fuzzer/corpus/0a83be702790967e92a681ae521e34f9dcb7032e
Binary files differ
diff --git a/fuzzer/corpus/0a9cafa9df7a5f6edb1823e7d854ac46a9b244d2 b/fuzzer/corpus/0a9cafa9df7a5f6edb1823e7d854ac46a9b244d2
new file mode 100644
index 0000000..1750007
--- /dev/null
+++ b/fuzzer/corpus/0a9cafa9df7a5f6edb1823e7d854ac46a9b244d2
Binary files differ
diff --git a/fuzzer/corpus/0a9cf33434e23f6f4db4e45df315c4ec73c2a260 b/fuzzer/corpus/0a9cf33434e23f6f4db4e45df315c4ec73c2a260
new file mode 100644
index 0000000..82ec8ae
--- /dev/null
+++ b/fuzzer/corpus/0a9cf33434e23f6f4db4e45df315c4ec73c2a260
Binary files differ
diff --git a/fuzzer/corpus/0ab40fbf2b76dca836fa4fa121ca393663cc2e7b b/fuzzer/corpus/0ab40fbf2b76dca836fa4fa121ca393663cc2e7b
new file mode 100644
index 0000000..2a10952
--- /dev/null
+++ b/fuzzer/corpus/0ab40fbf2b76dca836fa4fa121ca393663cc2e7b
Binary files differ
diff --git a/fuzzer/corpus/0b0a7d16784aebbd05cf5a7b2af92f3657004d8b b/fuzzer/corpus/0b0a7d16784aebbd05cf5a7b2af92f3657004d8b
new file mode 100644
index 0000000..deaa9bb
--- /dev/null
+++ b/fuzzer/corpus/0b0a7d16784aebbd05cf5a7b2af92f3657004d8b
Binary files differ
diff --git a/fuzzer/corpus/0b0e0fa9cfdd30cae7823d1dcf622a2f504884f4 b/fuzzer/corpus/0b0e0fa9cfdd30cae7823d1dcf622a2f504884f4
new file mode 100644
index 0000000..b5f2f78
--- /dev/null
+++ b/fuzzer/corpus/0b0e0fa9cfdd30cae7823d1dcf622a2f504884f4
Binary files differ
diff --git a/fuzzer/corpus/0b45eaf9ca6d929c409d344b55e91f5e6e36942f b/fuzzer/corpus/0b45eaf9ca6d929c409d344b55e91f5e6e36942f
new file mode 100644
index 0000000..850eb59
--- /dev/null
+++ b/fuzzer/corpus/0b45eaf9ca6d929c409d344b55e91f5e6e36942f
Binary files differ
diff --git a/fuzzer/corpus/0b47f78707cf005058384cd1e7e034845b332fd7 b/fuzzer/corpus/0b47f78707cf005058384cd1e7e034845b332fd7
new file mode 100644
index 0000000..cccbaa5
--- /dev/null
+++ b/fuzzer/corpus/0b47f78707cf005058384cd1e7e034845b332fd7
Binary files differ
diff --git a/fuzzer/corpus/0b53d780e946f28d827e35ac7778d17f8bb130ff b/fuzzer/corpus/0b53d780e946f28d827e35ac7778d17f8bb130ff
new file mode 100644
index 0000000..e201c03
--- /dev/null
+++ b/fuzzer/corpus/0b53d780e946f28d827e35ac7778d17f8bb130ff
Binary files differ
diff --git a/fuzzer/corpus/0b6878d289eead16e8ff787fb0bb630f834c9acc b/fuzzer/corpus/0b6878d289eead16e8ff787fb0bb630f834c9acc
new file mode 100644
index 0000000..88db47e
--- /dev/null
+++ b/fuzzer/corpus/0b6878d289eead16e8ff787fb0bb630f834c9acc
Binary files differ
diff --git a/fuzzer/corpus/0b71974af915b2f0c6fd38bd27082c99262e7b8e b/fuzzer/corpus/0b71974af915b2f0c6fd38bd27082c99262e7b8e
new file mode 100644
index 0000000..a588bf8
--- /dev/null
+++ b/fuzzer/corpus/0b71974af915b2f0c6fd38bd27082c99262e7b8e
Binary files differ
diff --git a/fuzzer/corpus/0b73ad5e360a55bedc8bd3f908692aa19082f163 b/fuzzer/corpus/0b73ad5e360a55bedc8bd3f908692aa19082f163
new file mode 100644
index 0000000..e417349
--- /dev/null
+++ b/fuzzer/corpus/0b73ad5e360a55bedc8bd3f908692aa19082f163
Binary files differ
diff --git a/fuzzer/corpus/0b95252916e3788b4e49600d3646e069fad8e392 b/fuzzer/corpus/0b95252916e3788b4e49600d3646e069fad8e392
new file mode 100644
index 0000000..4c96582
--- /dev/null
+++ b/fuzzer/corpus/0b95252916e3788b4e49600d3646e069fad8e392
Binary files differ
diff --git a/fuzzer/corpus/0ba4cfd67c08eab21f1a4ef02e966b7d8a9eab25 b/fuzzer/corpus/0ba4cfd67c08eab21f1a4ef02e966b7d8a9eab25
new file mode 100644
index 0000000..f085b21
--- /dev/null
+++ b/fuzzer/corpus/0ba4cfd67c08eab21f1a4ef02e966b7d8a9eab25
Binary files differ
diff --git a/fuzzer/corpus/0bb532b810a0b0f13d473838d4f7676b206bfcf0 b/fuzzer/corpus/0bb532b810a0b0f13d473838d4f7676b206bfcf0
new file mode 100644
index 0000000..4757eae
--- /dev/null
+++ b/fuzzer/corpus/0bb532b810a0b0f13d473838d4f7676b206bfcf0
Binary files differ
diff --git a/fuzzer/corpus/0bcd6e7d3c5e1ce3d3184bc64fb37ead8de43a16 b/fuzzer/corpus/0bcd6e7d3c5e1ce3d3184bc64fb37ead8de43a16
new file mode 100644
index 0000000..29a724f
--- /dev/null
+++ b/fuzzer/corpus/0bcd6e7d3c5e1ce3d3184bc64fb37ead8de43a16
Binary files differ
diff --git a/fuzzer/corpus/0be07a86c0df5258ebd70442c46bbba5009927dc b/fuzzer/corpus/0be07a86c0df5258ebd70442c46bbba5009927dc
new file mode 100644
index 0000000..f0970d0
--- /dev/null
+++ b/fuzzer/corpus/0be07a86c0df5258ebd70442c46bbba5009927dc
Binary files differ
diff --git a/fuzzer/corpus/0c2e96c40ae7c243fffc9825a44b00d206444b56 b/fuzzer/corpus/0c2e96c40ae7c243fffc9825a44b00d206444b56
new file mode 100644
index 0000000..8e91152
--- /dev/null
+++ b/fuzzer/corpus/0c2e96c40ae7c243fffc9825a44b00d206444b56
Binary files differ
diff --git a/fuzzer/corpus/0c3b829efd6c1df47d4cf903c7ea96f1e8b54cee b/fuzzer/corpus/0c3b829efd6c1df47d4cf903c7ea96f1e8b54cee
new file mode 100644
index 0000000..0c95ab3
--- /dev/null
+++ b/fuzzer/corpus/0c3b829efd6c1df47d4cf903c7ea96f1e8b54cee
Binary files differ
diff --git a/fuzzer/corpus/0c78f857acec16092cf998d8c44894eb1ddce77c b/fuzzer/corpus/0c78f857acec16092cf998d8c44894eb1ddce77c
new file mode 100644
index 0000000..86ad4ce
--- /dev/null
+++ b/fuzzer/corpus/0c78f857acec16092cf998d8c44894eb1ddce77c
Binary files differ
diff --git a/fuzzer/corpus/0c9cd9b8d3dbf3d31be28725f635a4ef59901c99 b/fuzzer/corpus/0c9cd9b8d3dbf3d31be28725f635a4ef59901c99
new file mode 100644
index 0000000..2908918
--- /dev/null
+++ b/fuzzer/corpus/0c9cd9b8d3dbf3d31be28725f635a4ef59901c99
Binary files differ
diff --git a/fuzzer/corpus/0cb30cc8bb29e9ecb263f86c8fb65b3462274d99 b/fuzzer/corpus/0cb30cc8bb29e9ecb263f86c8fb65b3462274d99
new file mode 100644
index 0000000..bb1a087
--- /dev/null
+++ b/fuzzer/corpus/0cb30cc8bb29e9ecb263f86c8fb65b3462274d99
Binary files differ
diff --git a/fuzzer/corpus/0cc45599f2bdce269a425cea96f7873ffba96439 b/fuzzer/corpus/0cc45599f2bdce269a425cea96f7873ffba96439
new file mode 100644
index 0000000..6067ec7
--- /dev/null
+++ b/fuzzer/corpus/0cc45599f2bdce269a425cea96f7873ffba96439
Binary files differ
diff --git a/fuzzer/corpus/0ce33b085f7fd07e35a255014258c43ed6aeac5e b/fuzzer/corpus/0ce33b085f7fd07e35a255014258c43ed6aeac5e
new file mode 100644
index 0000000..ecb8100
--- /dev/null
+++ b/fuzzer/corpus/0ce33b085f7fd07e35a255014258c43ed6aeac5e
Binary files differ
diff --git a/fuzzer/corpus/0cf2c747728fff29b1f5f58c6c0e05e07e21cae7 b/fuzzer/corpus/0cf2c747728fff29b1f5f58c6c0e05e07e21cae7
new file mode 100644
index 0000000..f972dcf
--- /dev/null
+++ b/fuzzer/corpus/0cf2c747728fff29b1f5f58c6c0e05e07e21cae7
Binary files differ
diff --git a/fuzzer/corpus/0d04ce1a2c20bcb54992f345f4257155d0e0719d b/fuzzer/corpus/0d04ce1a2c20bcb54992f345f4257155d0e0719d
new file mode 100644
index 0000000..0059e45
--- /dev/null
+++ b/fuzzer/corpus/0d04ce1a2c20bcb54992f345f4257155d0e0719d
Binary files differ
diff --git a/fuzzer/corpus/0d57949067883dc35477e6ec810947ef44450e64 b/fuzzer/corpus/0d57949067883dc35477e6ec810947ef44450e64
new file mode 100644
index 0000000..3eb31b7
--- /dev/null
+++ b/fuzzer/corpus/0d57949067883dc35477e6ec810947ef44450e64
Binary files differ
diff --git a/fuzzer/corpus/0d6a5e25c11d7f569ef579d3a4d0f3de7bc21bf7 b/fuzzer/corpus/0d6a5e25c11d7f569ef579d3a4d0f3de7bc21bf7
new file mode 100644
index 0000000..9d08b9b
--- /dev/null
+++ b/fuzzer/corpus/0d6a5e25c11d7f569ef579d3a4d0f3de7bc21bf7
Binary files differ
diff --git a/fuzzer/corpus/0d6cf32fc6ee3cec7b0807f3316c6ca2f5e9e0cb b/fuzzer/corpus/0d6cf32fc6ee3cec7b0807f3316c6ca2f5e9e0cb
new file mode 100644
index 0000000..500951f
--- /dev/null
+++ b/fuzzer/corpus/0d6cf32fc6ee3cec7b0807f3316c6ca2f5e9e0cb
Binary files differ
diff --git a/fuzzer/corpus/0d813bc002fa52de02deebe0bb0fa428a1ee4cad b/fuzzer/corpus/0d813bc002fa52de02deebe0bb0fa428a1ee4cad
new file mode 100644
index 0000000..40db023
--- /dev/null
+++ b/fuzzer/corpus/0d813bc002fa52de02deebe0bb0fa428a1ee4cad
Binary files differ
diff --git a/fuzzer/corpus/0da5f1e1de1727cd7555dcb9ca1a0c725ee62e3f b/fuzzer/corpus/0da5f1e1de1727cd7555dcb9ca1a0c725ee62e3f
new file mode 100644
index 0000000..cdbba5d
--- /dev/null
+++ b/fuzzer/corpus/0da5f1e1de1727cd7555dcb9ca1a0c725ee62e3f
Binary files differ
diff --git a/fuzzer/corpus/0df58d320f751d2dcf559f8fafedb42994035dd8 b/fuzzer/corpus/0df58d320f751d2dcf559f8fafedb42994035dd8
new file mode 100644
index 0000000..9b0cb9e
--- /dev/null
+++ b/fuzzer/corpus/0df58d320f751d2dcf559f8fafedb42994035dd8
Binary files differ
diff --git a/fuzzer/corpus/0df9354cb689e53770b13c7b31219bcf34d0163b b/fuzzer/corpus/0df9354cb689e53770b13c7b31219bcf34d0163b
new file mode 100644
index 0000000..6a9a793
--- /dev/null
+++ b/fuzzer/corpus/0df9354cb689e53770b13c7b31219bcf34d0163b
Binary files differ
diff --git a/fuzzer/corpus/0e151d71bcf4df62790cc196096eb6d0e1601688 b/fuzzer/corpus/0e151d71bcf4df62790cc196096eb6d0e1601688
new file mode 100644
index 0000000..76fd48d
--- /dev/null
+++ b/fuzzer/corpus/0e151d71bcf4df62790cc196096eb6d0e1601688
Binary files differ
diff --git a/fuzzer/corpus/0e16367eceb4f5b5526e06bc7a5b55d1b53fca73 b/fuzzer/corpus/0e16367eceb4f5b5526e06bc7a5b55d1b53fca73
new file mode 100644
index 0000000..163366a
--- /dev/null
+++ b/fuzzer/corpus/0e16367eceb4f5b5526e06bc7a5b55d1b53fca73
Binary files differ
diff --git a/fuzzer/corpus/0e1f38d2f6c55064c22525d6d143f42fa174bc19 b/fuzzer/corpus/0e1f38d2f6c55064c22525d6d143f42fa174bc19
new file mode 100644
index 0000000..07c7aac
--- /dev/null
+++ b/fuzzer/corpus/0e1f38d2f6c55064c22525d6d143f42fa174bc19
Binary files differ
diff --git a/fuzzer/corpus/0e24e772929f8f6356686d362a5c6d81000a5b2f b/fuzzer/corpus/0e24e772929f8f6356686d362a5c6d81000a5b2f
new file mode 100644
index 0000000..d7887ad
--- /dev/null
+++ b/fuzzer/corpus/0e24e772929f8f6356686d362a5c6d81000a5b2f
Binary files differ
diff --git a/fuzzer/corpus/0e27505ded1b13af4c9a60452ea1e5c8689a3a68 b/fuzzer/corpus/0e27505ded1b13af4c9a60452ea1e5c8689a3a68
new file mode 100644
index 0000000..c692e9e
--- /dev/null
+++ b/fuzzer/corpus/0e27505ded1b13af4c9a60452ea1e5c8689a3a68
Binary files differ
diff --git a/fuzzer/corpus/0e2d32b4b3026107dfbf6271b4c29eda5ddc8225 b/fuzzer/corpus/0e2d32b4b3026107dfbf6271b4c29eda5ddc8225
new file mode 100644
index 0000000..77dc004
--- /dev/null
+++ b/fuzzer/corpus/0e2d32b4b3026107dfbf6271b4c29eda5ddc8225
Binary files differ
diff --git a/fuzzer/corpus/0e8fe4feacfe262b2e81eccb028e26f30a0ae9a9 b/fuzzer/corpus/0e8fe4feacfe262b2e81eccb028e26f30a0ae9a9
new file mode 100644
index 0000000..a1a3fbd
--- /dev/null
+++ b/fuzzer/corpus/0e8fe4feacfe262b2e81eccb028e26f30a0ae9a9
Binary files differ
diff --git a/fuzzer/corpus/0e903098663ddeaa0a8cffb4cb0794687d443387 b/fuzzer/corpus/0e903098663ddeaa0a8cffb4cb0794687d443387
new file mode 100644
index 0000000..184050e
--- /dev/null
+++ b/fuzzer/corpus/0e903098663ddeaa0a8cffb4cb0794687d443387
Binary files differ
diff --git a/fuzzer/corpus/0ea94a4329b77ac55425accc3f45e00835cabcab b/fuzzer/corpus/0ea94a4329b77ac55425accc3f45e00835cabcab
new file mode 100644
index 0000000..40cdb1b
--- /dev/null
+++ b/fuzzer/corpus/0ea94a4329b77ac55425accc3f45e00835cabcab
Binary files differ
diff --git a/fuzzer/corpus/0eadc19736f781636c50a9a0ac6b25bd4414c96e b/fuzzer/corpus/0eadc19736f781636c50a9a0ac6b25bd4414c96e
new file mode 100644
index 0000000..18474f9
--- /dev/null
+++ b/fuzzer/corpus/0eadc19736f781636c50a9a0ac6b25bd4414c96e
Binary files differ
diff --git a/fuzzer/corpus/0ed5d3e2df87df961cd2deb341b8e9a67209c6e1 b/fuzzer/corpus/0ed5d3e2df87df961cd2deb341b8e9a67209c6e1
new file mode 100644
index 0000000..4e2aeb6
--- /dev/null
+++ b/fuzzer/corpus/0ed5d3e2df87df961cd2deb341b8e9a67209c6e1
Binary files differ
diff --git a/fuzzer/corpus/0ef196119127905d092568e2f4dff4ca9819f994 b/fuzzer/corpus/0ef196119127905d092568e2f4dff4ca9819f994
new file mode 100644
index 0000000..4f46498
--- /dev/null
+++ b/fuzzer/corpus/0ef196119127905d092568e2f4dff4ca9819f994
Binary files differ
diff --git a/fuzzer/corpus/0f0297462fb6410ce428cc75cb3ff96f1c3ed0b8 b/fuzzer/corpus/0f0297462fb6410ce428cc75cb3ff96f1c3ed0b8
new file mode 100644
index 0000000..4a3bdca
--- /dev/null
+++ b/fuzzer/corpus/0f0297462fb6410ce428cc75cb3ff96f1c3ed0b8
Binary files differ
diff --git a/fuzzer/corpus/0f12faf5d8fbedafbe01aac0b4bbc8f356751e2b b/fuzzer/corpus/0f12faf5d8fbedafbe01aac0b4bbc8f356751e2b
new file mode 100644
index 0000000..f456c69
--- /dev/null
+++ b/fuzzer/corpus/0f12faf5d8fbedafbe01aac0b4bbc8f356751e2b
Binary files differ
diff --git a/fuzzer/corpus/0f15f407a1ac27a9b189cb1985227022d227f01f b/fuzzer/corpus/0f15f407a1ac27a9b189cb1985227022d227f01f
new file mode 100644
index 0000000..f530bd9
--- /dev/null
+++ b/fuzzer/corpus/0f15f407a1ac27a9b189cb1985227022d227f01f
Binary files differ
diff --git a/fuzzer/corpus/0f457ddfd42fd5dd20fc59eae9c1371d9f274c70 b/fuzzer/corpus/0f457ddfd42fd5dd20fc59eae9c1371d9f274c70
new file mode 100644
index 0000000..3b0760c
--- /dev/null
+++ b/fuzzer/corpus/0f457ddfd42fd5dd20fc59eae9c1371d9f274c70
Binary files differ
diff --git a/fuzzer/corpus/0f897cf0f5f6312eb24bdd6f702987843df0b5fc b/fuzzer/corpus/0f897cf0f5f6312eb24bdd6f702987843df0b5fc
new file mode 100644
index 0000000..b61d712
--- /dev/null
+++ b/fuzzer/corpus/0f897cf0f5f6312eb24bdd6f702987843df0b5fc
Binary files differ
diff --git a/fuzzer/corpus/0faec3c7bbe27664d58ffdb654dd5650e56a010b b/fuzzer/corpus/0faec3c7bbe27664d58ffdb654dd5650e56a010b
new file mode 100644
index 0000000..6ade657
--- /dev/null
+++ b/fuzzer/corpus/0faec3c7bbe27664d58ffdb654dd5650e56a010b
Binary files differ
diff --git a/fuzzer/corpus/0ff2e806b8e0557f336dfcd9a2c3f11af71d20c1 b/fuzzer/corpus/0ff2e806b8e0557f336dfcd9a2c3f11af71d20c1
new file mode 100644
index 0000000..220aafe
--- /dev/null
+++ b/fuzzer/corpus/0ff2e806b8e0557f336dfcd9a2c3f11af71d20c1
Binary files differ
diff --git a/fuzzer/corpus/0ffed8703f6db0aaf1fbdee67426f19868359873 b/fuzzer/corpus/0ffed8703f6db0aaf1fbdee67426f19868359873
new file mode 100644
index 0000000..6931a85
--- /dev/null
+++ b/fuzzer/corpus/0ffed8703f6db0aaf1fbdee67426f19868359873
Binary files differ
diff --git a/fuzzer/corpus/10020fdcdb69d0b4b5600c1e476d3c7dee0a497c b/fuzzer/corpus/10020fdcdb69d0b4b5600c1e476d3c7dee0a497c
new file mode 100644
index 0000000..c2da2bb
--- /dev/null
+++ b/fuzzer/corpus/10020fdcdb69d0b4b5600c1e476d3c7dee0a497c
Binary files differ
diff --git a/fuzzer/corpus/10353359261f90d378d885e136c8822da559e277 b/fuzzer/corpus/10353359261f90d378d885e136c8822da559e277
new file mode 100644
index 0000000..b410734
--- /dev/null
+++ b/fuzzer/corpus/10353359261f90d378d885e136c8822da559e277
Binary files differ
diff --git a/fuzzer/corpus/106899ffb306c8414a01763d3641ea3d49f15f69 b/fuzzer/corpus/106899ffb306c8414a01763d3641ea3d49f15f69
new file mode 100644
index 0000000..3513818
--- /dev/null
+++ b/fuzzer/corpus/106899ffb306c8414a01763d3641ea3d49f15f69
Binary files differ
diff --git a/fuzzer/corpus/106d937a6e03980521f5cb5ca1da09f668361e45 b/fuzzer/corpus/106d937a6e03980521f5cb5ca1da09f668361e45
new file mode 100644
index 0000000..85b8f35
--- /dev/null
+++ b/fuzzer/corpus/106d937a6e03980521f5cb5ca1da09f668361e45
Binary files differ
diff --git a/fuzzer/corpus/1086fbbfd6b30c19b6dc5416b7e90242e95ffb59 b/fuzzer/corpus/1086fbbfd6b30c19b6dc5416b7e90242e95ffb59
new file mode 100644
index 0000000..4f56bc2
--- /dev/null
+++ b/fuzzer/corpus/1086fbbfd6b30c19b6dc5416b7e90242e95ffb59
Binary files differ
diff --git a/fuzzer/corpus/108b064b51c763b4ad0746b36dc371ced2a1df53 b/fuzzer/corpus/108b064b51c763b4ad0746b36dc371ced2a1df53
new file mode 100644
index 0000000..46add92
--- /dev/null
+++ b/fuzzer/corpus/108b064b51c763b4ad0746b36dc371ced2a1df53
Binary files differ
diff --git a/fuzzer/corpus/10c2c1a37537b0a61065d730ea05d8012da701aa b/fuzzer/corpus/10c2c1a37537b0a61065d730ea05d8012da701aa
new file mode 100644
index 0000000..361ece9
--- /dev/null
+++ b/fuzzer/corpus/10c2c1a37537b0a61065d730ea05d8012da701aa
Binary files differ
diff --git a/fuzzer/corpus/10f85c3d2ee49a5314f754d2f36b1b9bb10c639c b/fuzzer/corpus/10f85c3d2ee49a5314f754d2f36b1b9bb10c639c
new file mode 100644
index 0000000..370dbd7
--- /dev/null
+++ b/fuzzer/corpus/10f85c3d2ee49a5314f754d2f36b1b9bb10c639c
Binary files differ
diff --git a/fuzzer/corpus/112bf82f42f7565c078c10cbacd857ce7719390c b/fuzzer/corpus/112bf82f42f7565c078c10cbacd857ce7719390c
new file mode 100644
index 0000000..dca6ac2
--- /dev/null
+++ b/fuzzer/corpus/112bf82f42f7565c078c10cbacd857ce7719390c
Binary files differ
diff --git a/fuzzer/corpus/113cc39dbe4e96e681d052a79747ad2927aa6730 b/fuzzer/corpus/113cc39dbe4e96e681d052a79747ad2927aa6730
new file mode 100644
index 0000000..55657ce
--- /dev/null
+++ b/fuzzer/corpus/113cc39dbe4e96e681d052a79747ad2927aa6730
Binary files differ
diff --git a/fuzzer/corpus/11610fedcbba0e344e28e157e9aef567f5d16345 b/fuzzer/corpus/11610fedcbba0e344e28e157e9aef567f5d16345
new file mode 100644
index 0000000..6461355
--- /dev/null
+++ b/fuzzer/corpus/11610fedcbba0e344e28e157e9aef567f5d16345
Binary files differ
diff --git a/fuzzer/corpus/118f06bdbeb591043148d4e5d1ce27b0a9c9f8f3 b/fuzzer/corpus/118f06bdbeb591043148d4e5d1ce27b0a9c9f8f3
new file mode 100644
index 0000000..fe535a8
--- /dev/null
+++ b/fuzzer/corpus/118f06bdbeb591043148d4e5d1ce27b0a9c9f8f3
Binary files differ
diff --git a/fuzzer/corpus/11a49d50bc766e99bf0dcec52086f469a2f5f103 b/fuzzer/corpus/11a49d50bc766e99bf0dcec52086f469a2f5f103
new file mode 100644
index 0000000..17cd7df
--- /dev/null
+++ b/fuzzer/corpus/11a49d50bc766e99bf0dcec52086f469a2f5f103
Binary files differ
diff --git a/fuzzer/corpus/11bc680cc678bb6bbb5e680a990265e615dc4bfb b/fuzzer/corpus/11bc680cc678bb6bbb5e680a990265e615dc4bfb
new file mode 100644
index 0000000..ba37c67
--- /dev/null
+++ b/fuzzer/corpus/11bc680cc678bb6bbb5e680a990265e615dc4bfb
Binary files differ
diff --git a/fuzzer/corpus/11c2513261f7802865fa2c2d050b46b3928b2ad2 b/fuzzer/corpus/11c2513261f7802865fa2c2d050b46b3928b2ad2
new file mode 100644
index 0000000..296b558
--- /dev/null
+++ b/fuzzer/corpus/11c2513261f7802865fa2c2d050b46b3928b2ad2
Binary files differ
diff --git a/fuzzer/corpus/11ce8e0171a1f053a92450f2618e202e33c0e07d b/fuzzer/corpus/11ce8e0171a1f053a92450f2618e202e33c0e07d
new file mode 100644
index 0000000..39e7396
--- /dev/null
+++ b/fuzzer/corpus/11ce8e0171a1f053a92450f2618e202e33c0e07d
Binary files differ
diff --git a/fuzzer/corpus/11d3d01f2c2e8294a7d1baff76819cf558b57500 b/fuzzer/corpus/11d3d01f2c2e8294a7d1baff76819cf558b57500
new file mode 100644
index 0000000..f41596d
--- /dev/null
+++ b/fuzzer/corpus/11d3d01f2c2e8294a7d1baff76819cf558b57500
Binary files differ
diff --git a/fuzzer/corpus/11d784f1929d0a45649bb5be9d007e3770a67b75 b/fuzzer/corpus/11d784f1929d0a45649bb5be9d007e3770a67b75
new file mode 100644
index 0000000..394d6dc
--- /dev/null
+++ b/fuzzer/corpus/11d784f1929d0a45649bb5be9d007e3770a67b75
Binary files differ
diff --git a/fuzzer/corpus/11f711de1fea529eda028d72bec4fbaf52142955 b/fuzzer/corpus/11f711de1fea529eda028d72bec4fbaf52142955
new file mode 100644
index 0000000..b261d07
--- /dev/null
+++ b/fuzzer/corpus/11f711de1fea529eda028d72bec4fbaf52142955
Binary files differ
diff --git a/fuzzer/corpus/125ec7476de02df91a1b7fffcae7af02535b4a7e b/fuzzer/corpus/125ec7476de02df91a1b7fffcae7af02535b4a7e
new file mode 100644
index 0000000..853fc10
--- /dev/null
+++ b/fuzzer/corpus/125ec7476de02df91a1b7fffcae7af02535b4a7e
Binary files differ
diff --git a/fuzzer/corpus/129713ffde375e2a70a33c335ef12123815a6f08 b/fuzzer/corpus/129713ffde375e2a70a33c335ef12123815a6f08
new file mode 100644
index 0000000..128a2d6
--- /dev/null
+++ b/fuzzer/corpus/129713ffde375e2a70a33c335ef12123815a6f08
Binary files differ
diff --git a/fuzzer/corpus/12b841b6938f6bc4ad6f9280414dc059e36e4628 b/fuzzer/corpus/12b841b6938f6bc4ad6f9280414dc059e36e4628
new file mode 100644
index 0000000..e001e38
--- /dev/null
+++ b/fuzzer/corpus/12b841b6938f6bc4ad6f9280414dc059e36e4628
Binary files differ
diff --git a/fuzzer/corpus/12c4887d4f77ce1f88da51c42373c1677f5fb2ce b/fuzzer/corpus/12c4887d4f77ce1f88da51c42373c1677f5fb2ce
new file mode 100644
index 0000000..a92e8f1
--- /dev/null
+++ b/fuzzer/corpus/12c4887d4f77ce1f88da51c42373c1677f5fb2ce
Binary files differ
diff --git a/fuzzer/corpus/12cb907b48884f4aee44a0d1bab61d27556659fc b/fuzzer/corpus/12cb907b48884f4aee44a0d1bab61d27556659fc
new file mode 100644
index 0000000..1945b69
--- /dev/null
+++ b/fuzzer/corpus/12cb907b48884f4aee44a0d1bab61d27556659fc
Binary files differ
diff --git a/fuzzer/corpus/1332d4bedb9482a958e4a9ee88f0b2824ef4ac4c b/fuzzer/corpus/1332d4bedb9482a958e4a9ee88f0b2824ef4ac4c
new file mode 100644
index 0000000..5455ec0
--- /dev/null
+++ b/fuzzer/corpus/1332d4bedb9482a958e4a9ee88f0b2824ef4ac4c
Binary files differ
diff --git a/fuzzer/corpus/1347b7e3c16ba49ecd523c6405d33fee8e9102d3 b/fuzzer/corpus/1347b7e3c16ba49ecd523c6405d33fee8e9102d3
new file mode 100644
index 0000000..38f61e2
--- /dev/null
+++ b/fuzzer/corpus/1347b7e3c16ba49ecd523c6405d33fee8e9102d3
Binary files differ
diff --git a/fuzzer/corpus/137786a5add9ae16566d363c74a98339bf95069c b/fuzzer/corpus/137786a5add9ae16566d363c74a98339bf95069c
new file mode 100644
index 0000000..eb70631
--- /dev/null
+++ b/fuzzer/corpus/137786a5add9ae16566d363c74a98339bf95069c
Binary files differ
diff --git a/fuzzer/corpus/139d5e002579f5937f218cf10a73d89e8edf9411 b/fuzzer/corpus/139d5e002579f5937f218cf10a73d89e8edf9411
new file mode 100644
index 0000000..c7301b5
--- /dev/null
+++ b/fuzzer/corpus/139d5e002579f5937f218cf10a73d89e8edf9411
Binary files differ
diff --git a/fuzzer/corpus/13cb2e6d4f20030a7dfe97256da1fbb6f06aec43 b/fuzzer/corpus/13cb2e6d4f20030a7dfe97256da1fbb6f06aec43
new file mode 100644
index 0000000..0fdd888
--- /dev/null
+++ b/fuzzer/corpus/13cb2e6d4f20030a7dfe97256da1fbb6f06aec43
Binary files differ
diff --git a/fuzzer/corpus/13d2c7efc608333c80ad377f00854cc1eb477ac8 b/fuzzer/corpus/13d2c7efc608333c80ad377f00854cc1eb477ac8
new file mode 100644
index 0000000..53fe07a
--- /dev/null
+++ b/fuzzer/corpus/13d2c7efc608333c80ad377f00854cc1eb477ac8
Binary files differ
diff --git a/fuzzer/corpus/13f2ccae0436f4625fbbea1b467afa94708cf677 b/fuzzer/corpus/13f2ccae0436f4625fbbea1b467afa94708cf677
new file mode 100644
index 0000000..dae2ab0
--- /dev/null
+++ b/fuzzer/corpus/13f2ccae0436f4625fbbea1b467afa94708cf677
Binary files differ
diff --git a/fuzzer/corpus/13f9cec1aabcd60730a792ee79d43cd13040721a b/fuzzer/corpus/13f9cec1aabcd60730a792ee79d43cd13040721a
new file mode 100644
index 0000000..ceb5190
--- /dev/null
+++ b/fuzzer/corpus/13f9cec1aabcd60730a792ee79d43cd13040721a
Binary files differ
diff --git a/fuzzer/corpus/1411668b05f1ebea15b894317aa013ee23e0db81 b/fuzzer/corpus/1411668b05f1ebea15b894317aa013ee23e0db81
new file mode 100644
index 0000000..7c4155c
--- /dev/null
+++ b/fuzzer/corpus/1411668b05f1ebea15b894317aa013ee23e0db81
Binary files differ
diff --git a/fuzzer/corpus/14250df0dce407c9ca1762d042f3c223bf47bea2 b/fuzzer/corpus/14250df0dce407c9ca1762d042f3c223bf47bea2
new file mode 100644
index 0000000..b99d0e0
--- /dev/null
+++ b/fuzzer/corpus/14250df0dce407c9ca1762d042f3c223bf47bea2
Binary files differ
diff --git a/fuzzer/corpus/14ada392455cce4e078ac9011d65a1a0511e6023 b/fuzzer/corpus/14ada392455cce4e078ac9011d65a1a0511e6023
new file mode 100644
index 0000000..8875c67
--- /dev/null
+++ b/fuzzer/corpus/14ada392455cce4e078ac9011d65a1a0511e6023
Binary files differ
diff --git a/fuzzer/corpus/14fb2f67765a562023bd18e4d264088cd9a5a4ec b/fuzzer/corpus/14fb2f67765a562023bd18e4d264088cd9a5a4ec
new file mode 100644
index 0000000..3b42ecb
--- /dev/null
+++ b/fuzzer/corpus/14fb2f67765a562023bd18e4d264088cd9a5a4ec
Binary files differ
diff --git a/fuzzer/corpus/152d339594b5af9a0a28e045cf9b5eb845017c99 b/fuzzer/corpus/152d339594b5af9a0a28e045cf9b5eb845017c99
new file mode 100644
index 0000000..dfa0c23
--- /dev/null
+++ b/fuzzer/corpus/152d339594b5af9a0a28e045cf9b5eb845017c99
Binary files differ
diff --git a/fuzzer/corpus/1530fd7edbeec7869c725a18ed679e41c624ae3d b/fuzzer/corpus/1530fd7edbeec7869c725a18ed679e41c624ae3d
new file mode 100644
index 0000000..6db0435
--- /dev/null
+++ b/fuzzer/corpus/1530fd7edbeec7869c725a18ed679e41c624ae3d
@@ -0,0 +1 @@
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿu*e^
\ No newline at end of file
diff --git a/fuzzer/corpus/153fccc706e5c47b7436ea81499c8a6f986b31f9 b/fuzzer/corpus/153fccc706e5c47b7436ea81499c8a6f986b31f9
new file mode 100644
index 0000000..1bcbcb7
--- /dev/null
+++ b/fuzzer/corpus/153fccc706e5c47b7436ea81499c8a6f986b31f9
Binary files differ
diff --git a/fuzzer/corpus/15509174166c9a924a5e48e12154074775b5fc37 b/fuzzer/corpus/15509174166c9a924a5e48e12154074775b5fc37
new file mode 100644
index 0000000..3337f8a
--- /dev/null
+++ b/fuzzer/corpus/15509174166c9a924a5e48e12154074775b5fc37
Binary files differ
diff --git a/fuzzer/corpus/1568ae57a7f12f568f76b8f0057473a9b4b7519b b/fuzzer/corpus/1568ae57a7f12f568f76b8f0057473a9b4b7519b
new file mode 100644
index 0000000..3d28146
--- /dev/null
+++ b/fuzzer/corpus/1568ae57a7f12f568f76b8f0057473a9b4b7519b
Binary files differ
diff --git a/fuzzer/corpus/158e9583be2f79abf80f7282f24c723a76fde845 b/fuzzer/corpus/158e9583be2f79abf80f7282f24c723a76fde845
new file mode 100644
index 0000000..e66aa18
--- /dev/null
+++ b/fuzzer/corpus/158e9583be2f79abf80f7282f24c723a76fde845
Binary files differ
diff --git a/fuzzer/corpus/15b3290f4811f52095f53b8dbe5bfda07280c656 b/fuzzer/corpus/15b3290f4811f52095f53b8dbe5bfda07280c656
new file mode 100644
index 0000000..7e402e8
--- /dev/null
+++ b/fuzzer/corpus/15b3290f4811f52095f53b8dbe5bfda07280c656
Binary files differ
diff --git a/fuzzer/corpus/15bf86750a9593c30ad1bc6c0de027c022b48d1f b/fuzzer/corpus/15bf86750a9593c30ad1bc6c0de027c022b48d1f
new file mode 100644
index 0000000..272b071
--- /dev/null
+++ b/fuzzer/corpus/15bf86750a9593c30ad1bc6c0de027c022b48d1f
Binary files differ
diff --git a/fuzzer/corpus/15d35184a67502a0cbc45b8de19c05570aa99a7d b/fuzzer/corpus/15d35184a67502a0cbc45b8de19c05570aa99a7d
new file mode 100644
index 0000000..9157e34
--- /dev/null
+++ b/fuzzer/corpus/15d35184a67502a0cbc45b8de19c05570aa99a7d
Binary files differ
diff --git a/fuzzer/corpus/15d7a8f78b14422e1a79d5bdd936f78d48101cfd b/fuzzer/corpus/15d7a8f78b14422e1a79d5bdd936f78d48101cfd
new file mode 100644
index 0000000..1eb5d5e
--- /dev/null
+++ b/fuzzer/corpus/15d7a8f78b14422e1a79d5bdd936f78d48101cfd
Binary files differ
diff --git a/fuzzer/corpus/15eefbe9fcc1fcf48d544816d4fe517b63363a06 b/fuzzer/corpus/15eefbe9fcc1fcf48d544816d4fe517b63363a06
new file mode 100644
index 0000000..6f019bb
--- /dev/null
+++ b/fuzzer/corpus/15eefbe9fcc1fcf48d544816d4fe517b63363a06
Binary files differ
diff --git a/fuzzer/corpus/15ef439075a2c3e589aa7aa527ae9f5697304c88 b/fuzzer/corpus/15ef439075a2c3e589aa7aa527ae9f5697304c88
new file mode 100644
index 0000000..87dd689
--- /dev/null
+++ b/fuzzer/corpus/15ef439075a2c3e589aa7aa527ae9f5697304c88
Binary files differ
diff --git a/fuzzer/corpus/162f7fdaa63159281641a0f529b86598ececcba1 b/fuzzer/corpus/162f7fdaa63159281641a0f529b86598ececcba1
new file mode 100644
index 0000000..0612f3e
--- /dev/null
+++ b/fuzzer/corpus/162f7fdaa63159281641a0f529b86598ececcba1
Binary files differ
diff --git a/fuzzer/corpus/164fb77e922240a2dd91a53d9e4dbaeebefaba74 b/fuzzer/corpus/164fb77e922240a2dd91a53d9e4dbaeebefaba74
new file mode 100644
index 0000000..637368d
--- /dev/null
+++ b/fuzzer/corpus/164fb77e922240a2dd91a53d9e4dbaeebefaba74
Binary files differ
diff --git a/fuzzer/corpus/1655d4709eb28ee3f4d0475c8de90a0cd9331191 b/fuzzer/corpus/1655d4709eb28ee3f4d0475c8de90a0cd9331191
new file mode 100644
index 0000000..0835628
--- /dev/null
+++ b/fuzzer/corpus/1655d4709eb28ee3f4d0475c8de90a0cd9331191
Binary files differ
diff --git a/fuzzer/corpus/1690d12228908395a0dbee2057af9c10f338957f b/fuzzer/corpus/1690d12228908395a0dbee2057af9c10f338957f
new file mode 100644
index 0000000..0054d10
--- /dev/null
+++ b/fuzzer/corpus/1690d12228908395a0dbee2057af9c10f338957f
Binary files differ
diff --git a/fuzzer/corpus/16b8bcc4d8ec930505532403d9ef82ac4cddc756 b/fuzzer/corpus/16b8bcc4d8ec930505532403d9ef82ac4cddc756
new file mode 100644
index 0000000..a2d8bc9
--- /dev/null
+++ b/fuzzer/corpus/16b8bcc4d8ec930505532403d9ef82ac4cddc756
Binary files differ
diff --git a/fuzzer/corpus/16c0e62840c363d445403c8c384a968df4ab6129 b/fuzzer/corpus/16c0e62840c363d445403c8c384a968df4ab6129
new file mode 100644
index 0000000..397345b
--- /dev/null
+++ b/fuzzer/corpus/16c0e62840c363d445403c8c384a968df4ab6129
Binary files differ
diff --git a/fuzzer/corpus/16c7b668a461b4918816139a9ad3cce469a4e347 b/fuzzer/corpus/16c7b668a461b4918816139a9ad3cce469a4e347
new file mode 100644
index 0000000..da9572b
--- /dev/null
+++ b/fuzzer/corpus/16c7b668a461b4918816139a9ad3cce469a4e347
Binary files differ
diff --git a/fuzzer/corpus/16ca5cde1e50ad6b0909b5bbe7b69d8880141000 b/fuzzer/corpus/16ca5cde1e50ad6b0909b5bbe7b69d8880141000
new file mode 100644
index 0000000..f30c1cd
--- /dev/null
+++ b/fuzzer/corpus/16ca5cde1e50ad6b0909b5bbe7b69d8880141000
Binary files differ
diff --git a/fuzzer/corpus/16d758b26c9a90f85223cc5e0235304716088283 b/fuzzer/corpus/16d758b26c9a90f85223cc5e0235304716088283
new file mode 100644
index 0000000..055e195
--- /dev/null
+++ b/fuzzer/corpus/16d758b26c9a90f85223cc5e0235304716088283
Binary files differ
diff --git a/fuzzer/corpus/16e2f1c0d0db630d92a7aacc679c082f804d22bd b/fuzzer/corpus/16e2f1c0d0db630d92a7aacc679c082f804d22bd
new file mode 100644
index 0000000..4aed6de
--- /dev/null
+++ b/fuzzer/corpus/16e2f1c0d0db630d92a7aacc679c082f804d22bd
Binary files differ
diff --git a/fuzzer/corpus/16ea25a019063bb1ccf7b806c5c9f5e1893fc710 b/fuzzer/corpus/16ea25a019063bb1ccf7b806c5c9f5e1893fc710
new file mode 100644
index 0000000..bc9b214
--- /dev/null
+++ b/fuzzer/corpus/16ea25a019063bb1ccf7b806c5c9f5e1893fc710
Binary files differ
diff --git a/fuzzer/corpus/16ef185c5da3d10634abdd0d2b37fc5765e58cbf b/fuzzer/corpus/16ef185c5da3d10634abdd0d2b37fc5765e58cbf
new file mode 100644
index 0000000..0e87b64
--- /dev/null
+++ b/fuzzer/corpus/16ef185c5da3d10634abdd0d2b37fc5765e58cbf
Binary files differ
diff --git a/fuzzer/corpus/17289773390a998809f87df4c0ad828b304b17a2 b/fuzzer/corpus/17289773390a998809f87df4c0ad828b304b17a2
new file mode 100644
index 0000000..51a0a11
--- /dev/null
+++ b/fuzzer/corpus/17289773390a998809f87df4c0ad828b304b17a2
Binary files differ
diff --git a/fuzzer/corpus/1748e19ed1d71535cc11e7d4d3e2b95601daa152 b/fuzzer/corpus/1748e19ed1d71535cc11e7d4d3e2b95601daa152
new file mode 100644
index 0000000..aafdc29
--- /dev/null
+++ b/fuzzer/corpus/1748e19ed1d71535cc11e7d4d3e2b95601daa152
Binary files differ
diff --git a/fuzzer/corpus/180b5d8e467eaa17c97f8354c9764297d5fd2c69 b/fuzzer/corpus/180b5d8e467eaa17c97f8354c9764297d5fd2c69
new file mode 100644
index 0000000..578a5e8
--- /dev/null
+++ b/fuzzer/corpus/180b5d8e467eaa17c97f8354c9764297d5fd2c69
Binary files differ
diff --git a/fuzzer/corpus/180cbb1659b9d13634580714afeb51d64712e180 b/fuzzer/corpus/180cbb1659b9d13634580714afeb51d64712e180
new file mode 100644
index 0000000..7ed6b82
--- /dev/null
+++ b/fuzzer/corpus/180cbb1659b9d13634580714afeb51d64712e180
Binary files differ
diff --git a/fuzzer/corpus/1833e1700d98ffa165ec05491e1d51e451ceb1b9 b/fuzzer/corpus/1833e1700d98ffa165ec05491e1d51e451ceb1b9
new file mode 100644
index 0000000..30d3641
--- /dev/null
+++ b/fuzzer/corpus/1833e1700d98ffa165ec05491e1d51e451ceb1b9
Binary files differ
diff --git a/fuzzer/corpus/183420e4a244ec70f35b35f5beb47d09225ebfb6 b/fuzzer/corpus/183420e4a244ec70f35b35f5beb47d09225ebfb6
new file mode 100644
index 0000000..4aad8d6
--- /dev/null
+++ b/fuzzer/corpus/183420e4a244ec70f35b35f5beb47d09225ebfb6
Binary files differ
diff --git a/fuzzer/corpus/185edb2648ee2955e8be0092b5cfe3538a79a409 b/fuzzer/corpus/185edb2648ee2955e8be0092b5cfe3538a79a409
new file mode 100644
index 0000000..7078291
--- /dev/null
+++ b/fuzzer/corpus/185edb2648ee2955e8be0092b5cfe3538a79a409
Binary files differ
diff --git a/fuzzer/corpus/189034da51d05386e0428ff97433aef413764026 b/fuzzer/corpus/189034da51d05386e0428ff97433aef413764026
new file mode 100644
index 0000000..2ca1456
--- /dev/null
+++ b/fuzzer/corpus/189034da51d05386e0428ff97433aef413764026
Binary files differ
diff --git a/fuzzer/corpus/18b1e77bd0b37d14731aaaafc5b33d108d680a16 b/fuzzer/corpus/18b1e77bd0b37d14731aaaafc5b33d108d680a16
new file mode 100644
index 0000000..a20ffaa
--- /dev/null
+++ b/fuzzer/corpus/18b1e77bd0b37d14731aaaafc5b33d108d680a16
Binary files differ
diff --git a/fuzzer/corpus/18bafde5a80020975ac51fc61ce4308b843caf81 b/fuzzer/corpus/18bafde5a80020975ac51fc61ce4308b843caf81
new file mode 100644
index 0000000..7e0f5ce
--- /dev/null
+++ b/fuzzer/corpus/18bafde5a80020975ac51fc61ce4308b843caf81
Binary files differ
diff --git a/fuzzer/corpus/18bb987b2b56d2a842893b69482a81d593a83bda b/fuzzer/corpus/18bb987b2b56d2a842893b69482a81d593a83bda
new file mode 100644
index 0000000..3f2bf75
--- /dev/null
+++ b/fuzzer/corpus/18bb987b2b56d2a842893b69482a81d593a83bda
Binary files differ
diff --git a/fuzzer/corpus/18c1fc9726579bcb19df251b41a35c9934f1cb45 b/fuzzer/corpus/18c1fc9726579bcb19df251b41a35c9934f1cb45
new file mode 100644
index 0000000..dc06aea
--- /dev/null
+++ b/fuzzer/corpus/18c1fc9726579bcb19df251b41a35c9934f1cb45
Binary files differ
diff --git a/fuzzer/corpus/18ee580f0036635e86777fcae1898413cb85b5f1 b/fuzzer/corpus/18ee580f0036635e86777fcae1898413cb85b5f1
new file mode 100644
index 0000000..350a195
--- /dev/null
+++ b/fuzzer/corpus/18ee580f0036635e86777fcae1898413cb85b5f1
Binary files differ
diff --git a/fuzzer/corpus/190dd7833b267c8d92d3479266e3213d51bfcb54 b/fuzzer/corpus/190dd7833b267c8d92d3479266e3213d51bfcb54
new file mode 100644
index 0000000..85d697f
--- /dev/null
+++ b/fuzzer/corpus/190dd7833b267c8d92d3479266e3213d51bfcb54
Binary files differ
diff --git a/fuzzer/corpus/190f6cb999f13a8ba278b005a33fc9809347633b b/fuzzer/corpus/190f6cb999f13a8ba278b005a33fc9809347633b
new file mode 100644
index 0000000..9efd9d4
--- /dev/null
+++ b/fuzzer/corpus/190f6cb999f13a8ba278b005a33fc9809347633b
Binary files differ
diff --git a/fuzzer/corpus/191048251f2c2e09b17745ab719f6e2bd838f26e b/fuzzer/corpus/191048251f2c2e09b17745ab719f6e2bd838f26e
new file mode 100644
index 0000000..9b745d9
--- /dev/null
+++ b/fuzzer/corpus/191048251f2c2e09b17745ab719f6e2bd838f26e
Binary files differ
diff --git a/fuzzer/corpus/19181dcd992e1a7d1d33ab591d21ba60a693b8ad b/fuzzer/corpus/19181dcd992e1a7d1d33ab591d21ba60a693b8ad
new file mode 100644
index 0000000..ed93ccf
--- /dev/null
+++ b/fuzzer/corpus/19181dcd992e1a7d1d33ab591d21ba60a693b8ad
Binary files differ
diff --git a/fuzzer/corpus/192a17d52a83eaa270acf582e9e61cb6af690541 b/fuzzer/corpus/192a17d52a83eaa270acf582e9e61cb6af690541
new file mode 100644
index 0000000..3df09d6
--- /dev/null
+++ b/fuzzer/corpus/192a17d52a83eaa270acf582e9e61cb6af690541
Binary files differ
diff --git a/fuzzer/corpus/19389f74563061d1b6157f1f89ab4d16093de5e3 b/fuzzer/corpus/19389f74563061d1b6157f1f89ab4d16093de5e3
new file mode 100644
index 0000000..87c0260
--- /dev/null
+++ b/fuzzer/corpus/19389f74563061d1b6157f1f89ab4d16093de5e3
Binary files differ
diff --git a/fuzzer/corpus/193ab2d67563efbe350f17ce9cf473a0e0c7dc88 b/fuzzer/corpus/193ab2d67563efbe350f17ce9cf473a0e0c7dc88
new file mode 100644
index 0000000..ab6bff3
--- /dev/null
+++ b/fuzzer/corpus/193ab2d67563efbe350f17ce9cf473a0e0c7dc88
Binary files differ
diff --git a/fuzzer/corpus/194dab4253a4300ca7776e1309f931529d1d5ff9 b/fuzzer/corpus/194dab4253a4300ca7776e1309f931529d1d5ff9
new file mode 100644
index 0000000..67bfd3f
--- /dev/null
+++ b/fuzzer/corpus/194dab4253a4300ca7776e1309f931529d1d5ff9
Binary files differ
diff --git a/fuzzer/corpus/1952f847e548db1d422ad9ab80f1a9ff529c7a0f b/fuzzer/corpus/1952f847e548db1d422ad9ab80f1a9ff529c7a0f
new file mode 100644
index 0000000..0ef3d1d
--- /dev/null
+++ b/fuzzer/corpus/1952f847e548db1d422ad9ab80f1a9ff529c7a0f
Binary files differ
diff --git a/fuzzer/corpus/195b412f8c979a39c5a20fa6e38f6064e4c135c8 b/fuzzer/corpus/195b412f8c979a39c5a20fa6e38f6064e4c135c8
new file mode 100644
index 0000000..75eb017
--- /dev/null
+++ b/fuzzer/corpus/195b412f8c979a39c5a20fa6e38f6064e4c135c8
Binary files differ
diff --git a/fuzzer/corpus/199f12346c862ac534d33cdfa126e2449f2fb304 b/fuzzer/corpus/199f12346c862ac534d33cdfa126e2449f2fb304
new file mode 100644
index 0000000..0a40563
--- /dev/null
+++ b/fuzzer/corpus/199f12346c862ac534d33cdfa126e2449f2fb304
Binary files differ
diff --git a/fuzzer/corpus/19a685aac9dc4f6480eeb04ee8cfa17d3862ce60 b/fuzzer/corpus/19a685aac9dc4f6480eeb04ee8cfa17d3862ce60
new file mode 100644
index 0000000..b5c37c1
--- /dev/null
+++ b/fuzzer/corpus/19a685aac9dc4f6480eeb04ee8cfa17d3862ce60
Binary files differ
diff --git a/fuzzer/corpus/19b18f85e4c13b1c2c4aff0e77007a9f960776ab b/fuzzer/corpus/19b18f85e4c13b1c2c4aff0e77007a9f960776ab
new file mode 100644
index 0000000..e96001c
--- /dev/null
+++ b/fuzzer/corpus/19b18f85e4c13b1c2c4aff0e77007a9f960776ab
Binary files differ
diff --git a/fuzzer/corpus/19b95f88c6bc9aee7c73ad2cb314df5076eb93f3 b/fuzzer/corpus/19b95f88c6bc9aee7c73ad2cb314df5076eb93f3
new file mode 100644
index 0000000..7055dd5
--- /dev/null
+++ b/fuzzer/corpus/19b95f88c6bc9aee7c73ad2cb314df5076eb93f3
Binary files differ
diff --git a/fuzzer/corpus/19bb3720429208bbf3b0f810df1c2e66f02beb26 b/fuzzer/corpus/19bb3720429208bbf3b0f810df1c2e66f02beb26
new file mode 100644
index 0000000..8361674
--- /dev/null
+++ b/fuzzer/corpus/19bb3720429208bbf3b0f810df1c2e66f02beb26
Binary files differ
diff --git a/fuzzer/corpus/19be43ff2713b92a328b043d3cd4dbe4bc296416 b/fuzzer/corpus/19be43ff2713b92a328b043d3cd4dbe4bc296416
new file mode 100644
index 0000000..618141f
--- /dev/null
+++ b/fuzzer/corpus/19be43ff2713b92a328b043d3cd4dbe4bc296416
Binary files differ
diff --git a/fuzzer/corpus/19c83bb9287208ac96ce3aba044791697a56a792 b/fuzzer/corpus/19c83bb9287208ac96ce3aba044791697a56a792
new file mode 100644
index 0000000..1e9b937
--- /dev/null
+++ b/fuzzer/corpus/19c83bb9287208ac96ce3aba044791697a56a792
Binary files differ
diff --git a/fuzzer/corpus/19e7cfda3dad7f03203852b5b3eba69dd7a7288b b/fuzzer/corpus/19e7cfda3dad7f03203852b5b3eba69dd7a7288b
new file mode 100644
index 0000000..e67f97a
--- /dev/null
+++ b/fuzzer/corpus/19e7cfda3dad7f03203852b5b3eba69dd7a7288b
Binary files differ
diff --git a/fuzzer/corpus/19e8fdf7cde60aaad5adfbde80ddd63dc420e7f3 b/fuzzer/corpus/19e8fdf7cde60aaad5adfbde80ddd63dc420e7f3
new file mode 100644
index 0000000..8fb65a8
--- /dev/null
+++ b/fuzzer/corpus/19e8fdf7cde60aaad5adfbde80ddd63dc420e7f3
Binary files differ
diff --git a/fuzzer/corpus/19eab4f5e394806e573c01c8bac367fdffee6975 b/fuzzer/corpus/19eab4f5e394806e573c01c8bac367fdffee6975
new file mode 100644
index 0000000..6d46559
--- /dev/null
+++ b/fuzzer/corpus/19eab4f5e394806e573c01c8bac367fdffee6975
Binary files differ
diff --git a/fuzzer/corpus/1a1b82f5bc63cc1726632aabd342001a6e3a9f99 b/fuzzer/corpus/1a1b82f5bc63cc1726632aabd342001a6e3a9f99
new file mode 100644
index 0000000..0fe0b5f
--- /dev/null
+++ b/fuzzer/corpus/1a1b82f5bc63cc1726632aabd342001a6e3a9f99
Binary files differ
diff --git a/fuzzer/corpus/1a2b4d487f5ce01dd47f34f6ff9c5a39e68010e6 b/fuzzer/corpus/1a2b4d487f5ce01dd47f34f6ff9c5a39e68010e6
new file mode 100644
index 0000000..11758ec
--- /dev/null
+++ b/fuzzer/corpus/1a2b4d487f5ce01dd47f34f6ff9c5a39e68010e6
Binary files differ
diff --git a/fuzzer/corpus/1a4e264291647ba9af8e65803c03c74f2f411a32 b/fuzzer/corpus/1a4e264291647ba9af8e65803c03c74f2f411a32
new file mode 100644
index 0000000..7fcce74
--- /dev/null
+++ b/fuzzer/corpus/1a4e264291647ba9af8e65803c03c74f2f411a32
Binary files differ
diff --git a/fuzzer/corpus/1ac596ee837462a1cb97c505ae116430a83ffe3c b/fuzzer/corpus/1ac596ee837462a1cb97c505ae116430a83ffe3c
new file mode 100644
index 0000000..dc7d7bd
--- /dev/null
+++ b/fuzzer/corpus/1ac596ee837462a1cb97c505ae116430a83ffe3c
Binary files differ
diff --git a/fuzzer/corpus/1ad20d4c38e26a0b9e4672c2e4d1aebe39e9f3d3 b/fuzzer/corpus/1ad20d4c38e26a0b9e4672c2e4d1aebe39e9f3d3
new file mode 100644
index 0000000..0d1fd2a
--- /dev/null
+++ b/fuzzer/corpus/1ad20d4c38e26a0b9e4672c2e4d1aebe39e9f3d3
@@ -0,0 +1 @@
+s_0i_0i
\ No newline at end of file
diff --git a/fuzzer/corpus/1ae963370d665e48a6961d9e88424998c0fb88c3 b/fuzzer/corpus/1ae963370d665e48a6961d9e88424998c0fb88c3
new file mode 100644
index 0000000..8d97716
--- /dev/null
+++ b/fuzzer/corpus/1ae963370d665e48a6961d9e88424998c0fb88c3
Binary files differ
diff --git a/fuzzer/corpus/1b0b7ceabc1a5fd6a4236b578742f5de7aa49ebb b/fuzzer/corpus/1b0b7ceabc1a5fd6a4236b578742f5de7aa49ebb
new file mode 100644
index 0000000..d4a2082
--- /dev/null
+++ b/fuzzer/corpus/1b0b7ceabc1a5fd6a4236b578742f5de7aa49ebb
Binary files differ
diff --git a/fuzzer/corpus/1b3d48cff56a0335891bb4b61621c3d70e7a7d51 b/fuzzer/corpus/1b3d48cff56a0335891bb4b61621c3d70e7a7d51
new file mode 100644
index 0000000..cbbf915
--- /dev/null
+++ b/fuzzer/corpus/1b3d48cff56a0335891bb4b61621c3d70e7a7d51
Binary files differ
diff --git a/fuzzer/corpus/1b5481b66dde6ee35c80bce903d630cc3c2b5851 b/fuzzer/corpus/1b5481b66dde6ee35c80bce903d630cc3c2b5851
new file mode 100644
index 0000000..5d6bed1
--- /dev/null
+++ b/fuzzer/corpus/1b5481b66dde6ee35c80bce903d630cc3c2b5851
Binary files differ
diff --git a/fuzzer/corpus/1b65df661cfe121d546ba9362253e10b2696632b b/fuzzer/corpus/1b65df661cfe121d546ba9362253e10b2696632b
new file mode 100644
index 0000000..5ac6602
--- /dev/null
+++ b/fuzzer/corpus/1b65df661cfe121d546ba9362253e10b2696632b
Binary files differ
diff --git a/fuzzer/corpus/1b76fd0ad1366043a1f56b75f6c87ff4f51d46dc b/fuzzer/corpus/1b76fd0ad1366043a1f56b75f6c87ff4f51d46dc
new file mode 100644
index 0000000..a0d0aac
--- /dev/null
+++ b/fuzzer/corpus/1b76fd0ad1366043a1f56b75f6c87ff4f51d46dc
Binary files differ
diff --git a/fuzzer/corpus/1b7d36ac56b808296ad4bcf1fa65eef7b8d256f0 b/fuzzer/corpus/1b7d36ac56b808296ad4bcf1fa65eef7b8d256f0
new file mode 100644
index 0000000..92c01f1
--- /dev/null
+++ b/fuzzer/corpus/1b7d36ac56b808296ad4bcf1fa65eef7b8d256f0
Binary files differ
diff --git a/fuzzer/corpus/1bc9b6c41825ac42ce21717ad4afbc53683465bc b/fuzzer/corpus/1bc9b6c41825ac42ce21717ad4afbc53683465bc
new file mode 100644
index 0000000..ae1b33c
--- /dev/null
+++ b/fuzzer/corpus/1bc9b6c41825ac42ce21717ad4afbc53683465bc
Binary files differ
diff --git a/fuzzer/corpus/1be1b517d92b4d495ecd47c887d0d7c268c6db49 b/fuzzer/corpus/1be1b517d92b4d495ecd47c887d0d7c268c6db49
new file mode 100644
index 0000000..c9695fe
--- /dev/null
+++ b/fuzzer/corpus/1be1b517d92b4d495ecd47c887d0d7c268c6db49
Binary files differ
diff --git a/fuzzer/corpus/1c596a3a0b033b20de20f8deba4ad83c8d84a6f6 b/fuzzer/corpus/1c596a3a0b033b20de20f8deba4ad83c8d84a6f6
new file mode 100644
index 0000000..8820134
--- /dev/null
+++ b/fuzzer/corpus/1c596a3a0b033b20de20f8deba4ad83c8d84a6f6
Binary files differ
diff --git a/fuzzer/corpus/1c726e5ff7b037b201648e2dd403327597b5a375 b/fuzzer/corpus/1c726e5ff7b037b201648e2dd403327597b5a375
new file mode 100644
index 0000000..aa4f434
--- /dev/null
+++ b/fuzzer/corpus/1c726e5ff7b037b201648e2dd403327597b5a375
Binary files differ
diff --git a/fuzzer/corpus/1c7928b22e737ea5fd9720c636fe8c3a06f1e118 b/fuzzer/corpus/1c7928b22e737ea5fd9720c636fe8c3a06f1e118
new file mode 100644
index 0000000..cc78438
--- /dev/null
+++ b/fuzzer/corpus/1c7928b22e737ea5fd9720c636fe8c3a06f1e118
Binary files differ
diff --git a/fuzzer/corpus/1c82db6ba0cd64689a2f4daa3128908529253a31 b/fuzzer/corpus/1c82db6ba0cd64689a2f4daa3128908529253a31
new file mode 100644
index 0000000..bed5bd3
--- /dev/null
+++ b/fuzzer/corpus/1c82db6ba0cd64689a2f4daa3128908529253a31
Binary files differ
diff --git a/fuzzer/corpus/1cab314ed40788602a9abbb0f3180e704c679d02 b/fuzzer/corpus/1cab314ed40788602a9abbb0f3180e704c679d02
new file mode 100644
index 0000000..409b728
--- /dev/null
+++ b/fuzzer/corpus/1cab314ed40788602a9abbb0f3180e704c679d02
Binary files differ
diff --git a/fuzzer/corpus/1cb5781376248984e1028512c5cdb5777d4fc6a4 b/fuzzer/corpus/1cb5781376248984e1028512c5cdb5777d4fc6a4
new file mode 100644
index 0000000..b850254
--- /dev/null
+++ b/fuzzer/corpus/1cb5781376248984e1028512c5cdb5777d4fc6a4
Binary files differ
diff --git a/fuzzer/corpus/1cde4c21d886ccec58748c0d7df993a6e8c701da b/fuzzer/corpus/1cde4c21d886ccec58748c0d7df993a6e8c701da
new file mode 100644
index 0000000..2272afc
--- /dev/null
+++ b/fuzzer/corpus/1cde4c21d886ccec58748c0d7df993a6e8c701da
Binary files differ
diff --git a/fuzzer/corpus/1ce211f0e78de79878c1c2f26744aa9460e81d35 b/fuzzer/corpus/1ce211f0e78de79878c1c2f26744aa9460e81d35
new file mode 100644
index 0000000..3546def
--- /dev/null
+++ b/fuzzer/corpus/1ce211f0e78de79878c1c2f26744aa9460e81d35
Binary files differ
diff --git a/fuzzer/corpus/1d20720b200177fd0af56cf36d492509a761abf4 b/fuzzer/corpus/1d20720b200177fd0af56cf36d492509a761abf4
new file mode 100644
index 0000000..5d6e5d4
--- /dev/null
+++ b/fuzzer/corpus/1d20720b200177fd0af56cf36d492509a761abf4
Binary files differ
diff --git a/fuzzer/corpus/1d3b79b6b0040c3eb529d0819b55b0c8b8914dda b/fuzzer/corpus/1d3b79b6b0040c3eb529d0819b55b0c8b8914dda
new file mode 100644
index 0000000..6c46cc4
--- /dev/null
+++ b/fuzzer/corpus/1d3b79b6b0040c3eb529d0819b55b0c8b8914dda
Binary files differ
diff --git a/fuzzer/corpus/1d4bcefe39a815a4f323a5e5df3009acc2c3e1b3 b/fuzzer/corpus/1d4bcefe39a815a4f323a5e5df3009acc2c3e1b3
new file mode 100644
index 0000000..e387b51
--- /dev/null
+++ b/fuzzer/corpus/1d4bcefe39a815a4f323a5e5df3009acc2c3e1b3
Binary files differ
diff --git a/fuzzer/corpus/1d8acc57eea6870ad737ded85d4e0774b961557c b/fuzzer/corpus/1d8acc57eea6870ad737ded85d4e0774b961557c
new file mode 100644
index 0000000..fd2e104
--- /dev/null
+++ b/fuzzer/corpus/1d8acc57eea6870ad737ded85d4e0774b961557c
@@ -0,0 +1 @@
+se~{{{se__üs_[{{{{{{{{{{--ÿÿÿÿÿÿ__i
\ No newline at end of file
diff --git a/fuzzer/corpus/1d92a1890b0aac435aa0eb63697cdc4aaff77181 b/fuzzer/corpus/1d92a1890b0aac435aa0eb63697cdc4aaff77181
new file mode 100644
index 0000000..ee52915
--- /dev/null
+++ b/fuzzer/corpus/1d92a1890b0aac435aa0eb63697cdc4aaff77181
Binary files differ
diff --git a/fuzzer/corpus/1dca16d2e29e2bfb2476d153401ded8a0f50b9c1 b/fuzzer/corpus/1dca16d2e29e2bfb2476d153401ded8a0f50b9c1
new file mode 100644
index 0000000..acae802
--- /dev/null
+++ b/fuzzer/corpus/1dca16d2e29e2bfb2476d153401ded8a0f50b9c1
Binary files differ
diff --git a/fuzzer/corpus/1de28f1e1b6d8f703c99a2846712d9e63a1e6155 b/fuzzer/corpus/1de28f1e1b6d8f703c99a2846712d9e63a1e6155
new file mode 100644
index 0000000..220568a
--- /dev/null
+++ b/fuzzer/corpus/1de28f1e1b6d8f703c99a2846712d9e63a1e6155
Binary files differ
diff --git a/fuzzer/corpus/1df08a552acca9caab5ef72c1b39184c26981a50 b/fuzzer/corpus/1df08a552acca9caab5ef72c1b39184c26981a50
new file mode 100644
index 0000000..e3dbc2a
--- /dev/null
+++ b/fuzzer/corpus/1df08a552acca9caab5ef72c1b39184c26981a50
Binary files differ
diff --git a/fuzzer/corpus/1df6482dbec92e60541dbb58d6819cf519c00cda b/fuzzer/corpus/1df6482dbec92e60541dbb58d6819cf519c00cda
new file mode 100644
index 0000000..a145b3b
--- /dev/null
+++ b/fuzzer/corpus/1df6482dbec92e60541dbb58d6819cf519c00cda
Binary files differ
diff --git a/fuzzer/corpus/1e001b058cbf8a551961951384d42da41971fb72 b/fuzzer/corpus/1e001b058cbf8a551961951384d42da41971fb72
new file mode 100644
index 0000000..5c89472
--- /dev/null
+++ b/fuzzer/corpus/1e001b058cbf8a551961951384d42da41971fb72
Binary files differ
diff --git a/fuzzer/corpus/1e1de04d68b75e3a1415ccef3371e9bb72b99f9a b/fuzzer/corpus/1e1de04d68b75e3a1415ccef3371e9bb72b99f9a
new file mode 100644
index 0000000..d774120
--- /dev/null
+++ b/fuzzer/corpus/1e1de04d68b75e3a1415ccef3371e9bb72b99f9a
Binary files differ
diff --git a/fuzzer/corpus/1e257a9aca2ce3439a6e83188e56c9c6416f969b b/fuzzer/corpus/1e257a9aca2ce3439a6e83188e56c9c6416f969b
new file mode 100644
index 0000000..81f8a41
--- /dev/null
+++ b/fuzzer/corpus/1e257a9aca2ce3439a6e83188e56c9c6416f969b
Binary files differ
diff --git a/fuzzer/corpus/1e3ba081980c7474a300b5608fd0c5abf9d45db0 b/fuzzer/corpus/1e3ba081980c7474a300b5608fd0c5abf9d45db0
new file mode 100644
index 0000000..fdad921
--- /dev/null
+++ b/fuzzer/corpus/1e3ba081980c7474a300b5608fd0c5abf9d45db0
Binary files differ
diff --git a/fuzzer/corpus/1e5bdda85a505648439ff41ac23c33d5cf6b0ef7 b/fuzzer/corpus/1e5bdda85a505648439ff41ac23c33d5cf6b0ef7
new file mode 100644
index 0000000..c045325
--- /dev/null
+++ b/fuzzer/corpus/1e5bdda85a505648439ff41ac23c33d5cf6b0ef7
Binary files differ
diff --git a/fuzzer/corpus/1e5e4774fba88bf5d28f2a6e08b11ad2ebde47f5 b/fuzzer/corpus/1e5e4774fba88bf5d28f2a6e08b11ad2ebde47f5
new file mode 100644
index 0000000..ea2fd84
--- /dev/null
+++ b/fuzzer/corpus/1e5e4774fba88bf5d28f2a6e08b11ad2ebde47f5
Binary files differ
diff --git a/fuzzer/corpus/1e75f08c8fdfdd5ec4bb70eec4f236e77b3f3c49 b/fuzzer/corpus/1e75f08c8fdfdd5ec4bb70eec4f236e77b3f3c49
new file mode 100644
index 0000000..204d14e
--- /dev/null
+++ b/fuzzer/corpus/1e75f08c8fdfdd5ec4bb70eec4f236e77b3f3c49
Binary files differ
diff --git a/fuzzer/corpus/1f09cdb2f36a27faa3215a482922d0ddd171fb30 b/fuzzer/corpus/1f09cdb2f36a27faa3215a482922d0ddd171fb30
new file mode 100644
index 0000000..e64bc9e
--- /dev/null
+++ b/fuzzer/corpus/1f09cdb2f36a27faa3215a482922d0ddd171fb30
Binary files differ
diff --git a/fuzzer/corpus/1f243de603023706b356a1c202396c890b931d5a b/fuzzer/corpus/1f243de603023706b356a1c202396c890b931d5a
new file mode 100644
index 0000000..9393ab2
--- /dev/null
+++ b/fuzzer/corpus/1f243de603023706b356a1c202396c890b931d5a
Binary files differ
diff --git a/fuzzer/corpus/1f47ab0e8c89c4505faf634959468b81e58107d3 b/fuzzer/corpus/1f47ab0e8c89c4505faf634959468b81e58107d3
new file mode 100644
index 0000000..ad3ffeb
--- /dev/null
+++ b/fuzzer/corpus/1f47ab0e8c89c4505faf634959468b81e58107d3
Binary files differ
diff --git a/fuzzer/corpus/1f491b62170a646d98a0d5747939b46f2772fe71 b/fuzzer/corpus/1f491b62170a646d98a0d5747939b46f2772fe71
new file mode 100644
index 0000000..ea52b64
--- /dev/null
+++ b/fuzzer/corpus/1f491b62170a646d98a0d5747939b46f2772fe71
Binary files differ
diff --git a/fuzzer/corpus/1f4e8530da7437fae1266020f6fe48febf0007cd b/fuzzer/corpus/1f4e8530da7437fae1266020f6fe48febf0007cd
new file mode 100644
index 0000000..0eed097
--- /dev/null
+++ b/fuzzer/corpus/1f4e8530da7437fae1266020f6fe48febf0007cd
Binary files differ
diff --git a/fuzzer/corpus/1f7217e98aff28adbc22ae15da519b468806d9ce b/fuzzer/corpus/1f7217e98aff28adbc22ae15da519b468806d9ce
new file mode 100644
index 0000000..9115fb2
--- /dev/null
+++ b/fuzzer/corpus/1f7217e98aff28adbc22ae15da519b468806d9ce
Binary files differ
diff --git a/fuzzer/corpus/1f9065e1fa9ec98fe4ba0b3f48c4936687a69e4f b/fuzzer/corpus/1f9065e1fa9ec98fe4ba0b3f48c4936687a69e4f
new file mode 100644
index 0000000..4dd63b3
--- /dev/null
+++ b/fuzzer/corpus/1f9065e1fa9ec98fe4ba0b3f48c4936687a69e4f
Binary files differ
diff --git a/fuzzer/corpus/1fa57f9f404b031475b678adb8d5b58ac93beffc b/fuzzer/corpus/1fa57f9f404b031475b678adb8d5b58ac93beffc
new file mode 100644
index 0000000..1ab1eaf
--- /dev/null
+++ b/fuzzer/corpus/1fa57f9f404b031475b678adb8d5b58ac93beffc
Binary files differ
diff --git a/fuzzer/corpus/1fb4aa3a057a008d92b9a42de0b081e009f7dcab b/fuzzer/corpus/1fb4aa3a057a008d92b9a42de0b081e009f7dcab
new file mode 100644
index 0000000..1f54a0b
--- /dev/null
+++ b/fuzzer/corpus/1fb4aa3a057a008d92b9a42de0b081e009f7dcab
Binary files differ
diff --git a/fuzzer/corpus/1fc76076c283821acd06cb51d2bec0cb40841775 b/fuzzer/corpus/1fc76076c283821acd06cb51d2bec0cb40841775
new file mode 100644
index 0000000..de00de8
--- /dev/null
+++ b/fuzzer/corpus/1fc76076c283821acd06cb51d2bec0cb40841775
Binary files differ
diff --git a/fuzzer/corpus/1fe52b716c5d1f12064976beafb3f4c70fefcccf b/fuzzer/corpus/1fe52b716c5d1f12064976beafb3f4c70fefcccf
new file mode 100644
index 0000000..9e853f0
--- /dev/null
+++ b/fuzzer/corpus/1fe52b716c5d1f12064976beafb3f4c70fefcccf
Binary files differ
diff --git a/fuzzer/corpus/2024efffb9c49434d8893ba644d45dd77931363e b/fuzzer/corpus/2024efffb9c49434d8893ba644d45dd77931363e
new file mode 100644
index 0000000..0fc9891
--- /dev/null
+++ b/fuzzer/corpus/2024efffb9c49434d8893ba644d45dd77931363e
Binary files differ
diff --git a/fuzzer/corpus/203167cf6a0ab546f9376abe90aab7843600ee22 b/fuzzer/corpus/203167cf6a0ab546f9376abe90aab7843600ee22
new file mode 100644
index 0000000..2177cfb
--- /dev/null
+++ b/fuzzer/corpus/203167cf6a0ab546f9376abe90aab7843600ee22
Binary files differ
diff --git a/fuzzer/corpus/2057a70c4bb533699c469d33ab4953200bf39183 b/fuzzer/corpus/2057a70c4bb533699c469d33ab4953200bf39183
new file mode 100644
index 0000000..1429e2f
--- /dev/null
+++ b/fuzzer/corpus/2057a70c4bb533699c469d33ab4953200bf39183
Binary files differ
diff --git a/fuzzer/corpus/2064fa04451a270836ce84717b7560d9b46191e7 b/fuzzer/corpus/2064fa04451a270836ce84717b7560d9b46191e7
new file mode 100644
index 0000000..25c877e
--- /dev/null
+++ b/fuzzer/corpus/2064fa04451a270836ce84717b7560d9b46191e7
Binary files differ
diff --git a/fuzzer/corpus/20a6a5b02f865bcbcf9917bd84384c18cb6370c7 b/fuzzer/corpus/20a6a5b02f865bcbcf9917bd84384c18cb6370c7
new file mode 100644
index 0000000..1fb0e6a
--- /dev/null
+++ b/fuzzer/corpus/20a6a5b02f865bcbcf9917bd84384c18cb6370c7
Binary files differ
diff --git a/fuzzer/corpus/20b298482c5928c3de0d9ee2cc045eec2fc98810 b/fuzzer/corpus/20b298482c5928c3de0d9ee2cc045eec2fc98810
new file mode 100644
index 0000000..bdafd0f
--- /dev/null
+++ b/fuzzer/corpus/20b298482c5928c3de0d9ee2cc045eec2fc98810
Binary files differ
diff --git a/fuzzer/corpus/20b34f745ae491df455949031b534e4af7a8fa3c b/fuzzer/corpus/20b34f745ae491df455949031b534e4af7a8fa3c
new file mode 100644
index 0000000..15af68c
--- /dev/null
+++ b/fuzzer/corpus/20b34f745ae491df455949031b534e4af7a8fa3c
Binary files differ
diff --git a/fuzzer/corpus/20d484f3139ac254c92b40b6f3375b3a5452ead4 b/fuzzer/corpus/20d484f3139ac254c92b40b6f3375b3a5452ead4
new file mode 100644
index 0000000..cb5b92b
--- /dev/null
+++ b/fuzzer/corpus/20d484f3139ac254c92b40b6f3375b3a5452ead4
Binary files differ
diff --git a/fuzzer/corpus/20db24304c5de28bb68109c0365d7c690d0da989 b/fuzzer/corpus/20db24304c5de28bb68109c0365d7c690d0da989
new file mode 100644
index 0000000..16f3177
--- /dev/null
+++ b/fuzzer/corpus/20db24304c5de28bb68109c0365d7c690d0da989
Binary files differ
diff --git a/fuzzer/corpus/21318c1a2b8c7365b1bf7649c9ec0f3b79e50a27 b/fuzzer/corpus/21318c1a2b8c7365b1bf7649c9ec0f3b79e50a27
new file mode 100644
index 0000000..cf4608c
--- /dev/null
+++ b/fuzzer/corpus/21318c1a2b8c7365b1bf7649c9ec0f3b79e50a27
Binary files differ
diff --git a/fuzzer/corpus/21550a35b9b0025fdb52e878f389d79caacae33e b/fuzzer/corpus/21550a35b9b0025fdb52e878f389d79caacae33e
new file mode 100644
index 0000000..3d74546
--- /dev/null
+++ b/fuzzer/corpus/21550a35b9b0025fdb52e878f389d79caacae33e
Binary files differ
diff --git a/fuzzer/corpus/21684e5e2d68246e4e674db92544a31c778a63cf b/fuzzer/corpus/21684e5e2d68246e4e674db92544a31c778a63cf
new file mode 100644
index 0000000..9031908
--- /dev/null
+++ b/fuzzer/corpus/21684e5e2d68246e4e674db92544a31c778a63cf
Binary files differ
diff --git a/fuzzer/corpus/21716e33b4ee3ab55154b72e1cfa0e2145e3c561 b/fuzzer/corpus/21716e33b4ee3ab55154b72e1cfa0e2145e3c561
new file mode 100644
index 0000000..e849936
--- /dev/null
+++ b/fuzzer/corpus/21716e33b4ee3ab55154b72e1cfa0e2145e3c561
Binary files differ
diff --git a/fuzzer/corpus/220e94d92ff849bab5ce93b251e34a2377b503e1 b/fuzzer/corpus/220e94d92ff849bab5ce93b251e34a2377b503e1
new file mode 100644
index 0000000..214fc50
--- /dev/null
+++ b/fuzzer/corpus/220e94d92ff849bab5ce93b251e34a2377b503e1
Binary files differ
diff --git a/fuzzer/corpus/22319cd6f55d76f5bd2ad557d53c38a181185510 b/fuzzer/corpus/22319cd6f55d76f5bd2ad557d53c38a181185510
new file mode 100644
index 0000000..705c4f0
--- /dev/null
+++ b/fuzzer/corpus/22319cd6f55d76f5bd2ad557d53c38a181185510
Binary files differ
diff --git a/fuzzer/corpus/223edd321605b2a814a42ef7bcfddbdc7d6de6b1 b/fuzzer/corpus/223edd321605b2a814a42ef7bcfddbdc7d6de6b1
new file mode 100644
index 0000000..b40b88c
--- /dev/null
+++ b/fuzzer/corpus/223edd321605b2a814a42ef7bcfddbdc7d6de6b1
Binary files differ
diff --git a/fuzzer/corpus/22820aaac73f83bbd2e51a446677a68210cd2abe b/fuzzer/corpus/22820aaac73f83bbd2e51a446677a68210cd2abe
new file mode 100644
index 0000000..e16bbdb
--- /dev/null
+++ b/fuzzer/corpus/22820aaac73f83bbd2e51a446677a68210cd2abe
Binary files differ
diff --git a/fuzzer/corpus/22964ffcca595066641ec08ca797ba4fb61b2626 b/fuzzer/corpus/22964ffcca595066641ec08ca797ba4fb61b2626
new file mode 100644
index 0000000..d620253
--- /dev/null
+++ b/fuzzer/corpus/22964ffcca595066641ec08ca797ba4fb61b2626
Binary files differ
diff --git a/fuzzer/corpus/22ba06644742205b84c5edb64a828c6c2ff9fe53 b/fuzzer/corpus/22ba06644742205b84c5edb64a828c6c2ff9fe53
new file mode 100644
index 0000000..4cc87c6
--- /dev/null
+++ b/fuzzer/corpus/22ba06644742205b84c5edb64a828c6c2ff9fe53
Binary files differ
diff --git a/fuzzer/corpus/22cf9894602eda1a399027e2c36986aa5f37f541 b/fuzzer/corpus/22cf9894602eda1a399027e2c36986aa5f37f541
new file mode 100644
index 0000000..8f82b5a
--- /dev/null
+++ b/fuzzer/corpus/22cf9894602eda1a399027e2c36986aa5f37f541
Binary files differ
diff --git a/fuzzer/corpus/22d276898acc2ef6fe03f8e92d3970d8c5a9c0fa b/fuzzer/corpus/22d276898acc2ef6fe03f8e92d3970d8c5a9c0fa
new file mode 100644
index 0000000..201ada5
--- /dev/null
+++ b/fuzzer/corpus/22d276898acc2ef6fe03f8e92d3970d8c5a9c0fa
Binary files differ
diff --git a/fuzzer/corpus/22d88f38377f5a29624de95ad24187d0b7f2f822 b/fuzzer/corpus/22d88f38377f5a29624de95ad24187d0b7f2f822
new file mode 100644
index 0000000..2e540b6
--- /dev/null
+++ b/fuzzer/corpus/22d88f38377f5a29624de95ad24187d0b7f2f822
Binary files differ
diff --git a/fuzzer/corpus/22e706b61599b63012daf28576fbbf951c06fb2f b/fuzzer/corpus/22e706b61599b63012daf28576fbbf951c06fb2f
new file mode 100644
index 0000000..95d24ba
--- /dev/null
+++ b/fuzzer/corpus/22e706b61599b63012daf28576fbbf951c06fb2f
Binary files differ
diff --git a/fuzzer/corpus/22e8328ac63816abed85d1c30e12999cfbf0b2a9 b/fuzzer/corpus/22e8328ac63816abed85d1c30e12999cfbf0b2a9
new file mode 100644
index 0000000..10ba762
--- /dev/null
+++ b/fuzzer/corpus/22e8328ac63816abed85d1c30e12999cfbf0b2a9
Binary files differ
diff --git a/fuzzer/corpus/22eb4071735ba26425b0ed9e7e9ecd9c3b6b36ef b/fuzzer/corpus/22eb4071735ba26425b0ed9e7e9ecd9c3b6b36ef
new file mode 100644
index 0000000..f9b09e7
--- /dev/null
+++ b/fuzzer/corpus/22eb4071735ba26425b0ed9e7e9ecd9c3b6b36ef
Binary files differ
diff --git a/fuzzer/corpus/22f3d21f1de355398fb28e60af305eaa0d3def1c b/fuzzer/corpus/22f3d21f1de355398fb28e60af305eaa0d3def1c
new file mode 100644
index 0000000..c9d0c97
--- /dev/null
+++ b/fuzzer/corpus/22f3d21f1de355398fb28e60af305eaa0d3def1c
Binary files differ
diff --git a/fuzzer/corpus/2313e4928dde8c50a69f5e98c91dd82f62679354 b/fuzzer/corpus/2313e4928dde8c50a69f5e98c91dd82f62679354
new file mode 100644
index 0000000..2cf88bc
--- /dev/null
+++ b/fuzzer/corpus/2313e4928dde8c50a69f5e98c91dd82f62679354
Binary files differ
diff --git a/fuzzer/corpus/2348a7177c749a58c82c40db51fee5dcfc9b2bfd b/fuzzer/corpus/2348a7177c749a58c82c40db51fee5dcfc9b2bfd
new file mode 100644
index 0000000..a23a011
--- /dev/null
+++ b/fuzzer/corpus/2348a7177c749a58c82c40db51fee5dcfc9b2bfd
Binary files differ
diff --git a/fuzzer/corpus/239a453aa1df476a83b8b34480ba8a741f0bb6ac b/fuzzer/corpus/239a453aa1df476a83b8b34480ba8a741f0bb6ac
new file mode 100644
index 0000000..35bf58d
--- /dev/null
+++ b/fuzzer/corpus/239a453aa1df476a83b8b34480ba8a741f0bb6ac
Binary files differ
diff --git a/fuzzer/corpus/23af973f0a19010fe3e341052c6c6958ebc788d6 b/fuzzer/corpus/23af973f0a19010fe3e341052c6c6958ebc788d6
new file mode 100644
index 0000000..ffefad6
--- /dev/null
+++ b/fuzzer/corpus/23af973f0a19010fe3e341052c6c6958ebc788d6
Binary files differ
diff --git a/fuzzer/corpus/23b5ba1837a9e8033bbfae75a9f0035cdd3005b8 b/fuzzer/corpus/23b5ba1837a9e8033bbfae75a9f0035cdd3005b8
new file mode 100644
index 0000000..f73d2a6
--- /dev/null
+++ b/fuzzer/corpus/23b5ba1837a9e8033bbfae75a9f0035cdd3005b8
Binary files differ
diff --git a/fuzzer/corpus/23bf4e0b5d758f920fd11106e5543639bbf865e4 b/fuzzer/corpus/23bf4e0b5d758f920fd11106e5543639bbf865e4
new file mode 100644
index 0000000..c3f070e
--- /dev/null
+++ b/fuzzer/corpus/23bf4e0b5d758f920fd11106e5543639bbf865e4
Binary files differ
diff --git a/fuzzer/corpus/23d7f6cf0e85ea06af8b3914c8dd2ff41bb38b24 b/fuzzer/corpus/23d7f6cf0e85ea06af8b3914c8dd2ff41bb38b24
new file mode 100644
index 0000000..c49c2fa
--- /dev/null
+++ b/fuzzer/corpus/23d7f6cf0e85ea06af8b3914c8dd2ff41bb38b24
Binary files differ
diff --git a/fuzzer/corpus/23eb335737546cbcfbb12d0bad97af4abc31d4a4 b/fuzzer/corpus/23eb335737546cbcfbb12d0bad97af4abc31d4a4
new file mode 100644
index 0000000..85eda2a
--- /dev/null
+++ b/fuzzer/corpus/23eb335737546cbcfbb12d0bad97af4abc31d4a4
Binary files differ
diff --git a/fuzzer/corpus/23f0dc1a2d2e9531bdf2b50b8e3f4cc6564ff11f b/fuzzer/corpus/23f0dc1a2d2e9531bdf2b50b8e3f4cc6564ff11f
new file mode 100644
index 0000000..c1108d7
--- /dev/null
+++ b/fuzzer/corpus/23f0dc1a2d2e9531bdf2b50b8e3f4cc6564ff11f
Binary files differ
diff --git a/fuzzer/corpus/24066e9de96bd46630d07606ac12b8acc3a5a050 b/fuzzer/corpus/24066e9de96bd46630d07606ac12b8acc3a5a050
new file mode 100644
index 0000000..28a1a10
--- /dev/null
+++ b/fuzzer/corpus/24066e9de96bd46630d07606ac12b8acc3a5a050
Binary files differ
diff --git a/fuzzer/corpus/241be221f09d0a69e929da58cc1198dc7f7d8446 b/fuzzer/corpus/241be221f09d0a69e929da58cc1198dc7f7d8446
new file mode 100644
index 0000000..f5732fb
--- /dev/null
+++ b/fuzzer/corpus/241be221f09d0a69e929da58cc1198dc7f7d8446
Binary files differ
diff --git a/fuzzer/corpus/2423e0cee389b740112a04a935a28b5da664dc66 b/fuzzer/corpus/2423e0cee389b740112a04a935a28b5da664dc66
new file mode 100644
index 0000000..ad2e175
--- /dev/null
+++ b/fuzzer/corpus/2423e0cee389b740112a04a935a28b5da664dc66
Binary files differ
diff --git a/fuzzer/corpus/244fa9f5c80e78a3b3b2b2f4259dfc838abd803f b/fuzzer/corpus/244fa9f5c80e78a3b3b2b2f4259dfc838abd803f
new file mode 100644
index 0000000..1b36f20
--- /dev/null
+++ b/fuzzer/corpus/244fa9f5c80e78a3b3b2b2f4259dfc838abd803f
Binary files differ
diff --git a/fuzzer/corpus/246698c04d8849dc19e8a103928a53f5006a044f b/fuzzer/corpus/246698c04d8849dc19e8a103928a53f5006a044f
new file mode 100644
index 0000000..09cafb3
--- /dev/null
+++ b/fuzzer/corpus/246698c04d8849dc19e8a103928a53f5006a044f
Binary files differ
diff --git a/fuzzer/corpus/246daf04584b1b3a3b3069215f2e3b386eed7630 b/fuzzer/corpus/246daf04584b1b3a3b3069215f2e3b386eed7630
new file mode 100644
index 0000000..86c44b4
--- /dev/null
+++ b/fuzzer/corpus/246daf04584b1b3a3b3069215f2e3b386eed7630
Binary files differ
diff --git a/fuzzer/corpus/247c682f37063541eebd05e45f8b590f0d2d8442 b/fuzzer/corpus/247c682f37063541eebd05e45f8b590f0d2d8442
new file mode 100644
index 0000000..8ffc022
--- /dev/null
+++ b/fuzzer/corpus/247c682f37063541eebd05e45f8b590f0d2d8442
Binary files differ
diff --git a/fuzzer/corpus/2485ab2cdd6337d7e3157ed5a4780dd7630464fa b/fuzzer/corpus/2485ab2cdd6337d7e3157ed5a4780dd7630464fa
new file mode 100644
index 0000000..384f566
--- /dev/null
+++ b/fuzzer/corpus/2485ab2cdd6337d7e3157ed5a4780dd7630464fa
Binary files differ
diff --git a/fuzzer/corpus/24e5e89131727595bba3ad7abd10a735f0791683 b/fuzzer/corpus/24e5e89131727595bba3ad7abd10a735f0791683
new file mode 100644
index 0000000..891ad78
--- /dev/null
+++ b/fuzzer/corpus/24e5e89131727595bba3ad7abd10a735f0791683
Binary files differ
diff --git a/fuzzer/corpus/25055f92a8aaaa223150ab4eda6754ead23fec6f b/fuzzer/corpus/25055f92a8aaaa223150ab4eda6754ead23fec6f
new file mode 100644
index 0000000..d013c4a
--- /dev/null
+++ b/fuzzer/corpus/25055f92a8aaaa223150ab4eda6754ead23fec6f
Binary files differ
diff --git a/fuzzer/corpus/25297ce21678042b03d55b3162326f3409903ee9 b/fuzzer/corpus/25297ce21678042b03d55b3162326f3409903ee9
new file mode 100644
index 0000000..c981c24
--- /dev/null
+++ b/fuzzer/corpus/25297ce21678042b03d55b3162326f3409903ee9
Binary files differ
diff --git a/fuzzer/corpus/2596b607e7f3e2c35331a6bae16ccbf436d8eb9d b/fuzzer/corpus/2596b607e7f3e2c35331a6bae16ccbf436d8eb9d
new file mode 100644
index 0000000..e3026b0
--- /dev/null
+++ b/fuzzer/corpus/2596b607e7f3e2c35331a6bae16ccbf436d8eb9d
Binary files differ
diff --git a/fuzzer/corpus/259c4e5e079300b8b3a059c4ea5a9c3e8a6f5513 b/fuzzer/corpus/259c4e5e079300b8b3a059c4ea5a9c3e8a6f5513
new file mode 100644
index 0000000..2492351
--- /dev/null
+++ b/fuzzer/corpus/259c4e5e079300b8b3a059c4ea5a9c3e8a6f5513
Binary files differ
diff --git a/fuzzer/corpus/25b0c0b4ae8dbca7e3455401be9f534e0afd8717 b/fuzzer/corpus/25b0c0b4ae8dbca7e3455401be9f534e0afd8717
new file mode 100644
index 0000000..3605e01
--- /dev/null
+++ b/fuzzer/corpus/25b0c0b4ae8dbca7e3455401be9f534e0afd8717
Binary files differ
diff --git a/fuzzer/corpus/25c3d2aafdaf53d5cfe45a36bf927c58f7986a69 b/fuzzer/corpus/25c3d2aafdaf53d5cfe45a36bf927c58f7986a69
new file mode 100644
index 0000000..ef56a4b
--- /dev/null
+++ b/fuzzer/corpus/25c3d2aafdaf53d5cfe45a36bf927c58f7986a69
Binary files differ
diff --git a/fuzzer/corpus/25c5862d2d7fc0ae1fe4704613b9f6e0ac8d1b0e b/fuzzer/corpus/25c5862d2d7fc0ae1fe4704613b9f6e0ac8d1b0e
new file mode 100644
index 0000000..a49146a
--- /dev/null
+++ b/fuzzer/corpus/25c5862d2d7fc0ae1fe4704613b9f6e0ac8d1b0e
Binary files differ
diff --git a/fuzzer/corpus/25cb6d57cfe58d83ef4bcc4d5327f185d5c50971 b/fuzzer/corpus/25cb6d57cfe58d83ef4bcc4d5327f185d5c50971
new file mode 100644
index 0000000..54afac8
--- /dev/null
+++ b/fuzzer/corpus/25cb6d57cfe58d83ef4bcc4d5327f185d5c50971
Binary files differ
diff --git a/fuzzer/corpus/25f63d41f5aa30bea23374d2f98bd2fb5bc6e330 b/fuzzer/corpus/25f63d41f5aa30bea23374d2f98bd2fb5bc6e330
new file mode 100644
index 0000000..3b4962b
--- /dev/null
+++ b/fuzzer/corpus/25f63d41f5aa30bea23374d2f98bd2fb5bc6e330
Binary files differ
diff --git a/fuzzer/corpus/25f71c075445f2ca32f378d9b73a99043fb7299c b/fuzzer/corpus/25f71c075445f2ca32f378d9b73a99043fb7299c
new file mode 100644
index 0000000..4ff9e58
--- /dev/null
+++ b/fuzzer/corpus/25f71c075445f2ca32f378d9b73a99043fb7299c
Binary files differ
diff --git a/fuzzer/corpus/261abd3920c9848bb7e27d132f56396ac71e81eb b/fuzzer/corpus/261abd3920c9848bb7e27d132f56396ac71e81eb
new file mode 100644
index 0000000..f1fff3c
--- /dev/null
+++ b/fuzzer/corpus/261abd3920c9848bb7e27d132f56396ac71e81eb
Binary files differ
diff --git a/fuzzer/corpus/266d4d8456fbe6e9492ef131edc18f08e92ad969 b/fuzzer/corpus/266d4d8456fbe6e9492ef131edc18f08e92ad969
new file mode 100644
index 0000000..2f053d2
--- /dev/null
+++ b/fuzzer/corpus/266d4d8456fbe6e9492ef131edc18f08e92ad969
Binary files differ
diff --git a/fuzzer/corpus/26bd241443c6ca63fb02587e96e7f56821f616be b/fuzzer/corpus/26bd241443c6ca63fb02587e96e7f56821f616be
new file mode 100644
index 0000000..af4e797
--- /dev/null
+++ b/fuzzer/corpus/26bd241443c6ca63fb02587e96e7f56821f616be
Binary files differ
diff --git a/fuzzer/corpus/26e5d99c26ce43fc432883c50ff75fcdd8f0e9ab b/fuzzer/corpus/26e5d99c26ce43fc432883c50ff75fcdd8f0e9ab
new file mode 100644
index 0000000..898fcc9
--- /dev/null
+++ b/fuzzer/corpus/26e5d99c26ce43fc432883c50ff75fcdd8f0e9ab
Binary files differ
diff --git a/fuzzer/corpus/276c148ce886ab053d55dc7a45b1ba2089608488 b/fuzzer/corpus/276c148ce886ab053d55dc7a45b1ba2089608488
new file mode 100644
index 0000000..bd67196
--- /dev/null
+++ b/fuzzer/corpus/276c148ce886ab053d55dc7a45b1ba2089608488
Binary files differ
diff --git a/fuzzer/corpus/276cd356df9685144bc41ed78d813e6421fd96a4 b/fuzzer/corpus/276cd356df9685144bc41ed78d813e6421fd96a4
new file mode 100644
index 0000000..b25a04a
--- /dev/null
+++ b/fuzzer/corpus/276cd356df9685144bc41ed78d813e6421fd96a4
Binary files differ
diff --git a/fuzzer/corpus/278880f708e854f9b7669ae76dfa4221f98ee9cb b/fuzzer/corpus/278880f708e854f9b7669ae76dfa4221f98ee9cb
new file mode 100644
index 0000000..c985111
--- /dev/null
+++ b/fuzzer/corpus/278880f708e854f9b7669ae76dfa4221f98ee9cb
Binary files differ
diff --git a/fuzzer/corpus/27b247b75feab9765414a16e7e94de7bbf7397c3 b/fuzzer/corpus/27b247b75feab9765414a16e7e94de7bbf7397c3
new file mode 100644
index 0000000..03f0138
--- /dev/null
+++ b/fuzzer/corpus/27b247b75feab9765414a16e7e94de7bbf7397c3
Binary files differ
diff --git a/fuzzer/corpus/27e9eb505ac8401904ee7ff4d9a34eb3f873afe5 b/fuzzer/corpus/27e9eb505ac8401904ee7ff4d9a34eb3f873afe5
new file mode 100644
index 0000000..0ce0832
--- /dev/null
+++ b/fuzzer/corpus/27e9eb505ac8401904ee7ff4d9a34eb3f873afe5
Binary files differ
diff --git a/fuzzer/corpus/2812717d79d66037931c0d8b3092a892842ddaa7 b/fuzzer/corpus/2812717d79d66037931c0d8b3092a892842ddaa7
new file mode 100644
index 0000000..d6aa34f
--- /dev/null
+++ b/fuzzer/corpus/2812717d79d66037931c0d8b3092a892842ddaa7
Binary files differ
diff --git a/fuzzer/corpus/28485ae79b2ff5ca3dbd31e514a0ced95e8045ff b/fuzzer/corpus/28485ae79b2ff5ca3dbd31e514a0ced95e8045ff
new file mode 100644
index 0000000..bb4987e
--- /dev/null
+++ b/fuzzer/corpus/28485ae79b2ff5ca3dbd31e514a0ced95e8045ff
Binary files differ
diff --git a/fuzzer/corpus/284f3000a725d125cf1d65db2d15cc2d92860f14 b/fuzzer/corpus/284f3000a725d125cf1d65db2d15cc2d92860f14
new file mode 100644
index 0000000..9385ee7
--- /dev/null
+++ b/fuzzer/corpus/284f3000a725d125cf1d65db2d15cc2d92860f14
Binary files differ
diff --git a/fuzzer/corpus/285ccc5acf8c016da64fd33ed910c2320d385050 b/fuzzer/corpus/285ccc5acf8c016da64fd33ed910c2320d385050
new file mode 100644
index 0000000..e36273c
--- /dev/null
+++ b/fuzzer/corpus/285ccc5acf8c016da64fd33ed910c2320d385050
Binary files differ
diff --git a/fuzzer/corpus/2870bb659278b0907ea62fd38dd1fff5df58069c b/fuzzer/corpus/2870bb659278b0907ea62fd38dd1fff5df58069c
new file mode 100644
index 0000000..3101862
--- /dev/null
+++ b/fuzzer/corpus/2870bb659278b0907ea62fd38dd1fff5df58069c
Binary files differ
diff --git a/fuzzer/corpus/287934ac53e229708f5caa467cf905ae6dcfff76 b/fuzzer/corpus/287934ac53e229708f5caa467cf905ae6dcfff76
new file mode 100644
index 0000000..7abc5a7
--- /dev/null
+++ b/fuzzer/corpus/287934ac53e229708f5caa467cf905ae6dcfff76
Binary files differ
diff --git a/fuzzer/corpus/288011eea6ae35fe9017fada0d235a66120adb35 b/fuzzer/corpus/288011eea6ae35fe9017fada0d235a66120adb35
new file mode 100644
index 0000000..be22d18
--- /dev/null
+++ b/fuzzer/corpus/288011eea6ae35fe9017fada0d235a66120adb35
Binary files differ
diff --git a/fuzzer/corpus/28a6865768a7b43ec593b1d8ee4933c78e0562e9 b/fuzzer/corpus/28a6865768a7b43ec593b1d8ee4933c78e0562e9
new file mode 100644
index 0000000..475a8fa
--- /dev/null
+++ b/fuzzer/corpus/28a6865768a7b43ec593b1d8ee4933c78e0562e9
Binary files differ
diff --git a/fuzzer/corpus/28aa8de4a01317db99d4baf57e41f582424e9a90 b/fuzzer/corpus/28aa8de4a01317db99d4baf57e41f582424e9a90
new file mode 100644
index 0000000..90cadc3
--- /dev/null
+++ b/fuzzer/corpus/28aa8de4a01317db99d4baf57e41f582424e9a90
Binary files differ
diff --git a/fuzzer/corpus/28b080f54b1d4323e2bcb2d4d64dbe68c74bf840 b/fuzzer/corpus/28b080f54b1d4323e2bcb2d4d64dbe68c74bf840
new file mode 100644
index 0000000..7c92d94
--- /dev/null
+++ b/fuzzer/corpus/28b080f54b1d4323e2bcb2d4d64dbe68c74bf840
Binary files differ
diff --git a/fuzzer/corpus/28b4b75d0fba962051d25e9ca6db1a2c870e39da b/fuzzer/corpus/28b4b75d0fba962051d25e9ca6db1a2c870e39da
new file mode 100644
index 0000000..bcbf3a5
--- /dev/null
+++ b/fuzzer/corpus/28b4b75d0fba962051d25e9ca6db1a2c870e39da
Binary files differ
diff --git a/fuzzer/corpus/28c304f04cc35c1d67d97210fc65fa99c6b0c3ac b/fuzzer/corpus/28c304f04cc35c1d67d97210fc65fa99c6b0c3ac
new file mode 100644
index 0000000..d3f3a43
--- /dev/null
+++ b/fuzzer/corpus/28c304f04cc35c1d67d97210fc65fa99c6b0c3ac
Binary files differ
diff --git a/fuzzer/corpus/28d63e980c334119aefe2ea928b3e4bab4834ec1 b/fuzzer/corpus/28d63e980c334119aefe2ea928b3e4bab4834ec1
new file mode 100644
index 0000000..5d8686f
--- /dev/null
+++ b/fuzzer/corpus/28d63e980c334119aefe2ea928b3e4bab4834ec1
Binary files differ
diff --git a/fuzzer/corpus/291e958f82465146816cfe86d7964796893911a3 b/fuzzer/corpus/291e958f82465146816cfe86d7964796893911a3
new file mode 100644
index 0000000..15b79b4
--- /dev/null
+++ b/fuzzer/corpus/291e958f82465146816cfe86d7964796893911a3
Binary files differ
diff --git a/fuzzer/corpus/296f1aaf63c1ed2099da363e718be68a2d67f1d1 b/fuzzer/corpus/296f1aaf63c1ed2099da363e718be68a2d67f1d1
new file mode 100644
index 0000000..6238c8c
--- /dev/null
+++ b/fuzzer/corpus/296f1aaf63c1ed2099da363e718be68a2d67f1d1
Binary files differ
diff --git a/fuzzer/corpus/29704b3d9b9c0645c1320d852ab1beea871a1ca3 b/fuzzer/corpus/29704b3d9b9c0645c1320d852ab1beea871a1ca3
new file mode 100644
index 0000000..99b7610
--- /dev/null
+++ b/fuzzer/corpus/29704b3d9b9c0645c1320d852ab1beea871a1ca3
Binary files differ
diff --git a/fuzzer/corpus/2985d508c0f8f374504ddfc6786eb21934aae32b b/fuzzer/corpus/2985d508c0f8f374504ddfc6786eb21934aae32b
new file mode 100644
index 0000000..bd8ecdf
--- /dev/null
+++ b/fuzzer/corpus/2985d508c0f8f374504ddfc6786eb21934aae32b
Binary files differ
diff --git a/fuzzer/corpus/298f69b74788cf92817b9f2395f5383a18b148d1 b/fuzzer/corpus/298f69b74788cf92817b9f2395f5383a18b148d1
new file mode 100644
index 0000000..6d6c7a7
--- /dev/null
+++ b/fuzzer/corpus/298f69b74788cf92817b9f2395f5383a18b148d1
@@ -0,0 +1 @@
+se__ü
\ No newline at end of file
diff --git a/fuzzer/corpus/299218026c0e3f24bb8f7ee7a3e5bbab4013a438 b/fuzzer/corpus/299218026c0e3f24bb8f7ee7a3e5bbab4013a438
new file mode 100644
index 0000000..53315cf
--- /dev/null
+++ b/fuzzer/corpus/299218026c0e3f24bb8f7ee7a3e5bbab4013a438
Binary files differ
diff --git a/fuzzer/corpus/2998e292991fc5c2abd7dfccb2f497b6f2aca0bd b/fuzzer/corpus/2998e292991fc5c2abd7dfccb2f497b6f2aca0bd
new file mode 100644
index 0000000..1b56225
--- /dev/null
+++ b/fuzzer/corpus/2998e292991fc5c2abd7dfccb2f497b6f2aca0bd
Binary files differ
diff --git a/fuzzer/corpus/29a13021ac5be7f0923f25b1fffc37a5d33e1cbf b/fuzzer/corpus/29a13021ac5be7f0923f25b1fffc37a5d33e1cbf
new file mode 100644
index 0000000..f70430a
--- /dev/null
+++ b/fuzzer/corpus/29a13021ac5be7f0923f25b1fffc37a5d33e1cbf
Binary files differ
diff --git a/fuzzer/corpus/29a62d158c6ba4f9736219bffcb7d103019406cb b/fuzzer/corpus/29a62d158c6ba4f9736219bffcb7d103019406cb
new file mode 100644
index 0000000..b24eaa0
--- /dev/null
+++ b/fuzzer/corpus/29a62d158c6ba4f9736219bffcb7d103019406cb
Binary files differ
diff --git a/fuzzer/corpus/29c9b1c37e16b9fab789366a57efaea4b694a3da b/fuzzer/corpus/29c9b1c37e16b9fab789366a57efaea4b694a3da
new file mode 100644
index 0000000..ae283cd
--- /dev/null
+++ b/fuzzer/corpus/29c9b1c37e16b9fab789366a57efaea4b694a3da
Binary files differ
diff --git a/fuzzer/corpus/29fd5570888006939e71a86bbc0201742783adca b/fuzzer/corpus/29fd5570888006939e71a86bbc0201742783adca
new file mode 100644
index 0000000..18e7576
--- /dev/null
+++ b/fuzzer/corpus/29fd5570888006939e71a86bbc0201742783adca
Binary files differ
diff --git a/fuzzer/corpus/2a0979e8d583541d1437ff3f6f10334606a24588 b/fuzzer/corpus/2a0979e8d583541d1437ff3f6f10334606a24588
new file mode 100644
index 0000000..dbb627f
--- /dev/null
+++ b/fuzzer/corpus/2a0979e8d583541d1437ff3f6f10334606a24588
Binary files differ
diff --git a/fuzzer/corpus/2a57659db0b59c22251257abc75e07f3ad71b746 b/fuzzer/corpus/2a57659db0b59c22251257abc75e07f3ad71b746
new file mode 100644
index 0000000..6aa1e66
--- /dev/null
+++ b/fuzzer/corpus/2a57659db0b59c22251257abc75e07f3ad71b746
Binary files differ
diff --git a/fuzzer/corpus/2a9137d8bbd841e49c09cf835c3725f44465fa6a b/fuzzer/corpus/2a9137d8bbd841e49c09cf835c3725f44465fa6a
new file mode 100644
index 0000000..f7fdba6
--- /dev/null
+++ b/fuzzer/corpus/2a9137d8bbd841e49c09cf835c3725f44465fa6a
Binary files differ
diff --git a/fuzzer/corpus/2aa08ae64041b0afe24a0722f9b9053ed2a5cdc0 b/fuzzer/corpus/2aa08ae64041b0afe24a0722f9b9053ed2a5cdc0
new file mode 100644
index 0000000..a4e7025
--- /dev/null
+++ b/fuzzer/corpus/2aa08ae64041b0afe24a0722f9b9053ed2a5cdc0
Binary files differ
diff --git a/fuzzer/corpus/2acb3dfc6d7857429d3a277ae413af55afefdee9 b/fuzzer/corpus/2acb3dfc6d7857429d3a277ae413af55afefdee9
new file mode 100644
index 0000000..906619f
--- /dev/null
+++ b/fuzzer/corpus/2acb3dfc6d7857429d3a277ae413af55afefdee9
Binary files differ
diff --git a/fuzzer/corpus/2af0dab1f33551f7022e6da7af7970cf73c2a2b1 b/fuzzer/corpus/2af0dab1f33551f7022e6da7af7970cf73c2a2b1
new file mode 100644
index 0000000..60d107a
--- /dev/null
+++ b/fuzzer/corpus/2af0dab1f33551f7022e6da7af7970cf73c2a2b1
Binary files differ
diff --git a/fuzzer/corpus/2af1c5d0d5347c8d540f726d402816153ccc9981 b/fuzzer/corpus/2af1c5d0d5347c8d540f726d402816153ccc9981
new file mode 100644
index 0000000..9d87e6c
--- /dev/null
+++ b/fuzzer/corpus/2af1c5d0d5347c8d540f726d402816153ccc9981
Binary files differ
diff --git a/fuzzer/corpus/2b0eeaba194b803783b311c0ad77403162c39d51 b/fuzzer/corpus/2b0eeaba194b803783b311c0ad77403162c39d51
new file mode 100644
index 0000000..6240a71
--- /dev/null
+++ b/fuzzer/corpus/2b0eeaba194b803783b311c0ad77403162c39d51
Binary files differ
diff --git a/fuzzer/corpus/2b3444a8e868a2d2264a075e9dea23c42db723be b/fuzzer/corpus/2b3444a8e868a2d2264a075e9dea23c42db723be
new file mode 100644
index 0000000..0701405
--- /dev/null
+++ b/fuzzer/corpus/2b3444a8e868a2d2264a075e9dea23c42db723be
Binary files differ
diff --git a/fuzzer/corpus/2b703c0e974c7eed7640d4abc70f40d935591a33 b/fuzzer/corpus/2b703c0e974c7eed7640d4abc70f40d935591a33
new file mode 100644
index 0000000..2345257
--- /dev/null
+++ b/fuzzer/corpus/2b703c0e974c7eed7640d4abc70f40d935591a33
Binary files differ
diff --git a/fuzzer/corpus/2ba839bf04327768140748b8bfcccf9c72100ebf b/fuzzer/corpus/2ba839bf04327768140748b8bfcccf9c72100ebf
new file mode 100644
index 0000000..960db90
--- /dev/null
+++ b/fuzzer/corpus/2ba839bf04327768140748b8bfcccf9c72100ebf
Binary files differ
diff --git a/fuzzer/corpus/2bb298d1f0223998820582ec7b67fbfd0f6040c6 b/fuzzer/corpus/2bb298d1f0223998820582ec7b67fbfd0f6040c6
new file mode 100644
index 0000000..0b2d495
--- /dev/null
+++ b/fuzzer/corpus/2bb298d1f0223998820582ec7b67fbfd0f6040c6
Binary files differ
diff --git a/fuzzer/corpus/2bb3697dc1c419b5e940eb5acf2951f49006fad4 b/fuzzer/corpus/2bb3697dc1c419b5e940eb5acf2951f49006fad4
new file mode 100644
index 0000000..85f7874
--- /dev/null
+++ b/fuzzer/corpus/2bb3697dc1c419b5e940eb5acf2951f49006fad4
Binary files differ
diff --git a/fuzzer/corpus/2be7c75fa6ef71a1d75907e4c68dbdc8b9c98501 b/fuzzer/corpus/2be7c75fa6ef71a1d75907e4c68dbdc8b9c98501
new file mode 100644
index 0000000..c687e1c
--- /dev/null
+++ b/fuzzer/corpus/2be7c75fa6ef71a1d75907e4c68dbdc8b9c98501
Binary files differ
diff --git a/fuzzer/corpus/2bee35c47df46ea0217d0c6011ad24e8fca4e124 b/fuzzer/corpus/2bee35c47df46ea0217d0c6011ad24e8fca4e124
new file mode 100644
index 0000000..b0366a7
--- /dev/null
+++ b/fuzzer/corpus/2bee35c47df46ea0217d0c6011ad24e8fca4e124
Binary files differ
diff --git a/fuzzer/corpus/2c118bf269688e7562987e20964d5861de9bb517 b/fuzzer/corpus/2c118bf269688e7562987e20964d5861de9bb517
new file mode 100644
index 0000000..8e0eea5
--- /dev/null
+++ b/fuzzer/corpus/2c118bf269688e7562987e20964d5861de9bb517
Binary files differ
diff --git a/fuzzer/corpus/2c22aa93fd640cfa4ed55e48f93af608f978691b b/fuzzer/corpus/2c22aa93fd640cfa4ed55e48f93af608f978691b
new file mode 100644
index 0000000..3f7212d
--- /dev/null
+++ b/fuzzer/corpus/2c22aa93fd640cfa4ed55e48f93af608f978691b
Binary files differ
diff --git a/fuzzer/corpus/2c2a4bcd3ca4db18b35c8608a74a4b02c2476c27 b/fuzzer/corpus/2c2a4bcd3ca4db18b35c8608a74a4b02c2476c27
new file mode 100644
index 0000000..184b8e3
--- /dev/null
+++ b/fuzzer/corpus/2c2a4bcd3ca4db18b35c8608a74a4b02c2476c27
Binary files differ
diff --git a/fuzzer/corpus/2ca5b5ea23724a9aae48dcf587bbdb93f5647bd8 b/fuzzer/corpus/2ca5b5ea23724a9aae48dcf587bbdb93f5647bd8
new file mode 100644
index 0000000..06dcd39
--- /dev/null
+++ b/fuzzer/corpus/2ca5b5ea23724a9aae48dcf587bbdb93f5647bd8
Binary files differ
diff --git a/fuzzer/corpus/2ca79063c49122e0f47e397c3d9e79c993d666c7 b/fuzzer/corpus/2ca79063c49122e0f47e397c3d9e79c993d666c7
new file mode 100644
index 0000000..d11d4fc
--- /dev/null
+++ b/fuzzer/corpus/2ca79063c49122e0f47e397c3d9e79c993d666c7
Binary files differ
diff --git a/fuzzer/corpus/2ced2f6093d5e4331730cbf9d88d766229f9cd3b b/fuzzer/corpus/2ced2f6093d5e4331730cbf9d88d766229f9cd3b
new file mode 100644
index 0000000..28cd7fe
--- /dev/null
+++ b/fuzzer/corpus/2ced2f6093d5e4331730cbf9d88d766229f9cd3b
Binary files differ
diff --git a/fuzzer/corpus/2d1a23f3862d9280ff671fba2070923ad6e1947a b/fuzzer/corpus/2d1a23f3862d9280ff671fba2070923ad6e1947a
new file mode 100644
index 0000000..2cf8deb
--- /dev/null
+++ b/fuzzer/corpus/2d1a23f3862d9280ff671fba2070923ad6e1947a
Binary files differ
diff --git a/fuzzer/corpus/2d4242afa49b93a6225225692ca154c3e45724d5 b/fuzzer/corpus/2d4242afa49b93a6225225692ca154c3e45724d5
new file mode 100644
index 0000000..27a1ea3
--- /dev/null
+++ b/fuzzer/corpus/2d4242afa49b93a6225225692ca154c3e45724d5
Binary files differ
diff --git a/fuzzer/corpus/2d581bb7c0a36182032532922f7e5699793337ca b/fuzzer/corpus/2d581bb7c0a36182032532922f7e5699793337ca
new file mode 100644
index 0000000..7d38031
--- /dev/null
+++ b/fuzzer/corpus/2d581bb7c0a36182032532922f7e5699793337ca
Binary files differ
diff --git a/fuzzer/corpus/2d66ac9504561c6a0f844138e2b4d52418c67f80 b/fuzzer/corpus/2d66ac9504561c6a0f844138e2b4d52418c67f80
new file mode 100644
index 0000000..3c3d8dc
--- /dev/null
+++ b/fuzzer/corpus/2d66ac9504561c6a0f844138e2b4d52418c67f80
Binary files differ
diff --git a/fuzzer/corpus/2d71aaa244448b9f4cc5d055953855d0d85fae3f b/fuzzer/corpus/2d71aaa244448b9f4cc5d055953855d0d85fae3f
new file mode 100644
index 0000000..fca6785
--- /dev/null
+++ b/fuzzer/corpus/2d71aaa244448b9f4cc5d055953855d0d85fae3f
Binary files differ
diff --git a/fuzzer/corpus/2d843e83cfefd6a8a7ba872d4062f974239cafee b/fuzzer/corpus/2d843e83cfefd6a8a7ba872d4062f974239cafee
new file mode 100644
index 0000000..df9c4dc
--- /dev/null
+++ b/fuzzer/corpus/2d843e83cfefd6a8a7ba872d4062f974239cafee
Binary files differ
diff --git a/fuzzer/corpus/2da6fe9966c981144a9dd5d39e5bfc7f300476ed b/fuzzer/corpus/2da6fe9966c981144a9dd5d39e5bfc7f300476ed
new file mode 100644
index 0000000..b77d4ed
--- /dev/null
+++ b/fuzzer/corpus/2da6fe9966c981144a9dd5d39e5bfc7f300476ed
Binary files differ
diff --git a/fuzzer/corpus/2dae7e025ff6cdb13331958ec792bcc85e00f2e5 b/fuzzer/corpus/2dae7e025ff6cdb13331958ec792bcc85e00f2e5
new file mode 100644
index 0000000..add569b
--- /dev/null
+++ b/fuzzer/corpus/2dae7e025ff6cdb13331958ec792bcc85e00f2e5
Binary files differ
diff --git a/fuzzer/corpus/2db9dc6a54e6a1129d9092eb324401741b9d24eb b/fuzzer/corpus/2db9dc6a54e6a1129d9092eb324401741b9d24eb
new file mode 100644
index 0000000..382d4f3
--- /dev/null
+++ b/fuzzer/corpus/2db9dc6a54e6a1129d9092eb324401741b9d24eb
Binary files differ
diff --git a/fuzzer/corpus/2dc75a74bf59fd36e1d17f4eab639b4118365114 b/fuzzer/corpus/2dc75a74bf59fd36e1d17f4eab639b4118365114
new file mode 100644
index 0000000..102a603
--- /dev/null
+++ b/fuzzer/corpus/2dc75a74bf59fd36e1d17f4eab639b4118365114
Binary files differ
diff --git a/fuzzer/corpus/2de31f9b6d02c301449a79e5384b485d9d225223 b/fuzzer/corpus/2de31f9b6d02c301449a79e5384b485d9d225223
new file mode 100644
index 0000000..b6988be
--- /dev/null
+++ b/fuzzer/corpus/2de31f9b6d02c301449a79e5384b485d9d225223
Binary files differ
diff --git a/fuzzer/corpus/2e32dee727385859cb50fd99e8f5352c8016c2c5 b/fuzzer/corpus/2e32dee727385859cb50fd99e8f5352c8016c2c5
new file mode 100644
index 0000000..81f4947
--- /dev/null
+++ b/fuzzer/corpus/2e32dee727385859cb50fd99e8f5352c8016c2c5
Binary files differ
diff --git a/fuzzer/corpus/2e4dd57095e0aab0b275de64702c69a40db96c50 b/fuzzer/corpus/2e4dd57095e0aab0b275de64702c69a40db96c50
new file mode 100644
index 0000000..5269f7e
--- /dev/null
+++ b/fuzzer/corpus/2e4dd57095e0aab0b275de64702c69a40db96c50
Binary files differ
diff --git a/fuzzer/corpus/2e50d0db4befbd9dcc3fbc8d1cf208e6cc2033ac b/fuzzer/corpus/2e50d0db4befbd9dcc3fbc8d1cf208e6cc2033ac
new file mode 100644
index 0000000..9cac4bf
--- /dev/null
+++ b/fuzzer/corpus/2e50d0db4befbd9dcc3fbc8d1cf208e6cc2033ac
Binary files differ
diff --git a/fuzzer/corpus/2e5e64528591a41347878d9925d1fd241aaa4139 b/fuzzer/corpus/2e5e64528591a41347878d9925d1fd241aaa4139
new file mode 100644
index 0000000..5e6abd2
--- /dev/null
+++ b/fuzzer/corpus/2e5e64528591a41347878d9925d1fd241aaa4139
Binary files differ
diff --git a/fuzzer/corpus/2e6088c241d4a37f5a95f5b9d6065c60e44900ee b/fuzzer/corpus/2e6088c241d4a37f5a95f5b9d6065c60e44900ee
new file mode 100644
index 0000000..5079990
--- /dev/null
+++ b/fuzzer/corpus/2e6088c241d4a37f5a95f5b9d6065c60e44900ee
Binary files differ
diff --git a/fuzzer/corpus/2e750f93090aee0bd4f31bfc34e39f500de73443 b/fuzzer/corpus/2e750f93090aee0bd4f31bfc34e39f500de73443
new file mode 100644
index 0000000..0f2054e
--- /dev/null
+++ b/fuzzer/corpus/2e750f93090aee0bd4f31bfc34e39f500de73443
Binary files differ
diff --git a/fuzzer/corpus/2ea26a0c95bb875c408aa17e0f53b7c88c2b27fe b/fuzzer/corpus/2ea26a0c95bb875c408aa17e0f53b7c88c2b27fe
new file mode 100644
index 0000000..abdbfb6
--- /dev/null
+++ b/fuzzer/corpus/2ea26a0c95bb875c408aa17e0f53b7c88c2b27fe
Binary files differ
diff --git a/fuzzer/corpus/2ed032b963bb50e8a84a8820339b445392d08d46 b/fuzzer/corpus/2ed032b963bb50e8a84a8820339b445392d08d46
new file mode 100644
index 0000000..d97d131
--- /dev/null
+++ b/fuzzer/corpus/2ed032b963bb50e8a84a8820339b445392d08d46
Binary files differ
diff --git a/fuzzer/corpus/2ed038f5938825b41af5e044b4a49d176ed1f49f b/fuzzer/corpus/2ed038f5938825b41af5e044b4a49d176ed1f49f
new file mode 100644
index 0000000..ef718ae
--- /dev/null
+++ b/fuzzer/corpus/2ed038f5938825b41af5e044b4a49d176ed1f49f
Binary files differ
diff --git a/fuzzer/corpus/2eda5d98220fbce3961573534a46f62ba02c7a47 b/fuzzer/corpus/2eda5d98220fbce3961573534a46f62ba02c7a47
new file mode 100644
index 0000000..d9004c5
--- /dev/null
+++ b/fuzzer/corpus/2eda5d98220fbce3961573534a46f62ba02c7a47
Binary files differ
diff --git a/fuzzer/corpus/2f1995d1e57bf1c3247bcfe75e58b6cc4ca4a78d b/fuzzer/corpus/2f1995d1e57bf1c3247bcfe75e58b6cc4ca4a78d
new file mode 100644
index 0000000..d75b8ac
--- /dev/null
+++ b/fuzzer/corpus/2f1995d1e57bf1c3247bcfe75e58b6cc4ca4a78d
Binary files differ
diff --git a/fuzzer/corpus/2f1d370325c03f3d4ab53b75ae6e67516e6f987a b/fuzzer/corpus/2f1d370325c03f3d4ab53b75ae6e67516e6f987a
new file mode 100644
index 0000000..0beb2b0
--- /dev/null
+++ b/fuzzer/corpus/2f1d370325c03f3d4ab53b75ae6e67516e6f987a
Binary files differ
diff --git a/fuzzer/corpus/2f24d59e4afa404d79970b52e52530615b081c4b b/fuzzer/corpus/2f24d59e4afa404d79970b52e52530615b081c4b
new file mode 100644
index 0000000..e3c4b89
--- /dev/null
+++ b/fuzzer/corpus/2f24d59e4afa404d79970b52e52530615b081c4b
Binary files differ
diff --git a/fuzzer/corpus/2f3c8381e242e9b5f8a240ab4f3dd4f301f68363 b/fuzzer/corpus/2f3c8381e242e9b5f8a240ab4f3dd4f301f68363
new file mode 100644
index 0000000..aa11cbb
--- /dev/null
+++ b/fuzzer/corpus/2f3c8381e242e9b5f8a240ab4f3dd4f301f68363
Binary files differ
diff --git a/fuzzer/corpus/2f7a4bdd939fd227395e8b2e8a719fc835c08093 b/fuzzer/corpus/2f7a4bdd939fd227395e8b2e8a719fc835c08093
new file mode 100644
index 0000000..a503ee8
--- /dev/null
+++ b/fuzzer/corpus/2f7a4bdd939fd227395e8b2e8a719fc835c08093
Binary files differ
diff --git a/fuzzer/corpus/2f7d3e7ca82d9c31fa362970c73f061067711165 b/fuzzer/corpus/2f7d3e7ca82d9c31fa362970c73f061067711165
new file mode 100644
index 0000000..ded8ce7
--- /dev/null
+++ b/fuzzer/corpus/2f7d3e7ca82d9c31fa362970c73f061067711165
Binary files differ
diff --git a/fuzzer/corpus/2f895aecf72f4c9227ecfb7451d6f2959c056a23 b/fuzzer/corpus/2f895aecf72f4c9227ecfb7451d6f2959c056a23
new file mode 100644
index 0000000..21fcfa5
--- /dev/null
+++ b/fuzzer/corpus/2f895aecf72f4c9227ecfb7451d6f2959c056a23
Binary files differ
diff --git a/fuzzer/corpus/2f9e9e3f2a74aaef978b51fa50b2b38af0d78da2 b/fuzzer/corpus/2f9e9e3f2a74aaef978b51fa50b2b38af0d78da2
new file mode 100644
index 0000000..d0f81f1
--- /dev/null
+++ b/fuzzer/corpus/2f9e9e3f2a74aaef978b51fa50b2b38af0d78da2
Binary files differ
diff --git a/fuzzer/corpus/300c545f97f160d32ac5c3c17b2cba0b75942c0b b/fuzzer/corpus/300c545f97f160d32ac5c3c17b2cba0b75942c0b
new file mode 100644
index 0000000..9f0e756
--- /dev/null
+++ b/fuzzer/corpus/300c545f97f160d32ac5c3c17b2cba0b75942c0b
Binary files differ
diff --git a/fuzzer/corpus/301c5d6629e0a595690f459eeaaf37260e8d9499 b/fuzzer/corpus/301c5d6629e0a595690f459eeaaf37260e8d9499
new file mode 100644
index 0000000..fde2297
--- /dev/null
+++ b/fuzzer/corpus/301c5d6629e0a595690f459eeaaf37260e8d9499
Binary files differ
diff --git a/fuzzer/corpus/307a33742ee217ffe6c44351d1df18a910553cd4 b/fuzzer/corpus/307a33742ee217ffe6c44351d1df18a910553cd4
new file mode 100644
index 0000000..77aa1b5
--- /dev/null
+++ b/fuzzer/corpus/307a33742ee217ffe6c44351d1df18a910553cd4
Binary files differ
diff --git a/fuzzer/corpus/30e489610e3e71cb4534b9ed62a3375c203e9478 b/fuzzer/corpus/30e489610e3e71cb4534b9ed62a3375c203e9478
new file mode 100644
index 0000000..cee5ba1
--- /dev/null
+++ b/fuzzer/corpus/30e489610e3e71cb4534b9ed62a3375c203e9478
Binary files differ
diff --git a/fuzzer/corpus/30e9ee869066f7a79dc0fbefcf0fc18c37423813 b/fuzzer/corpus/30e9ee869066f7a79dc0fbefcf0fc18c37423813
new file mode 100644
index 0000000..52550d4
--- /dev/null
+++ b/fuzzer/corpus/30e9ee869066f7a79dc0fbefcf0fc18c37423813
Binary files differ
diff --git a/fuzzer/corpus/30f41ac83e042820e3738a44464f82d2fd7dfb48 b/fuzzer/corpus/30f41ac83e042820e3738a44464f82d2fd7dfb48
new file mode 100644
index 0000000..d201b12
--- /dev/null
+++ b/fuzzer/corpus/30f41ac83e042820e3738a44464f82d2fd7dfb48
Binary files differ
diff --git a/fuzzer/corpus/30f9024418bf8fc9d03a330a1ffa271cd57842c1 b/fuzzer/corpus/30f9024418bf8fc9d03a330a1ffa271cd57842c1
new file mode 100644
index 0000000..2ce0446
--- /dev/null
+++ b/fuzzer/corpus/30f9024418bf8fc9d03a330a1ffa271cd57842c1
Binary files differ
diff --git a/fuzzer/corpus/31159657c8497099fdb8de9c3464691faaabcc2e b/fuzzer/corpus/31159657c8497099fdb8de9c3464691faaabcc2e
new file mode 100644
index 0000000..3a75536
--- /dev/null
+++ b/fuzzer/corpus/31159657c8497099fdb8de9c3464691faaabcc2e
Binary files differ
diff --git a/fuzzer/corpus/311eb84e6e831a361c7bd6fc2c683d6fefb3e7d9 b/fuzzer/corpus/311eb84e6e831a361c7bd6fc2c683d6fefb3e7d9
new file mode 100644
index 0000000..632de19
--- /dev/null
+++ b/fuzzer/corpus/311eb84e6e831a361c7bd6fc2c683d6fefb3e7d9
Binary files differ
diff --git a/fuzzer/corpus/31639931451c559a9f8b5fa5a06869b0efc9fabb b/fuzzer/corpus/31639931451c559a9f8b5fa5a06869b0efc9fabb
new file mode 100644
index 0000000..5dc9adc
--- /dev/null
+++ b/fuzzer/corpus/31639931451c559a9f8b5fa5a06869b0efc9fabb
Binary files differ
diff --git a/fuzzer/corpus/31687b4405707ccd151394799ad0ce56ecdee2f4 b/fuzzer/corpus/31687b4405707ccd151394799ad0ce56ecdee2f4
new file mode 100644
index 0000000..891c9dd
--- /dev/null
+++ b/fuzzer/corpus/31687b4405707ccd151394799ad0ce56ecdee2f4
Binary files differ
diff --git a/fuzzer/corpus/316ec5aeebb16f90f3b3eca41fea3073d100c588 b/fuzzer/corpus/316ec5aeebb16f90f3b3eca41fea3073d100c588
new file mode 100644
index 0000000..e0ddc9d
--- /dev/null
+++ b/fuzzer/corpus/316ec5aeebb16f90f3b3eca41fea3073d100c588
Binary files differ
diff --git a/fuzzer/corpus/3195e8a4f141a82ff4ba3c534d022e15d3899799 b/fuzzer/corpus/3195e8a4f141a82ff4ba3c534d022e15d3899799
new file mode 100644
index 0000000..f533bcc
--- /dev/null
+++ b/fuzzer/corpus/3195e8a4f141a82ff4ba3c534d022e15d3899799
Binary files differ
diff --git a/fuzzer/corpus/31cd11b914233dc41e2a8f094b77806d3886a898 b/fuzzer/corpus/31cd11b914233dc41e2a8f094b77806d3886a898
new file mode 100644
index 0000000..273cb12
--- /dev/null
+++ b/fuzzer/corpus/31cd11b914233dc41e2a8f094b77806d3886a898
Binary files differ
diff --git a/fuzzer/corpus/31fbf723caa4b5ab8c13eef1ab28a5af9a11b252 b/fuzzer/corpus/31fbf723caa4b5ab8c13eef1ab28a5af9a11b252
new file mode 100644
index 0000000..14b1936
--- /dev/null
+++ b/fuzzer/corpus/31fbf723caa4b5ab8c13eef1ab28a5af9a11b252
Binary files differ
diff --git a/fuzzer/corpus/321d0e9ffda61ba4e7f602b55ce88bcaad4bfe4c b/fuzzer/corpus/321d0e9ffda61ba4e7f602b55ce88bcaad4bfe4c
new file mode 100644
index 0000000..651da03
--- /dev/null
+++ b/fuzzer/corpus/321d0e9ffda61ba4e7f602b55ce88bcaad4bfe4c
Binary files differ
diff --git a/fuzzer/corpus/322bab4ee1290c088af091695f09dda8f4a9c9f1 b/fuzzer/corpus/322bab4ee1290c088af091695f09dda8f4a9c9f1
new file mode 100644
index 0000000..049ced9
--- /dev/null
+++ b/fuzzer/corpus/322bab4ee1290c088af091695f09dda8f4a9c9f1
Binary files differ
diff --git a/fuzzer/corpus/323a81ff8759bce599717f6c66abd08ec47fb862 b/fuzzer/corpus/323a81ff8759bce599717f6c66abd08ec47fb862
new file mode 100644
index 0000000..ef12bb4
--- /dev/null
+++ b/fuzzer/corpus/323a81ff8759bce599717f6c66abd08ec47fb862
Binary files differ
diff --git a/fuzzer/corpus/3263949e1fae15f5ce342db9a78686ddf15151c5 b/fuzzer/corpus/3263949e1fae15f5ce342db9a78686ddf15151c5
new file mode 100644
index 0000000..063d5fc
--- /dev/null
+++ b/fuzzer/corpus/3263949e1fae15f5ce342db9a78686ddf15151c5
Binary files differ
diff --git a/fuzzer/corpus/326728a546ac69adadd16535fa502a868c73e697 b/fuzzer/corpus/326728a546ac69adadd16535fa502a868c73e697
new file mode 100644
index 0000000..88e878e
--- /dev/null
+++ b/fuzzer/corpus/326728a546ac69adadd16535fa502a868c73e697
Binary files differ
diff --git a/fuzzer/corpus/328cf115bcb5e0abbaa5ff19e0f3f7664675d9cc b/fuzzer/corpus/328cf115bcb5e0abbaa5ff19e0f3f7664675d9cc
new file mode 100644
index 0000000..a3b9797
--- /dev/null
+++ b/fuzzer/corpus/328cf115bcb5e0abbaa5ff19e0f3f7664675d9cc
Binary files differ
diff --git a/fuzzer/corpus/3296e4620adf468afa30b02ab06f8b85e4c4ba7c b/fuzzer/corpus/3296e4620adf468afa30b02ab06f8b85e4c4ba7c
new file mode 100644
index 0000000..2284d5e
--- /dev/null
+++ b/fuzzer/corpus/3296e4620adf468afa30b02ab06f8b85e4c4ba7c
Binary files differ
diff --git a/fuzzer/corpus/32e5dfb5b0c33918722f7387b6f07175bd94a2a8 b/fuzzer/corpus/32e5dfb5b0c33918722f7387b6f07175bd94a2a8
new file mode 100644
index 0000000..99eb491
--- /dev/null
+++ b/fuzzer/corpus/32e5dfb5b0c33918722f7387b6f07175bd94a2a8
Binary files differ
diff --git a/fuzzer/corpus/33024c2d4c3b16db6ba069f497c20d1fe4c91fbc b/fuzzer/corpus/33024c2d4c3b16db6ba069f497c20d1fe4c91fbc
new file mode 100644
index 0000000..7188b04
--- /dev/null
+++ b/fuzzer/corpus/33024c2d4c3b16db6ba069f497c20d1fe4c91fbc
Binary files differ
diff --git a/fuzzer/corpus/334027b721576a743b67e98448ce3c5baa28897e b/fuzzer/corpus/334027b721576a743b67e98448ce3c5baa28897e
new file mode 100644
index 0000000..f6563e6
--- /dev/null
+++ b/fuzzer/corpus/334027b721576a743b67e98448ce3c5baa28897e
Binary files differ
diff --git a/fuzzer/corpus/33547a3ec1c8c2a903c017f5e606badb1c7096d9 b/fuzzer/corpus/33547a3ec1c8c2a903c017f5e606badb1c7096d9
new file mode 100644
index 0000000..4c07e9b
--- /dev/null
+++ b/fuzzer/corpus/33547a3ec1c8c2a903c017f5e606badb1c7096d9
Binary files differ
diff --git a/fuzzer/corpus/335ddddde8eb1d243e9ab8df35ede4f8f834532a b/fuzzer/corpus/335ddddde8eb1d243e9ab8df35ede4f8f834532a
new file mode 100644
index 0000000..62a81b9
--- /dev/null
+++ b/fuzzer/corpus/335ddddde8eb1d243e9ab8df35ede4f8f834532a
Binary files differ
diff --git a/fuzzer/corpus/33675e431250a58dc5880fbd65959d539808b81c b/fuzzer/corpus/33675e431250a58dc5880fbd65959d539808b81c
new file mode 100644
index 0000000..2fb953b
--- /dev/null
+++ b/fuzzer/corpus/33675e431250a58dc5880fbd65959d539808b81c
Binary files differ
diff --git a/fuzzer/corpus/3392d5b4715288bdbb8f7979934beb4666c5032d b/fuzzer/corpus/3392d5b4715288bdbb8f7979934beb4666c5032d
new file mode 100644
index 0000000..6f0eaa5
--- /dev/null
+++ b/fuzzer/corpus/3392d5b4715288bdbb8f7979934beb4666c5032d
Binary files differ
diff --git a/fuzzer/corpus/3395595affc65d089707d441e2e25bd59cd6094f b/fuzzer/corpus/3395595affc65d089707d441e2e25bd59cd6094f
new file mode 100644
index 0000000..a5dac42
--- /dev/null
+++ b/fuzzer/corpus/3395595affc65d089707d441e2e25bd59cd6094f
Binary files differ
diff --git a/fuzzer/corpus/339807e232d08bc40283c3b86378ee2cc139572f b/fuzzer/corpus/339807e232d08bc40283c3b86378ee2cc139572f
new file mode 100644
index 0000000..28d1cd0
--- /dev/null
+++ b/fuzzer/corpus/339807e232d08bc40283c3b86378ee2cc139572f
Binary files differ
diff --git a/fuzzer/corpus/33aa508cde4c11f0e4b71ef0cfabe8ecea0bc96e b/fuzzer/corpus/33aa508cde4c11f0e4b71ef0cfabe8ecea0bc96e
new file mode 100644
index 0000000..1f0acf7
--- /dev/null
+++ b/fuzzer/corpus/33aa508cde4c11f0e4b71ef0cfabe8ecea0bc96e
Binary files differ
diff --git a/fuzzer/corpus/33fe01ec2404d54d0bac1b2fb226221e94565b67 b/fuzzer/corpus/33fe01ec2404d54d0bac1b2fb226221e94565b67
new file mode 100644
index 0000000..9c56506
--- /dev/null
+++ b/fuzzer/corpus/33fe01ec2404d54d0bac1b2fb226221e94565b67
Binary files differ
diff --git a/fuzzer/corpus/34548ccb26e68f61c5bbaad4828304fdbcb972c9 b/fuzzer/corpus/34548ccb26e68f61c5bbaad4828304fdbcb972c9
new file mode 100644
index 0000000..f06a9c6
--- /dev/null
+++ b/fuzzer/corpus/34548ccb26e68f61c5bbaad4828304fdbcb972c9
Binary files differ
diff --git a/fuzzer/corpus/3457d577bc46c48886ebc1d8991c66591852d5eb b/fuzzer/corpus/3457d577bc46c48886ebc1d8991c66591852d5eb
new file mode 100644
index 0000000..901cad4
--- /dev/null
+++ b/fuzzer/corpus/3457d577bc46c48886ebc1d8991c66591852d5eb
Binary files differ
diff --git a/fuzzer/corpus/3459c86c8ade3b5dc7e52d3777da32360aa73d86 b/fuzzer/corpus/3459c86c8ade3b5dc7e52d3777da32360aa73d86
new file mode 100644
index 0000000..7a374a1
--- /dev/null
+++ b/fuzzer/corpus/3459c86c8ade3b5dc7e52d3777da32360aa73d86
Binary files differ
diff --git a/fuzzer/corpus/34dd104366c79eaa63ef86c655e4d99360701637 b/fuzzer/corpus/34dd104366c79eaa63ef86c655e4d99360701637
new file mode 100644
index 0000000..1fe79cd
--- /dev/null
+++ b/fuzzer/corpus/34dd104366c79eaa63ef86c655e4d99360701637
Binary files differ
diff --git a/fuzzer/corpus/34e2e4748a7aaf8d10f8537525a06b0cbcf0f273 b/fuzzer/corpus/34e2e4748a7aaf8d10f8537525a06b0cbcf0f273
new file mode 100644
index 0000000..35d18f8
--- /dev/null
+++ b/fuzzer/corpus/34e2e4748a7aaf8d10f8537525a06b0cbcf0f273
Binary files differ
diff --git a/fuzzer/corpus/34f6cc92ad5ad78d8ea36663ef08c760d080ac9a b/fuzzer/corpus/34f6cc92ad5ad78d8ea36663ef08c760d080ac9a
new file mode 100644
index 0000000..1f29fd5
--- /dev/null
+++ b/fuzzer/corpus/34f6cc92ad5ad78d8ea36663ef08c760d080ac9a
Binary files differ
diff --git a/fuzzer/corpus/354f8cbe60938f87c8c6990673eacb81836ed667 b/fuzzer/corpus/354f8cbe60938f87c8c6990673eacb81836ed667
new file mode 100644
index 0000000..85757aa
--- /dev/null
+++ b/fuzzer/corpus/354f8cbe60938f87c8c6990673eacb81836ed667
Binary files differ
diff --git a/fuzzer/corpus/3582246ca057c6a5c7737eec0715377eac1e14d8 b/fuzzer/corpus/3582246ca057c6a5c7737eec0715377eac1e14d8
new file mode 100644
index 0000000..4064c81
--- /dev/null
+++ b/fuzzer/corpus/3582246ca057c6a5c7737eec0715377eac1e14d8
Binary files differ
diff --git a/fuzzer/corpus/35924cb6ba0dbe20ed96f6159f9496c6054a86be b/fuzzer/corpus/35924cb6ba0dbe20ed96f6159f9496c6054a86be
new file mode 100644
index 0000000..706d170
--- /dev/null
+++ b/fuzzer/corpus/35924cb6ba0dbe20ed96f6159f9496c6054a86be
Binary files differ
diff --git a/fuzzer/corpus/35c34ab216412ea97c89a8d5618248601a8fb5c9 b/fuzzer/corpus/35c34ab216412ea97c89a8d5618248601a8fb5c9
new file mode 100644
index 0000000..bd7e582
--- /dev/null
+++ b/fuzzer/corpus/35c34ab216412ea97c89a8d5618248601a8fb5c9
Binary files differ
diff --git a/fuzzer/corpus/35d2502327c6844ba4b9626b29a42dab1ca263fb b/fuzzer/corpus/35d2502327c6844ba4b9626b29a42dab1ca263fb
new file mode 100644
index 0000000..fcc7ee6
--- /dev/null
+++ b/fuzzer/corpus/35d2502327c6844ba4b9626b29a42dab1ca263fb
Binary files differ
diff --git a/fuzzer/corpus/35dfb1e8ccb3aed1355b3cf3a88c960007b34bbd b/fuzzer/corpus/35dfb1e8ccb3aed1355b3cf3a88c960007b34bbd
new file mode 100644
index 0000000..9f728d8
--- /dev/null
+++ b/fuzzer/corpus/35dfb1e8ccb3aed1355b3cf3a88c960007b34bbd
Binary files differ
diff --git a/fuzzer/corpus/363a17ee0ea87ed4a68a1bff23a5c170bb6bc0d7 b/fuzzer/corpus/363a17ee0ea87ed4a68a1bff23a5c170bb6bc0d7
new file mode 100644
index 0000000..8d26aa7
--- /dev/null
+++ b/fuzzer/corpus/363a17ee0ea87ed4a68a1bff23a5c170bb6bc0d7
Binary files differ
diff --git a/fuzzer/corpus/3642bff3fbfd91d0e756b44adb772f641de00d8a b/fuzzer/corpus/3642bff3fbfd91d0e756b44adb772f641de00d8a
new file mode 100644
index 0000000..b41889e
--- /dev/null
+++ b/fuzzer/corpus/3642bff3fbfd91d0e756b44adb772f641de00d8a
Binary files differ
diff --git a/fuzzer/corpus/366864e1c74b6641d235e313f817a85c10c31579 b/fuzzer/corpus/366864e1c74b6641d235e313f817a85c10c31579
new file mode 100644
index 0000000..1d526dd
--- /dev/null
+++ b/fuzzer/corpus/366864e1c74b6641d235e313f817a85c10c31579
Binary files differ
diff --git a/fuzzer/corpus/36e81f478101cc90267ce6cd3bbd98dbd01e8420 b/fuzzer/corpus/36e81f478101cc90267ce6cd3bbd98dbd01e8420
new file mode 100644
index 0000000..5283fa6
--- /dev/null
+++ b/fuzzer/corpus/36e81f478101cc90267ce6cd3bbd98dbd01e8420
Binary files differ
diff --git a/fuzzer/corpus/36e946a964dd86881ad9b5f65edcb36dd9d9621e b/fuzzer/corpus/36e946a964dd86881ad9b5f65edcb36dd9d9621e
new file mode 100644
index 0000000..e5225be
--- /dev/null
+++ b/fuzzer/corpus/36e946a964dd86881ad9b5f65edcb36dd9d9621e
Binary files differ
diff --git a/fuzzer/corpus/36ecd5e6c48d02d9d78a933b76d1cc9bad0e55b0 b/fuzzer/corpus/36ecd5e6c48d02d9d78a933b76d1cc9bad0e55b0
new file mode 100644
index 0000000..4298c7f
--- /dev/null
+++ b/fuzzer/corpus/36ecd5e6c48d02d9d78a933b76d1cc9bad0e55b0
Binary files differ
diff --git a/fuzzer/corpus/36f2c2f608b4e348b61afaa2eb33671688549d6b b/fuzzer/corpus/36f2c2f608b4e348b61afaa2eb33671688549d6b
new file mode 100644
index 0000000..03f913a
--- /dev/null
+++ b/fuzzer/corpus/36f2c2f608b4e348b61afaa2eb33671688549d6b
Binary files differ
diff --git a/fuzzer/corpus/36f3fa3ef9e7914420c4971c63acc00a28e61c7b b/fuzzer/corpus/36f3fa3ef9e7914420c4971c63acc00a28e61c7b
new file mode 100644
index 0000000..7cfff1b
--- /dev/null
+++ b/fuzzer/corpus/36f3fa3ef9e7914420c4971c63acc00a28e61c7b
Binary files differ
diff --git a/fuzzer/corpus/36f98e764fb70a30aa6fe7e449190f9933a9ef6f b/fuzzer/corpus/36f98e764fb70a30aa6fe7e449190f9933a9ef6f
new file mode 100644
index 0000000..a8ee000
--- /dev/null
+++ b/fuzzer/corpus/36f98e764fb70a30aa6fe7e449190f9933a9ef6f
Binary files differ
diff --git a/fuzzer/corpus/36ff0852525ec8f7a8d3ac182bd72d6b14dcb8d3 b/fuzzer/corpus/36ff0852525ec8f7a8d3ac182bd72d6b14dcb8d3
new file mode 100644
index 0000000..bc24bdd
--- /dev/null
+++ b/fuzzer/corpus/36ff0852525ec8f7a8d3ac182bd72d6b14dcb8d3
Binary files differ
diff --git a/fuzzer/corpus/3731399a2b00a9362fa9395dcaafba38db8d1a11 b/fuzzer/corpus/3731399a2b00a9362fa9395dcaafba38db8d1a11
new file mode 100644
index 0000000..e21b2b4
--- /dev/null
+++ b/fuzzer/corpus/3731399a2b00a9362fa9395dcaafba38db8d1a11
Binary files differ
diff --git a/fuzzer/corpus/376fe3d3319a81e450cc836a8ecf226b6fc89813 b/fuzzer/corpus/376fe3d3319a81e450cc836a8ecf226b6fc89813
new file mode 100644
index 0000000..64b2d73
--- /dev/null
+++ b/fuzzer/corpus/376fe3d3319a81e450cc836a8ecf226b6fc89813
Binary files differ
diff --git a/fuzzer/corpus/3777ffa7f5f6d0a6214f0c4914f48d16f3d1fafc b/fuzzer/corpus/3777ffa7f5f6d0a6214f0c4914f48d16f3d1fafc
new file mode 100644
index 0000000..88ce927
--- /dev/null
+++ b/fuzzer/corpus/3777ffa7f5f6d0a6214f0c4914f48d16f3d1fafc
Binary files differ
diff --git a/fuzzer/corpus/379ecc803c96c01cd666d5ae011d680a40689022 b/fuzzer/corpus/379ecc803c96c01cd666d5ae011d680a40689022
new file mode 100644
index 0000000..46dd1c0
--- /dev/null
+++ b/fuzzer/corpus/379ecc803c96c01cd666d5ae011d680a40689022
Binary files differ
diff --git a/fuzzer/corpus/37c9f12b0dacae45dd089c567b83d81083533da9 b/fuzzer/corpus/37c9f12b0dacae45dd089c567b83d81083533da9
new file mode 100644
index 0000000..b61b1d6
--- /dev/null
+++ b/fuzzer/corpus/37c9f12b0dacae45dd089c567b83d81083533da9
Binary files differ
diff --git a/fuzzer/corpus/37ccc956fc98abc2bdfd1c898917c7d1bd126d6f b/fuzzer/corpus/37ccc956fc98abc2bdfd1c898917c7d1bd126d6f
new file mode 100644
index 0000000..c3e69ea
--- /dev/null
+++ b/fuzzer/corpus/37ccc956fc98abc2bdfd1c898917c7d1bd126d6f
Binary files differ
diff --git a/fuzzer/corpus/37dc70c7835a687490af81c9b7ac65aaaa69ea79 b/fuzzer/corpus/37dc70c7835a687490af81c9b7ac65aaaa69ea79
new file mode 100644
index 0000000..d935863
--- /dev/null
+++ b/fuzzer/corpus/37dc70c7835a687490af81c9b7ac65aaaa69ea79
Binary files differ
diff --git a/fuzzer/corpus/37df83e8c6105d9e19f7670a731e89d1b8926730 b/fuzzer/corpus/37df83e8c6105d9e19f7670a731e89d1b8926730
new file mode 100644
index 0000000..4dbe61f
--- /dev/null
+++ b/fuzzer/corpus/37df83e8c6105d9e19f7670a731e89d1b8926730
Binary files differ
diff --git a/fuzzer/corpus/37f46006e3bdb78933beb43857eb91b6b2f822c7 b/fuzzer/corpus/37f46006e3bdb78933beb43857eb91b6b2f822c7
new file mode 100644
index 0000000..a6820ab
--- /dev/null
+++ b/fuzzer/corpus/37f46006e3bdb78933beb43857eb91b6b2f822c7
Binary files differ
diff --git a/fuzzer/corpus/384722b39d0cbc498257d71accd00bf3771987bd b/fuzzer/corpus/384722b39d0cbc498257d71accd00bf3771987bd
new file mode 100644
index 0000000..ab06800
--- /dev/null
+++ b/fuzzer/corpus/384722b39d0cbc498257d71accd00bf3771987bd
Binary files differ
diff --git a/fuzzer/corpus/38474d73c748bf8a3e6b7c4942715bbe2ac0cfd5 b/fuzzer/corpus/38474d73c748bf8a3e6b7c4942715bbe2ac0cfd5
new file mode 100644
index 0000000..15000fd
--- /dev/null
+++ b/fuzzer/corpus/38474d73c748bf8a3e6b7c4942715bbe2ac0cfd5
Binary files differ
diff --git a/fuzzer/corpus/3851ecc2228386a9f2397ce4a6b1062f7e968012 b/fuzzer/corpus/3851ecc2228386a9f2397ce4a6b1062f7e968012
new file mode 100644
index 0000000..3d2300d
--- /dev/null
+++ b/fuzzer/corpus/3851ecc2228386a9f2397ce4a6b1062f7e968012
Binary files differ
diff --git a/fuzzer/corpus/388a3d4a14ab2988100ebebc55b9fa01f25eaef8 b/fuzzer/corpus/388a3d4a14ab2988100ebebc55b9fa01f25eaef8
new file mode 100644
index 0000000..6bc1506
--- /dev/null
+++ b/fuzzer/corpus/388a3d4a14ab2988100ebebc55b9fa01f25eaef8
Binary files differ
diff --git a/fuzzer/corpus/389e74ba8d33356e11bc156fdcfb78e8ab87425c b/fuzzer/corpus/389e74ba8d33356e11bc156fdcfb78e8ab87425c
new file mode 100644
index 0000000..959adaa
--- /dev/null
+++ b/fuzzer/corpus/389e74ba8d33356e11bc156fdcfb78e8ab87425c
Binary files differ
diff --git a/fuzzer/corpus/38a2be07779a39ebaa16b676a9dd075c1ac4be35 b/fuzzer/corpus/38a2be07779a39ebaa16b676a9dd075c1ac4be35
new file mode 100644
index 0000000..7dc2c9e
--- /dev/null
+++ b/fuzzer/corpus/38a2be07779a39ebaa16b676a9dd075c1ac4be35
Binary files differ
diff --git a/fuzzer/corpus/38b8cc94e5b7b0579db60ab32fc379d960ed9c93 b/fuzzer/corpus/38b8cc94e5b7b0579db60ab32fc379d960ed9c93
new file mode 100644
index 0000000..92f004b
--- /dev/null
+++ b/fuzzer/corpus/38b8cc94e5b7b0579db60ab32fc379d960ed9c93
Binary files differ
diff --git a/fuzzer/corpus/38e495437b0489074df62ac0e9c80fb8ae20b902 b/fuzzer/corpus/38e495437b0489074df62ac0e9c80fb8ae20b902
new file mode 100644
index 0000000..485f1cc
--- /dev/null
+++ b/fuzzer/corpus/38e495437b0489074df62ac0e9c80fb8ae20b902
Binary files differ
diff --git a/fuzzer/corpus/38f9ab23eafa3172f5d997c0709115a9819f30d5 b/fuzzer/corpus/38f9ab23eafa3172f5d997c0709115a9819f30d5
new file mode 100644
index 0000000..0144871
--- /dev/null
+++ b/fuzzer/corpus/38f9ab23eafa3172f5d997c0709115a9819f30d5
Binary files differ
diff --git a/fuzzer/corpus/3915ba54ef9cb376c3de9c3a6643b104ddbdac51 b/fuzzer/corpus/3915ba54ef9cb376c3de9c3a6643b104ddbdac51
new file mode 100644
index 0000000..608feb9
--- /dev/null
+++ b/fuzzer/corpus/3915ba54ef9cb376c3de9c3a6643b104ddbdac51
Binary files differ
diff --git a/fuzzer/corpus/3942771f68f432f704d3b57171809a4a16373b1d b/fuzzer/corpus/3942771f68f432f704d3b57171809a4a16373b1d
new file mode 100644
index 0000000..b753ab7
--- /dev/null
+++ b/fuzzer/corpus/3942771f68f432f704d3b57171809a4a16373b1d
Binary files differ
diff --git a/fuzzer/corpus/395deb37b57ba0bf27e65a4706d9ae912f887984 b/fuzzer/corpus/395deb37b57ba0bf27e65a4706d9ae912f887984
new file mode 100644
index 0000000..204be13
--- /dev/null
+++ b/fuzzer/corpus/395deb37b57ba0bf27e65a4706d9ae912f887984
Binary files differ
diff --git a/fuzzer/corpus/39708ed68d0d9b8021f7fb329e5e8481fc425b1f b/fuzzer/corpus/39708ed68d0d9b8021f7fb329e5e8481fc425b1f
new file mode 100644
index 0000000..c56e4a8
--- /dev/null
+++ b/fuzzer/corpus/39708ed68d0d9b8021f7fb329e5e8481fc425b1f
Binary files differ
diff --git a/fuzzer/corpus/39722794ff193e45909718eb2a478ac3e3274898 b/fuzzer/corpus/39722794ff193e45909718eb2a478ac3e3274898
new file mode 100644
index 0000000..f0a23f5
--- /dev/null
+++ b/fuzzer/corpus/39722794ff193e45909718eb2a478ac3e3274898
Binary files differ
diff --git a/fuzzer/corpus/3998ed85c4361a20be1a98d07b072223194bddb6 b/fuzzer/corpus/3998ed85c4361a20be1a98d07b072223194bddb6
new file mode 100644
index 0000000..e99db0e
--- /dev/null
+++ b/fuzzer/corpus/3998ed85c4361a20be1a98d07b072223194bddb6
Binary files differ
diff --git a/fuzzer/corpus/39a5dc856caeb933e18fcee23b89c2c6949287c3 b/fuzzer/corpus/39a5dc856caeb933e18fcee23b89c2c6949287c3
new file mode 100644
index 0000000..7612c07
--- /dev/null
+++ b/fuzzer/corpus/39a5dc856caeb933e18fcee23b89c2c6949287c3
Binary files differ
diff --git a/fuzzer/corpus/39ac63bbc3262157ee25140961de3d027dfd460b b/fuzzer/corpus/39ac63bbc3262157ee25140961de3d027dfd460b
new file mode 100644
index 0000000..fcb0b8b
--- /dev/null
+++ b/fuzzer/corpus/39ac63bbc3262157ee25140961de3d027dfd460b
Binary files differ
diff --git a/fuzzer/corpus/39cd4184fe91b6e094078cc42f6251cc2b01e097 b/fuzzer/corpus/39cd4184fe91b6e094078cc42f6251cc2b01e097
new file mode 100644
index 0000000..64170e6
--- /dev/null
+++ b/fuzzer/corpus/39cd4184fe91b6e094078cc42f6251cc2b01e097
Binary files differ
diff --git a/fuzzer/corpus/39df87ce18a963080e1ff6a19dfa5306c8e7c251 b/fuzzer/corpus/39df87ce18a963080e1ff6a19dfa5306c8e7c251
new file mode 100644
index 0000000..d88be9b
--- /dev/null
+++ b/fuzzer/corpus/39df87ce18a963080e1ff6a19dfa5306c8e7c251
Binary files differ
diff --git a/fuzzer/corpus/3a13bc0c12d1f5e485e0ddca176e3a587e2a1fab b/fuzzer/corpus/3a13bc0c12d1f5e485e0ddca176e3a587e2a1fab
new file mode 100644
index 0000000..ef6f89d
--- /dev/null
+++ b/fuzzer/corpus/3a13bc0c12d1f5e485e0ddca176e3a587e2a1fab
Binary files differ
diff --git a/fuzzer/corpus/3a3c08bd4e1bb5107a4ac4ec6458f876699fdfd5 b/fuzzer/corpus/3a3c08bd4e1bb5107a4ac4ec6458f876699fdfd5
new file mode 100644
index 0000000..29230c6
--- /dev/null
+++ b/fuzzer/corpus/3a3c08bd4e1bb5107a4ac4ec6458f876699fdfd5
Binary files differ
diff --git a/fuzzer/corpus/3a4ac91d10b7258c53c547a53d00211d55078059 b/fuzzer/corpus/3a4ac91d10b7258c53c547a53d00211d55078059
new file mode 100644
index 0000000..328986b
--- /dev/null
+++ b/fuzzer/corpus/3a4ac91d10b7258c53c547a53d00211d55078059
Binary files differ
diff --git a/fuzzer/corpus/3a78363ff2e86b505afe11f8e66433afa06b7f40 b/fuzzer/corpus/3a78363ff2e86b505afe11f8e66433afa06b7f40
new file mode 100644
index 0000000..500d61e
--- /dev/null
+++ b/fuzzer/corpus/3a78363ff2e86b505afe11f8e66433afa06b7f40
Binary files differ
diff --git a/fuzzer/corpus/3a9433d99a985eac8383a83fea07cb5b64257070 b/fuzzer/corpus/3a9433d99a985eac8383a83fea07cb5b64257070
new file mode 100644
index 0000000..e2fd27f
--- /dev/null
+++ b/fuzzer/corpus/3a9433d99a985eac8383a83fea07cb5b64257070
Binary files differ
diff --git a/fuzzer/corpus/3a95e6d99099003652330f3e02bce38016224beb b/fuzzer/corpus/3a95e6d99099003652330f3e02bce38016224beb
new file mode 100644
index 0000000..3616fde
--- /dev/null
+++ b/fuzzer/corpus/3a95e6d99099003652330f3e02bce38016224beb
Binary files differ
diff --git a/fuzzer/corpus/3a970316106f6c1b35d8f9d5f3e146c2112f14a5 b/fuzzer/corpus/3a970316106f6c1b35d8f9d5f3e146c2112f14a5
new file mode 100644
index 0000000..db25995
--- /dev/null
+++ b/fuzzer/corpus/3a970316106f6c1b35d8f9d5f3e146c2112f14a5
Binary files differ
diff --git a/fuzzer/corpus/3abe683987a7d385ed4976d5c2733f50bca8d5a2 b/fuzzer/corpus/3abe683987a7d385ed4976d5c2733f50bca8d5a2
new file mode 100644
index 0000000..e30adbb
--- /dev/null
+++ b/fuzzer/corpus/3abe683987a7d385ed4976d5c2733f50bca8d5a2
Binary files differ
diff --git a/fuzzer/corpus/3af86afa0cea1dc18159b6a3090d15b1787914f6 b/fuzzer/corpus/3af86afa0cea1dc18159b6a3090d15b1787914f6
new file mode 100644
index 0000000..ff12b50
--- /dev/null
+++ b/fuzzer/corpus/3af86afa0cea1dc18159b6a3090d15b1787914f6
Binary files differ
diff --git a/fuzzer/corpus/3b10e09d3fd23deea69b0ad02423772b41a7eea0 b/fuzzer/corpus/3b10e09d3fd23deea69b0ad02423772b41a7eea0
new file mode 100644
index 0000000..b244934
--- /dev/null
+++ b/fuzzer/corpus/3b10e09d3fd23deea69b0ad02423772b41a7eea0
Binary files differ
diff --git a/fuzzer/corpus/3b3ec9193d98ddc5b68f9080e4644a57cdc3434b b/fuzzer/corpus/3b3ec9193d98ddc5b68f9080e4644a57cdc3434b
new file mode 100644
index 0000000..29f7927
--- /dev/null
+++ b/fuzzer/corpus/3b3ec9193d98ddc5b68f9080e4644a57cdc3434b
Binary files differ
diff --git a/fuzzer/corpus/3b40fa26ef8d2efd89c7485a7169f8caa153cb81 b/fuzzer/corpus/3b40fa26ef8d2efd89c7485a7169f8caa153cb81
new file mode 100644
index 0000000..4fcb615
--- /dev/null
+++ b/fuzzer/corpus/3b40fa26ef8d2efd89c7485a7169f8caa153cb81
Binary files differ
diff --git a/fuzzer/corpus/3ba6ebc2d5753118c4e8623aa7138470ffccf7f2 b/fuzzer/corpus/3ba6ebc2d5753118c4e8623aa7138470ffccf7f2
new file mode 100644
index 0000000..2fc9a38
--- /dev/null
+++ b/fuzzer/corpus/3ba6ebc2d5753118c4e8623aa7138470ffccf7f2
Binary files differ
diff --git a/fuzzer/corpus/3bc1ee34a43f22d79553624be0198b945020db01 b/fuzzer/corpus/3bc1ee34a43f22d79553624be0198b945020db01
new file mode 100644
index 0000000..fc35f93
--- /dev/null
+++ b/fuzzer/corpus/3bc1ee34a43f22d79553624be0198b945020db01
Binary files differ
diff --git a/fuzzer/corpus/3bd120c9c543c838739a7a11e7203be29cd5f6d5 b/fuzzer/corpus/3bd120c9c543c838739a7a11e7203be29cd5f6d5
new file mode 100644
index 0000000..76801d6
--- /dev/null
+++ b/fuzzer/corpus/3bd120c9c543c838739a7a11e7203be29cd5f6d5
Binary files differ
diff --git a/fuzzer/corpus/3bdd0b395cf4e85b9f9126ac449c8019d2ed05b2 b/fuzzer/corpus/3bdd0b395cf4e85b9f9126ac449c8019d2ed05b2
new file mode 100644
index 0000000..e580fb7
--- /dev/null
+++ b/fuzzer/corpus/3bdd0b395cf4e85b9f9126ac449c8019d2ed05b2
Binary files differ
diff --git a/fuzzer/corpus/3c110c2ada493eaa4a3aa4be5c66f9e3f98aee5a b/fuzzer/corpus/3c110c2ada493eaa4a3aa4be5c66f9e3f98aee5a
new file mode 100644
index 0000000..e80db60
--- /dev/null
+++ b/fuzzer/corpus/3c110c2ada493eaa4a3aa4be5c66f9e3f98aee5a
Binary files differ
diff --git a/fuzzer/corpus/3c4bca2dcb7ec37c795be89744956dc098424e2b b/fuzzer/corpus/3c4bca2dcb7ec37c795be89744956dc098424e2b
new file mode 100644
index 0000000..80e332e
--- /dev/null
+++ b/fuzzer/corpus/3c4bca2dcb7ec37c795be89744956dc098424e2b
Binary files differ
diff --git a/fuzzer/corpus/3c53ca7f1515bfa6ac4da2758342f01943d85dc1 b/fuzzer/corpus/3c53ca7f1515bfa6ac4da2758342f01943d85dc1
new file mode 100644
index 0000000..38d091d
--- /dev/null
+++ b/fuzzer/corpus/3c53ca7f1515bfa6ac4da2758342f01943d85dc1
Binary files differ
diff --git a/fuzzer/corpus/3c66c6cc5aada6e33563fc14af3a52e1862462bc b/fuzzer/corpus/3c66c6cc5aada6e33563fc14af3a52e1862462bc
new file mode 100644
index 0000000..29c77a5
--- /dev/null
+++ b/fuzzer/corpus/3c66c6cc5aada6e33563fc14af3a52e1862462bc
Binary files differ
diff --git a/fuzzer/corpus/3ccbf6fc3cbc8a832320011b1d6615faf6c2b832 b/fuzzer/corpus/3ccbf6fc3cbc8a832320011b1d6615faf6c2b832
new file mode 100644
index 0000000..b4f265a
--- /dev/null
+++ b/fuzzer/corpus/3ccbf6fc3cbc8a832320011b1d6615faf6c2b832
Binary files differ
diff --git a/fuzzer/corpus/3cdaad14bf1228cd114e78fd4c8d9abdb1b0b8a3 b/fuzzer/corpus/3cdaad14bf1228cd114e78fd4c8d9abdb1b0b8a3
new file mode 100644
index 0000000..1947449
--- /dev/null
+++ b/fuzzer/corpus/3cdaad14bf1228cd114e78fd4c8d9abdb1b0b8a3
Binary files differ
diff --git a/fuzzer/corpus/3d0b741123a9c155718ad238791e177b3e734456 b/fuzzer/corpus/3d0b741123a9c155718ad238791e177b3e734456
new file mode 100644
index 0000000..a53c5bf
--- /dev/null
+++ b/fuzzer/corpus/3d0b741123a9c155718ad238791e177b3e734456
Binary files differ
diff --git a/fuzzer/corpus/3d18decfdd2aa7c608969f3b117c0ddb3a516cfa b/fuzzer/corpus/3d18decfdd2aa7c608969f3b117c0ddb3a516cfa
new file mode 100644
index 0000000..7abb01c
--- /dev/null
+++ b/fuzzer/corpus/3d18decfdd2aa7c608969f3b117c0ddb3a516cfa
Binary files differ
diff --git a/fuzzer/corpus/3d223cb01f3463cd3e3ed7b422b1da522a17b29d b/fuzzer/corpus/3d223cb01f3463cd3e3ed7b422b1da522a17b29d
new file mode 100644
index 0000000..9d3add6
--- /dev/null
+++ b/fuzzer/corpus/3d223cb01f3463cd3e3ed7b422b1da522a17b29d
Binary files differ
diff --git a/fuzzer/corpus/3d275cbc3a9d8483c5a3c9344ee92ad6624f258a b/fuzzer/corpus/3d275cbc3a9d8483c5a3c9344ee92ad6624f258a
new file mode 100644
index 0000000..a4a1707
--- /dev/null
+++ b/fuzzer/corpus/3d275cbc3a9d8483c5a3c9344ee92ad6624f258a
Binary files differ
diff --git a/fuzzer/corpus/3d73a879a78a074c651609b8eeed69133c351bf1 b/fuzzer/corpus/3d73a879a78a074c651609b8eeed69133c351bf1
new file mode 100644
index 0000000..c4455e2
--- /dev/null
+++ b/fuzzer/corpus/3d73a879a78a074c651609b8eeed69133c351bf1
Binary files differ
diff --git a/fuzzer/corpus/3d7615c2c1d058eaec88b26db15c6a6400b8e12d b/fuzzer/corpus/3d7615c2c1d058eaec88b26db15c6a6400b8e12d
new file mode 100644
index 0000000..6f31ec6
--- /dev/null
+++ b/fuzzer/corpus/3d7615c2c1d058eaec88b26db15c6a6400b8e12d
Binary files differ
diff --git a/fuzzer/corpus/3d82ce853b6cc3ea62e2edbb69bb8af3340a18ba b/fuzzer/corpus/3d82ce853b6cc3ea62e2edbb69bb8af3340a18ba
new file mode 100644
index 0000000..a822f54
--- /dev/null
+++ b/fuzzer/corpus/3d82ce853b6cc3ea62e2edbb69bb8af3340a18ba
Binary files differ
diff --git a/fuzzer/corpus/3d9e73f99911b53a65ccc0af00699a9c1a60b103 b/fuzzer/corpus/3d9e73f99911b53a65ccc0af00699a9c1a60b103
new file mode 100644
index 0000000..1b1afc6
--- /dev/null
+++ b/fuzzer/corpus/3d9e73f99911b53a65ccc0af00699a9c1a60b103
Binary files differ
diff --git a/fuzzer/corpus/3d9f8c75e3aa2a79f9b56aed46ec3c4eb695bcd3 b/fuzzer/corpus/3d9f8c75e3aa2a79f9b56aed46ec3c4eb695bcd3
new file mode 100644
index 0000000..faae60d
--- /dev/null
+++ b/fuzzer/corpus/3d9f8c75e3aa2a79f9b56aed46ec3c4eb695bcd3
Binary files differ
diff --git a/fuzzer/corpus/3dac9c7e9d9df3e3df60a2a045f7629e7ea19bd9 b/fuzzer/corpus/3dac9c7e9d9df3e3df60a2a045f7629e7ea19bd9
new file mode 100644
index 0000000..95960a7
--- /dev/null
+++ b/fuzzer/corpus/3dac9c7e9d9df3e3df60a2a045f7629e7ea19bd9
Binary files differ
diff --git a/fuzzer/corpus/3dc64a53c5888217ce40fdf659cf4d3925dc91f4 b/fuzzer/corpus/3dc64a53c5888217ce40fdf659cf4d3925dc91f4
new file mode 100644
index 0000000..e88d941
--- /dev/null
+++ b/fuzzer/corpus/3dc64a53c5888217ce40fdf659cf4d3925dc91f4
Binary files differ
diff --git a/fuzzer/corpus/3dda8a68d3fff33d141a7ebfd5101e2fd7f19489 b/fuzzer/corpus/3dda8a68d3fff33d141a7ebfd5101e2fd7f19489
new file mode 100644
index 0000000..a96ab77
--- /dev/null
+++ b/fuzzer/corpus/3dda8a68d3fff33d141a7ebfd5101e2fd7f19489
Binary files differ
diff --git a/fuzzer/corpus/3e1a394fa18fe58a522b874cacf9afa093345879 b/fuzzer/corpus/3e1a394fa18fe58a522b874cacf9afa093345879
new file mode 100644
index 0000000..e8f3aad
--- /dev/null
+++ b/fuzzer/corpus/3e1a394fa18fe58a522b874cacf9afa093345879
Binary files differ
diff --git a/fuzzer/corpus/3e334e58f7c0a6193122088cfc3d45d87f481d64 b/fuzzer/corpus/3e334e58f7c0a6193122088cfc3d45d87f481d64
new file mode 100644
index 0000000..f4c489a
--- /dev/null
+++ b/fuzzer/corpus/3e334e58f7c0a6193122088cfc3d45d87f481d64
Binary files differ
diff --git a/fuzzer/corpus/3e44ff8f35e193f7b7fa0e1831dc37cefaa4de02 b/fuzzer/corpus/3e44ff8f35e193f7b7fa0e1831dc37cefaa4de02
new file mode 100644
index 0000000..c67526d
--- /dev/null
+++ b/fuzzer/corpus/3e44ff8f35e193f7b7fa0e1831dc37cefaa4de02
Binary files differ
diff --git a/fuzzer/corpus/3e8b1c5a3088257149e28a9e485e0ba82ab628db b/fuzzer/corpus/3e8b1c5a3088257149e28a9e485e0ba82ab628db
new file mode 100644
index 0000000..8bdf9d0
--- /dev/null
+++ b/fuzzer/corpus/3e8b1c5a3088257149e28a9e485e0ba82ab628db
Binary files differ
diff --git a/fuzzer/corpus/3e9e8ec251dc7ba7c255e8d23c99c0643468233d b/fuzzer/corpus/3e9e8ec251dc7ba7c255e8d23c99c0643468233d
new file mode 100644
index 0000000..d667020
--- /dev/null
+++ b/fuzzer/corpus/3e9e8ec251dc7ba7c255e8d23c99c0643468233d
Binary files differ
diff --git a/fuzzer/corpus/3eb0759adda77c53acce357222fdcf2053313094 b/fuzzer/corpus/3eb0759adda77c53acce357222fdcf2053313094
new file mode 100644
index 0000000..d176346
--- /dev/null
+++ b/fuzzer/corpus/3eb0759adda77c53acce357222fdcf2053313094
Binary files differ
diff --git a/fuzzer/corpus/3f0d4db6e8f1b652dfc87aaa7adef1982655ccc0 b/fuzzer/corpus/3f0d4db6e8f1b652dfc87aaa7adef1982655ccc0
new file mode 100644
index 0000000..d69b381
--- /dev/null
+++ b/fuzzer/corpus/3f0d4db6e8f1b652dfc87aaa7adef1982655ccc0
Binary files differ
diff --git a/fuzzer/corpus/3f1349df4a14cc4d102b2583fecdd9082ce76081 b/fuzzer/corpus/3f1349df4a14cc4d102b2583fecdd9082ce76081
new file mode 100644
index 0000000..21baef8
--- /dev/null
+++ b/fuzzer/corpus/3f1349df4a14cc4d102b2583fecdd9082ce76081
Binary files differ
diff --git a/fuzzer/corpus/3f687d2e945375117d0a2b1caecd4f8c6e6d83ca b/fuzzer/corpus/3f687d2e945375117d0a2b1caecd4f8c6e6d83ca
new file mode 100644
index 0000000..737a50d
--- /dev/null
+++ b/fuzzer/corpus/3f687d2e945375117d0a2b1caecd4f8c6e6d83ca
Binary files differ
diff --git a/fuzzer/corpus/3f6ddc51c3619404b9e75f72fd112ec5a76fc64d b/fuzzer/corpus/3f6ddc51c3619404b9e75f72fd112ec5a76fc64d
new file mode 100644
index 0000000..3e6be7d
--- /dev/null
+++ b/fuzzer/corpus/3f6ddc51c3619404b9e75f72fd112ec5a76fc64d
Binary files differ
diff --git a/fuzzer/corpus/3f9ac80a27a5cdc533592f2435384f11feca27b7 b/fuzzer/corpus/3f9ac80a27a5cdc533592f2435384f11feca27b7
new file mode 100644
index 0000000..b0aa5f4
--- /dev/null
+++ b/fuzzer/corpus/3f9ac80a27a5cdc533592f2435384f11feca27b7
Binary files differ
diff --git a/fuzzer/corpus/3f9f73ce36478867a4605a96694ad1ac58568b8d b/fuzzer/corpus/3f9f73ce36478867a4605a96694ad1ac58568b8d
new file mode 100644
index 0000000..9d41c6b
--- /dev/null
+++ b/fuzzer/corpus/3f9f73ce36478867a4605a96694ad1ac58568b8d
Binary files differ
diff --git a/fuzzer/corpus/3fb546812bd87b53fe9c8bd2fb8d4fe5f55b088c b/fuzzer/corpus/3fb546812bd87b53fe9c8bd2fb8d4fe5f55b088c
new file mode 100644
index 0000000..2fb4f34
--- /dev/null
+++ b/fuzzer/corpus/3fb546812bd87b53fe9c8bd2fb8d4fe5f55b088c
Binary files differ
diff --git a/fuzzer/corpus/3fc0df015ffc9d645d8e8a217a0b97e0670cba21 b/fuzzer/corpus/3fc0df015ffc9d645d8e8a217a0b97e0670cba21
new file mode 100644
index 0000000..e42bd12
--- /dev/null
+++ b/fuzzer/corpus/3fc0df015ffc9d645d8e8a217a0b97e0670cba21
Binary files differ
diff --git a/fuzzer/corpus/3fd5193a7187cb18463bf8da4f4c842f314d5995 b/fuzzer/corpus/3fd5193a7187cb18463bf8da4f4c842f314d5995
new file mode 100644
index 0000000..c49d7b5
--- /dev/null
+++ b/fuzzer/corpus/3fd5193a7187cb18463bf8da4f4c842f314d5995
Binary files differ
diff --git a/fuzzer/corpus/3fd78ce33b5b209035ba45ca19e86442bf50ecf6 b/fuzzer/corpus/3fd78ce33b5b209035ba45ca19e86442bf50ecf6
new file mode 100644
index 0000000..f55fca8
--- /dev/null
+++ b/fuzzer/corpus/3fd78ce33b5b209035ba45ca19e86442bf50ecf6
Binary files differ
diff --git a/fuzzer/corpus/3ff19c57ca1f3cc01876498b0a953273906dbbdc b/fuzzer/corpus/3ff19c57ca1f3cc01876498b0a953273906dbbdc
new file mode 100644
index 0000000..8148e4a
--- /dev/null
+++ b/fuzzer/corpus/3ff19c57ca1f3cc01876498b0a953273906dbbdc
Binary files differ
diff --git a/fuzzer/corpus/3ff51948d3d4d45f4ebd06f358edabbc5b7b9591 b/fuzzer/corpus/3ff51948d3d4d45f4ebd06f358edabbc5b7b9591
new file mode 100644
index 0000000..4eca15e
--- /dev/null
+++ b/fuzzer/corpus/3ff51948d3d4d45f4ebd06f358edabbc5b7b9591
Binary files differ
diff --git a/fuzzer/corpus/3ffbc29ca6b05a807f47e3fe8b801f024af6baa7 b/fuzzer/corpus/3ffbc29ca6b05a807f47e3fe8b801f024af6baa7
new file mode 100644
index 0000000..f26da0d
--- /dev/null
+++ b/fuzzer/corpus/3ffbc29ca6b05a807f47e3fe8b801f024af6baa7
Binary files differ
diff --git a/fuzzer/corpus/40329c2dfd0b5557ddad1426bb978a1f6ac5d3d4 b/fuzzer/corpus/40329c2dfd0b5557ddad1426bb978a1f6ac5d3d4
new file mode 100644
index 0000000..6f2fc77
--- /dev/null
+++ b/fuzzer/corpus/40329c2dfd0b5557ddad1426bb978a1f6ac5d3d4
Binary files differ
diff --git a/fuzzer/corpus/4044f02ae152b5586847f90572fd0213a0e02273 b/fuzzer/corpus/4044f02ae152b5586847f90572fd0213a0e02273
new file mode 100644
index 0000000..320a92d
--- /dev/null
+++ b/fuzzer/corpus/4044f02ae152b5586847f90572fd0213a0e02273
Binary files differ
diff --git a/fuzzer/corpus/40458548157c8bd0cf6f4373d3e084a9b6e4fd5e b/fuzzer/corpus/40458548157c8bd0cf6f4373d3e084a9b6e4fd5e
new file mode 100644
index 0000000..bae68f1
--- /dev/null
+++ b/fuzzer/corpus/40458548157c8bd0cf6f4373d3e084a9b6e4fd5e
Binary files differ
diff --git a/fuzzer/corpus/4055d4180d2b5209e04a111dfbe6206c6b327797 b/fuzzer/corpus/4055d4180d2b5209e04a111dfbe6206c6b327797
new file mode 100644
index 0000000..19e9615
--- /dev/null
+++ b/fuzzer/corpus/4055d4180d2b5209e04a111dfbe6206c6b327797
Binary files differ
diff --git a/fuzzer/corpus/405ed43ddaaf49f883d26ffc462dbc7429ce8b00 b/fuzzer/corpus/405ed43ddaaf49f883d26ffc462dbc7429ce8b00
new file mode 100644
index 0000000..497ca29
--- /dev/null
+++ b/fuzzer/corpus/405ed43ddaaf49f883d26ffc462dbc7429ce8b00
Binary files differ
diff --git a/fuzzer/corpus/408d40b64b3c54d7d1ab7c510b5577007ea49b1b b/fuzzer/corpus/408d40b64b3c54d7d1ab7c510b5577007ea49b1b
new file mode 100644
index 0000000..2baa9ae
--- /dev/null
+++ b/fuzzer/corpus/408d40b64b3c54d7d1ab7c510b5577007ea49b1b
Binary files differ
diff --git a/fuzzer/corpus/4091f2765b6198e354d89934aa10a5a0123639e7 b/fuzzer/corpus/4091f2765b6198e354d89934aa10a5a0123639e7
new file mode 100644
index 0000000..1271bd1
--- /dev/null
+++ b/fuzzer/corpus/4091f2765b6198e354d89934aa10a5a0123639e7
Binary files differ
diff --git a/fuzzer/corpus/40aecdc88b99221f72b23e9e2eb43bdc717e45d5 b/fuzzer/corpus/40aecdc88b99221f72b23e9e2eb43bdc717e45d5
new file mode 100644
index 0000000..c5e6601
--- /dev/null
+++ b/fuzzer/corpus/40aecdc88b99221f72b23e9e2eb43bdc717e45d5
Binary files differ
diff --git a/fuzzer/corpus/40c960d7a807e01bac5411dc8584842e50aca3be b/fuzzer/corpus/40c960d7a807e01bac5411dc8584842e50aca3be
new file mode 100644
index 0000000..e47868d
--- /dev/null
+++ b/fuzzer/corpus/40c960d7a807e01bac5411dc8584842e50aca3be
Binary files differ
diff --git a/fuzzer/corpus/40ca56e9bbba92657a7bd8084de43e29bff2ea37 b/fuzzer/corpus/40ca56e9bbba92657a7bd8084de43e29bff2ea37
new file mode 100644
index 0000000..111e79a
--- /dev/null
+++ b/fuzzer/corpus/40ca56e9bbba92657a7bd8084de43e29bff2ea37
Binary files differ
diff --git a/fuzzer/corpus/40dfbf10224d335a28026e0eef1656d4a40505ad b/fuzzer/corpus/40dfbf10224d335a28026e0eef1656d4a40505ad
new file mode 100644
index 0000000..6c21767
--- /dev/null
+++ b/fuzzer/corpus/40dfbf10224d335a28026e0eef1656d4a40505ad
Binary files differ
diff --git a/fuzzer/corpus/40f286c2fbf58efd5466f2db430fbf7494614be9 b/fuzzer/corpus/40f286c2fbf58efd5466f2db430fbf7494614be9
new file mode 100644
index 0000000..6ec07fd
--- /dev/null
+++ b/fuzzer/corpus/40f286c2fbf58efd5466f2db430fbf7494614be9
Binary files differ
diff --git a/fuzzer/corpus/412720548a693cdd970c50d2a44e5ccc7602db9c b/fuzzer/corpus/412720548a693cdd970c50d2a44e5ccc7602db9c
new file mode 100644
index 0000000..0ac7501
--- /dev/null
+++ b/fuzzer/corpus/412720548a693cdd970c50d2a44e5ccc7602db9c
Binary files differ
diff --git a/fuzzer/corpus/413106b9dc73ca31bdfecd23057e468e374c2f31 b/fuzzer/corpus/413106b9dc73ca31bdfecd23057e468e374c2f31
new file mode 100644
index 0000000..210e8dd
--- /dev/null
+++ b/fuzzer/corpus/413106b9dc73ca31bdfecd23057e468e374c2f31
Binary files differ
diff --git a/fuzzer/corpus/41335e0c82bb96a952b1bbfa0c1f00df10fda809 b/fuzzer/corpus/41335e0c82bb96a952b1bbfa0c1f00df10fda809
new file mode 100644
index 0000000..8d20bf9
--- /dev/null
+++ b/fuzzer/corpus/41335e0c82bb96a952b1bbfa0c1f00df10fda809
Binary files differ
diff --git a/fuzzer/corpus/4134fcf90e7cf994669dc6acea4ecc1bd503d2cd b/fuzzer/corpus/4134fcf90e7cf994669dc6acea4ecc1bd503d2cd
new file mode 100644
index 0000000..660d56d
--- /dev/null
+++ b/fuzzer/corpus/4134fcf90e7cf994669dc6acea4ecc1bd503d2cd
Binary files differ
diff --git a/fuzzer/corpus/41584e3427ac6221f95e05d0a4a4d7e3055a240d b/fuzzer/corpus/41584e3427ac6221f95e05d0a4a4d7e3055a240d
new file mode 100644
index 0000000..88dfa41
--- /dev/null
+++ b/fuzzer/corpus/41584e3427ac6221f95e05d0a4a4d7e3055a240d
Binary files differ
diff --git a/fuzzer/corpus/4186b85c4506bba256807c212d3e182743c93181 b/fuzzer/corpus/4186b85c4506bba256807c212d3e182743c93181
new file mode 100644
index 0000000..b86aec6
--- /dev/null
+++ b/fuzzer/corpus/4186b85c4506bba256807c212d3e182743c93181
Binary files differ
diff --git a/fuzzer/corpus/4194d4f0bf534533aaa17f26b09cdf7f12553fb6 b/fuzzer/corpus/4194d4f0bf534533aaa17f26b09cdf7f12553fb6
new file mode 100644
index 0000000..ff439c5
--- /dev/null
+++ b/fuzzer/corpus/4194d4f0bf534533aaa17f26b09cdf7f12553fb6
Binary files differ
diff --git a/fuzzer/corpus/4196c508d14fe694df32f8204e3d2999f665da6a b/fuzzer/corpus/4196c508d14fe694df32f8204e3d2999f665da6a
new file mode 100644
index 0000000..bf93412
--- /dev/null
+++ b/fuzzer/corpus/4196c508d14fe694df32f8204e3d2999f665da6a
Binary files differ
diff --git a/fuzzer/corpus/41a107ed47ca1cf0fccd6be4290d840d6ff56684 b/fuzzer/corpus/41a107ed47ca1cf0fccd6be4290d840d6ff56684
new file mode 100644
index 0000000..ac97f72
--- /dev/null
+++ b/fuzzer/corpus/41a107ed47ca1cf0fccd6be4290d840d6ff56684
Binary files differ
diff --git a/fuzzer/corpus/41bba768406de331145bc73184616283a6c21435 b/fuzzer/corpus/41bba768406de331145bc73184616283a6c21435
new file mode 100644
index 0000000..b84f638
--- /dev/null
+++ b/fuzzer/corpus/41bba768406de331145bc73184616283a6c21435
Binary files differ
diff --git a/fuzzer/corpus/41eb38f14e8b574a8843608940ad38a261f05168 b/fuzzer/corpus/41eb38f14e8b574a8843608940ad38a261f05168
new file mode 100644
index 0000000..68bb6f8
--- /dev/null
+++ b/fuzzer/corpus/41eb38f14e8b574a8843608940ad38a261f05168
Binary files differ
diff --git a/fuzzer/corpus/41ec92787063926df8944fdecefaf53fe1a7b5e5 b/fuzzer/corpus/41ec92787063926df8944fdecefaf53fe1a7b5e5
new file mode 100644
index 0000000..93cc9ce
--- /dev/null
+++ b/fuzzer/corpus/41ec92787063926df8944fdecefaf53fe1a7b5e5
Binary files differ
diff --git a/fuzzer/corpus/41eefbb789679b53a64f6626494d219f1430f879 b/fuzzer/corpus/41eefbb789679b53a64f6626494d219f1430f879
new file mode 100644
index 0000000..d82b221
--- /dev/null
+++ b/fuzzer/corpus/41eefbb789679b53a64f6626494d219f1430f879
Binary files differ
diff --git a/fuzzer/corpus/4206806f2d00c457ea5de97e66e55c6de6ffb89e b/fuzzer/corpus/4206806f2d00c457ea5de97e66e55c6de6ffb89e
new file mode 100644
index 0000000..18451dc
--- /dev/null
+++ b/fuzzer/corpus/4206806f2d00c457ea5de97e66e55c6de6ffb89e
Binary files differ
diff --git a/fuzzer/corpus/422488058b968a30cf7764d28d0ded8c1bf8449a b/fuzzer/corpus/422488058b968a30cf7764d28d0ded8c1bf8449a
new file mode 100644
index 0000000..a6812c2
--- /dev/null
+++ b/fuzzer/corpus/422488058b968a30cf7764d28d0ded8c1bf8449a
Binary files differ
diff --git a/fuzzer/corpus/424b964fb6a4d92e4437d3110ae7698a7c9688fa b/fuzzer/corpus/424b964fb6a4d92e4437d3110ae7698a7c9688fa
new file mode 100644
index 0000000..bdf9e31
--- /dev/null
+++ b/fuzzer/corpus/424b964fb6a4d92e4437d3110ae7698a7c9688fa
Binary files differ
diff --git a/fuzzer/corpus/4256e705a385c38f2784695a200d16c542ac4a4f b/fuzzer/corpus/4256e705a385c38f2784695a200d16c542ac4a4f
new file mode 100644
index 0000000..60e5c74
--- /dev/null
+++ b/fuzzer/corpus/4256e705a385c38f2784695a200d16c542ac4a4f
Binary files differ
diff --git a/fuzzer/corpus/426f5a6d1afbe4ce58a91cafa0529025ccbd075e b/fuzzer/corpus/426f5a6d1afbe4ce58a91cafa0529025ccbd075e
new file mode 100644
index 0000000..bfed2da
--- /dev/null
+++ b/fuzzer/corpus/426f5a6d1afbe4ce58a91cafa0529025ccbd075e
Binary files differ
diff --git a/fuzzer/corpus/42914883e1e41c0835e439cbec407a8c81153fec b/fuzzer/corpus/42914883e1e41c0835e439cbec407a8c81153fec
new file mode 100644
index 0000000..9f68e2e
--- /dev/null
+++ b/fuzzer/corpus/42914883e1e41c0835e439cbec407a8c81153fec
Binary files differ
diff --git a/fuzzer/corpus/42ba9f5cdfb4bac5fbc46b9290c4d379ddbebfda b/fuzzer/corpus/42ba9f5cdfb4bac5fbc46b9290c4d379ddbebfda
new file mode 100644
index 0000000..f74ed2b
--- /dev/null
+++ b/fuzzer/corpus/42ba9f5cdfb4bac5fbc46b9290c4d379ddbebfda
Binary files differ
diff --git a/fuzzer/corpus/42c04f4949f6accdb425e809024b0fa34f91f32c b/fuzzer/corpus/42c04f4949f6accdb425e809024b0fa34f91f32c
new file mode 100644
index 0000000..5c51dd1
--- /dev/null
+++ b/fuzzer/corpus/42c04f4949f6accdb425e809024b0fa34f91f32c
Binary files differ
diff --git a/fuzzer/corpus/42cc9a350b9d030354e8f34b217062cb7d6a12b5 b/fuzzer/corpus/42cc9a350b9d030354e8f34b217062cb7d6a12b5
new file mode 100644
index 0000000..92bb93e
--- /dev/null
+++ b/fuzzer/corpus/42cc9a350b9d030354e8f34b217062cb7d6a12b5
Binary files differ
diff --git a/fuzzer/corpus/42f8549e216d4fc4fb83ec37f4ef82e8d1804270 b/fuzzer/corpus/42f8549e216d4fc4fb83ec37f4ef82e8d1804270
new file mode 100644
index 0000000..902efed
--- /dev/null
+++ b/fuzzer/corpus/42f8549e216d4fc4fb83ec37f4ef82e8d1804270
Binary files differ
diff --git a/fuzzer/corpus/42ff558e612d32805292e10e0d5588aff9ebfdb4 b/fuzzer/corpus/42ff558e612d32805292e10e0d5588aff9ebfdb4
new file mode 100644
index 0000000..0333076
--- /dev/null
+++ b/fuzzer/corpus/42ff558e612d32805292e10e0d5588aff9ebfdb4
Binary files differ
diff --git a/fuzzer/corpus/4311d53ab583253003762d5c6df248d9ad0b960d b/fuzzer/corpus/4311d53ab583253003762d5c6df248d9ad0b960d
new file mode 100644
index 0000000..2fa54c4
--- /dev/null
+++ b/fuzzer/corpus/4311d53ab583253003762d5c6df248d9ad0b960d
Binary files differ
diff --git a/fuzzer/corpus/431f6692d5d3b59cd7a4abf3f85e516309faaf23 b/fuzzer/corpus/431f6692d5d3b59cd7a4abf3f85e516309faaf23
new file mode 100644
index 0000000..61bec26
--- /dev/null
+++ b/fuzzer/corpus/431f6692d5d3b59cd7a4abf3f85e516309faaf23
Binary files differ
diff --git a/fuzzer/corpus/434b3aba4fb23b0a1dde7253ba6ce2e5b941280b b/fuzzer/corpus/434b3aba4fb23b0a1dde7253ba6ce2e5b941280b
new file mode 100644
index 0000000..e2743ec
--- /dev/null
+++ b/fuzzer/corpus/434b3aba4fb23b0a1dde7253ba6ce2e5b941280b
Binary files differ
diff --git a/fuzzer/corpus/43620b48bdc38c25d3301b1ee5f42aaa9fa22458 b/fuzzer/corpus/43620b48bdc38c25d3301b1ee5f42aaa9fa22458
new file mode 100644
index 0000000..0819663
--- /dev/null
+++ b/fuzzer/corpus/43620b48bdc38c25d3301b1ee5f42aaa9fa22458
Binary files differ
diff --git a/fuzzer/corpus/438a00f2bd6fe62fd7ecaf1d01add57dd249b5d8 b/fuzzer/corpus/438a00f2bd6fe62fd7ecaf1d01add57dd249b5d8
new file mode 100644
index 0000000..c52e37d
--- /dev/null
+++ b/fuzzer/corpus/438a00f2bd6fe62fd7ecaf1d01add57dd249b5d8
Binary files differ
diff --git a/fuzzer/corpus/43a04de428dc347375915abd1f32c95b14e07b9c b/fuzzer/corpus/43a04de428dc347375915abd1f32c95b14e07b9c
new file mode 100644
index 0000000..b661f90
--- /dev/null
+++ b/fuzzer/corpus/43a04de428dc347375915abd1f32c95b14e07b9c
Binary files differ
diff --git a/fuzzer/corpus/43a7dac2f22ed58d151d379f1a69492d15c4e4ec b/fuzzer/corpus/43a7dac2f22ed58d151d379f1a69492d15c4e4ec
new file mode 100644
index 0000000..b931e18
--- /dev/null
+++ b/fuzzer/corpus/43a7dac2f22ed58d151d379f1a69492d15c4e4ec
Binary files differ
diff --git a/fuzzer/corpus/43ab74cc4f5ecacf3a38572f954ed0388ecfd83c b/fuzzer/corpus/43ab74cc4f5ecacf3a38572f954ed0388ecfd83c
new file mode 100644
index 0000000..5a66813
--- /dev/null
+++ b/fuzzer/corpus/43ab74cc4f5ecacf3a38572f954ed0388ecfd83c
Binary files differ
diff --git a/fuzzer/corpus/43b16532811ba3ce84bd06113126a8e6230bc4e6 b/fuzzer/corpus/43b16532811ba3ce84bd06113126a8e6230bc4e6
new file mode 100644
index 0000000..8445b85
--- /dev/null
+++ b/fuzzer/corpus/43b16532811ba3ce84bd06113126a8e6230bc4e6
Binary files differ
diff --git a/fuzzer/corpus/43c65bc15f4c93adbb6bc2186d02d6d96946ae4b b/fuzzer/corpus/43c65bc15f4c93adbb6bc2186d02d6d96946ae4b
new file mode 100644
index 0000000..1e4ee00
--- /dev/null
+++ b/fuzzer/corpus/43c65bc15f4c93adbb6bc2186d02d6d96946ae4b
Binary files differ
diff --git a/fuzzer/corpus/43ccd4b004b8eba10b7981b649f41c212c7aef14 b/fuzzer/corpus/43ccd4b004b8eba10b7981b649f41c212c7aef14
new file mode 100644
index 0000000..55b425f
--- /dev/null
+++ b/fuzzer/corpus/43ccd4b004b8eba10b7981b649f41c212c7aef14
Binary files differ
diff --git a/fuzzer/corpus/43d0462689d206942c50b10018c5f2667afcaf9b b/fuzzer/corpus/43d0462689d206942c50b10018c5f2667afcaf9b
new file mode 100644
index 0000000..982184a
--- /dev/null
+++ b/fuzzer/corpus/43d0462689d206942c50b10018c5f2667afcaf9b
Binary files differ
diff --git a/fuzzer/corpus/44268627072b273b31866855e3d89a46db4c5993 b/fuzzer/corpus/44268627072b273b31866855e3d89a46db4c5993
new file mode 100644
index 0000000..b6d8210
--- /dev/null
+++ b/fuzzer/corpus/44268627072b273b31866855e3d89a46db4c5993
Binary files differ
diff --git a/fuzzer/corpus/442e7ba06aed4a44c6c60743ed6263a4c154dcc8 b/fuzzer/corpus/442e7ba06aed4a44c6c60743ed6263a4c154dcc8
new file mode 100644
index 0000000..30cb516
--- /dev/null
+++ b/fuzzer/corpus/442e7ba06aed4a44c6c60743ed6263a4c154dcc8
Binary files differ
diff --git a/fuzzer/corpus/446fbac27ea656dec4a21c616db79a6c45487ee3 b/fuzzer/corpus/446fbac27ea656dec4a21c616db79a6c45487ee3
new file mode 100644
index 0000000..b0469ac
--- /dev/null
+++ b/fuzzer/corpus/446fbac27ea656dec4a21c616db79a6c45487ee3
Binary files differ
diff --git a/fuzzer/corpus/4484889954c72cdccaea7a64af2a633d6efd9e82 b/fuzzer/corpus/4484889954c72cdccaea7a64af2a633d6efd9e82
new file mode 100644
index 0000000..3f8c999
--- /dev/null
+++ b/fuzzer/corpus/4484889954c72cdccaea7a64af2a633d6efd9e82
Binary files differ
diff --git a/fuzzer/corpus/44be8f2ae55fde174ac024caa7ab85037c4c6700 b/fuzzer/corpus/44be8f2ae55fde174ac024caa7ab85037c4c6700
new file mode 100644
index 0000000..c4c695f
--- /dev/null
+++ b/fuzzer/corpus/44be8f2ae55fde174ac024caa7ab85037c4c6700
Binary files differ
diff --git a/fuzzer/corpus/44ef353cd648470e438ce3405416d834dd75eece b/fuzzer/corpus/44ef353cd648470e438ce3405416d834dd75eece
new file mode 100644
index 0000000..b989e0f
--- /dev/null
+++ b/fuzzer/corpus/44ef353cd648470e438ce3405416d834dd75eece
Binary files differ
diff --git a/fuzzer/corpus/44f08b3d0f7edb74975426e4cd064027a885c576 b/fuzzer/corpus/44f08b3d0f7edb74975426e4cd064027a885c576
new file mode 100644
index 0000000..74d147e
--- /dev/null
+++ b/fuzzer/corpus/44f08b3d0f7edb74975426e4cd064027a885c576
Binary files differ
diff --git a/fuzzer/corpus/452f898e13f1b1a7096f7b7356ba805fd44e0a16 b/fuzzer/corpus/452f898e13f1b1a7096f7b7356ba805fd44e0a16
new file mode 100644
index 0000000..cbd18d6
--- /dev/null
+++ b/fuzzer/corpus/452f898e13f1b1a7096f7b7356ba805fd44e0a16
Binary files differ
diff --git a/fuzzer/corpus/456a4b84afd1e87dd2949a80e6b7de5532369daa b/fuzzer/corpus/456a4b84afd1e87dd2949a80e6b7de5532369daa
new file mode 100644
index 0000000..f3c3ba8
--- /dev/null
+++ b/fuzzer/corpus/456a4b84afd1e87dd2949a80e6b7de5532369daa
Binary files differ
diff --git a/fuzzer/corpus/456e5aba481e9494480dfe0e30103d7a371c36f0 b/fuzzer/corpus/456e5aba481e9494480dfe0e30103d7a371c36f0
new file mode 100644
index 0000000..90f2696
--- /dev/null
+++ b/fuzzer/corpus/456e5aba481e9494480dfe0e30103d7a371c36f0
Binary files differ
diff --git a/fuzzer/corpus/4573539cd102309a639d6efa7fb372db109f1c47 b/fuzzer/corpus/4573539cd102309a639d6efa7fb372db109f1c47
new file mode 100644
index 0000000..52a1efb
--- /dev/null
+++ b/fuzzer/corpus/4573539cd102309a639d6efa7fb372db109f1c47
Binary files differ
diff --git a/fuzzer/corpus/4580abd8e820990bcb6c9ba78bfca0aa3a0319ef b/fuzzer/corpus/4580abd8e820990bcb6c9ba78bfca0aa3a0319ef
new file mode 100644
index 0000000..12b188a
--- /dev/null
+++ b/fuzzer/corpus/4580abd8e820990bcb6c9ba78bfca0aa3a0319ef
Binary files differ
diff --git a/fuzzer/corpus/4580e371e8fbd69e47e02fa19e675785c501c989 b/fuzzer/corpus/4580e371e8fbd69e47e02fa19e675785c501c989
new file mode 100644
index 0000000..e3b7139
--- /dev/null
+++ b/fuzzer/corpus/4580e371e8fbd69e47e02fa19e675785c501c989
Binary files differ
diff --git a/fuzzer/corpus/4596b3e125384fd6616fe9a21c2d84a9e9146b02 b/fuzzer/corpus/4596b3e125384fd6616fe9a21c2d84a9e9146b02
new file mode 100644
index 0000000..15da728
--- /dev/null
+++ b/fuzzer/corpus/4596b3e125384fd6616fe9a21c2d84a9e9146b02
Binary files differ
diff --git a/fuzzer/corpus/45ad3957454b75c5ffd4b38e42f830a3ce2ddb58 b/fuzzer/corpus/45ad3957454b75c5ffd4b38e42f830a3ce2ddb58
new file mode 100644
index 0000000..d4b5ecb
--- /dev/null
+++ b/fuzzer/corpus/45ad3957454b75c5ffd4b38e42f830a3ce2ddb58
Binary files differ
diff --git a/fuzzer/corpus/45b1bb3f7e17a0449d0632c3014196ce57acdf4b b/fuzzer/corpus/45b1bb3f7e17a0449d0632c3014196ce57acdf4b
new file mode 100644
index 0000000..44a8013
--- /dev/null
+++ b/fuzzer/corpus/45b1bb3f7e17a0449d0632c3014196ce57acdf4b
Binary files differ
diff --git a/fuzzer/corpus/45d30863d34d0525446a92da17db464e08f14742 b/fuzzer/corpus/45d30863d34d0525446a92da17db464e08f14742
new file mode 100644
index 0000000..19c36c9
--- /dev/null
+++ b/fuzzer/corpus/45d30863d34d0525446a92da17db464e08f14742
Binary files differ
diff --git a/fuzzer/corpus/45e5313feec6e4f72bbb7115729571402922d931 b/fuzzer/corpus/45e5313feec6e4f72bbb7115729571402922d931
new file mode 100644
index 0000000..6d7dc4d
--- /dev/null
+++ b/fuzzer/corpus/45e5313feec6e4f72bbb7115729571402922d931
Binary files differ
diff --git a/fuzzer/corpus/45fa6f391ca41c78ce36d4626c6b1ac7016e3c13 b/fuzzer/corpus/45fa6f391ca41c78ce36d4626c6b1ac7016e3c13
new file mode 100644
index 0000000..fcfa66c
--- /dev/null
+++ b/fuzzer/corpus/45fa6f391ca41c78ce36d4626c6b1ac7016e3c13
Binary files differ
diff --git a/fuzzer/corpus/45fb88e3f3545891f75e3ef9c16e3ce4e1de331d b/fuzzer/corpus/45fb88e3f3545891f75e3ef9c16e3ce4e1de331d
new file mode 100644
index 0000000..b539f62
--- /dev/null
+++ b/fuzzer/corpus/45fb88e3f3545891f75e3ef9c16e3ce4e1de331d
Binary files differ
diff --git a/fuzzer/corpus/46058ec8608adad0ecd5495eb19e52ccbf96058e b/fuzzer/corpus/46058ec8608adad0ecd5495eb19e52ccbf96058e
new file mode 100644
index 0000000..199cfbd
--- /dev/null
+++ b/fuzzer/corpus/46058ec8608adad0ecd5495eb19e52ccbf96058e
Binary files differ
diff --git a/fuzzer/corpus/462629b211c9a20ad7d076b9fe1c8f223c02b980 b/fuzzer/corpus/462629b211c9a20ad7d076b9fe1c8f223c02b980
new file mode 100644
index 0000000..81b38e3
--- /dev/null
+++ b/fuzzer/corpus/462629b211c9a20ad7d076b9fe1c8f223c02b980
Binary files differ
diff --git a/fuzzer/corpus/4639b78e734ba41929677b69493804b8bbc7d2e7 b/fuzzer/corpus/4639b78e734ba41929677b69493804b8bbc7d2e7
new file mode 100644
index 0000000..132c8d6
--- /dev/null
+++ b/fuzzer/corpus/4639b78e734ba41929677b69493804b8bbc7d2e7
Binary files differ
diff --git a/fuzzer/corpus/464840724f0b6c8590dbc07ec6c5591248351ec2 b/fuzzer/corpus/464840724f0b6c8590dbc07ec6c5591248351ec2
new file mode 100644
index 0000000..684d134
--- /dev/null
+++ b/fuzzer/corpus/464840724f0b6c8590dbc07ec6c5591248351ec2
Binary files differ
diff --git a/fuzzer/corpus/465301866d547cf0c589fcb3e75703ce5913de47 b/fuzzer/corpus/465301866d547cf0c589fcb3e75703ce5913de47
new file mode 100644
index 0000000..63a72d3
--- /dev/null
+++ b/fuzzer/corpus/465301866d547cf0c589fcb3e75703ce5913de47
Binary files differ
diff --git a/fuzzer/corpus/46a911b5776c3eb28cdff0d6cd72df92387528b0 b/fuzzer/corpus/46a911b5776c3eb28cdff0d6cd72df92387528b0
new file mode 100644
index 0000000..b8a435d
--- /dev/null
+++ b/fuzzer/corpus/46a911b5776c3eb28cdff0d6cd72df92387528b0
Binary files differ
diff --git a/fuzzer/corpus/4702789fc04046636f32d326f926dc29b7d407f6 b/fuzzer/corpus/4702789fc04046636f32d326f926dc29b7d407f6
new file mode 100644
index 0000000..83e4536
--- /dev/null
+++ b/fuzzer/corpus/4702789fc04046636f32d326f926dc29b7d407f6
Binary files differ
diff --git a/fuzzer/corpus/4704a9ae384ff7aa7883898660e6504ae1dceabe b/fuzzer/corpus/4704a9ae384ff7aa7883898660e6504ae1dceabe
new file mode 100644
index 0000000..f3a1a41
--- /dev/null
+++ b/fuzzer/corpus/4704a9ae384ff7aa7883898660e6504ae1dceabe
Binary files differ
diff --git a/fuzzer/corpus/472b029f7805fc89e06be91239b3fadd74603e52 b/fuzzer/corpus/472b029f7805fc89e06be91239b3fadd74603e52
new file mode 100644
index 0000000..32b2915
--- /dev/null
+++ b/fuzzer/corpus/472b029f7805fc89e06be91239b3fadd74603e52
Binary files differ
diff --git a/fuzzer/corpus/474aa41a3d0eab350d75f7a6b112f0c78c0d0d21 b/fuzzer/corpus/474aa41a3d0eab350d75f7a6b112f0c78c0d0d21
new file mode 100644
index 0000000..47cdafd
--- /dev/null
+++ b/fuzzer/corpus/474aa41a3d0eab350d75f7a6b112f0c78c0d0d21
Binary files differ
diff --git a/fuzzer/corpus/475e9680116fad7e0b31d31ffae25bace7d0c5c2 b/fuzzer/corpus/475e9680116fad7e0b31d31ffae25bace7d0c5c2
new file mode 100644
index 0000000..5c2a606
--- /dev/null
+++ b/fuzzer/corpus/475e9680116fad7e0b31d31ffae25bace7d0c5c2
Binary files differ
diff --git a/fuzzer/corpus/4761baf77c06ed60f43ce3742ba3eca60cd3bb7b b/fuzzer/corpus/4761baf77c06ed60f43ce3742ba3eca60cd3bb7b
new file mode 100644
index 0000000..02fab4d
--- /dev/null
+++ b/fuzzer/corpus/4761baf77c06ed60f43ce3742ba3eca60cd3bb7b
Binary files differ
diff --git a/fuzzer/corpus/4766e711be17c18a4c6d8398d2c8337c270a90a4 b/fuzzer/corpus/4766e711be17c18a4c6d8398d2c8337c270a90a4
new file mode 100644
index 0000000..45c0b40
--- /dev/null
+++ b/fuzzer/corpus/4766e711be17c18a4c6d8398d2c8337c270a90a4
Binary files differ
diff --git a/fuzzer/corpus/47a1282ecb3d35237e7c7fd8dc1429698af11b39 b/fuzzer/corpus/47a1282ecb3d35237e7c7fd8dc1429698af11b39
new file mode 100644
index 0000000..35930ca
--- /dev/null
+++ b/fuzzer/corpus/47a1282ecb3d35237e7c7fd8dc1429698af11b39
Binary files differ
diff --git a/fuzzer/corpus/47caed181903c894531eb2e19c44c2d2b76fd6fd b/fuzzer/corpus/47caed181903c894531eb2e19c44c2d2b76fd6fd
new file mode 100644
index 0000000..d07e469
--- /dev/null
+++ b/fuzzer/corpus/47caed181903c894531eb2e19c44c2d2b76fd6fd
Binary files differ
diff --git a/fuzzer/corpus/47d8da30683459a8a20f3bef9ab28bee627eeac1 b/fuzzer/corpus/47d8da30683459a8a20f3bef9ab28bee627eeac1
new file mode 100644
index 0000000..189a716
--- /dev/null
+++ b/fuzzer/corpus/47d8da30683459a8a20f3bef9ab28bee627eeac1
Binary files differ
diff --git a/fuzzer/corpus/481fe58bfa684ed3e01059d2f6b613ab0edf7c17 b/fuzzer/corpus/481fe58bfa684ed3e01059d2f6b613ab0edf7c17
new file mode 100644
index 0000000..23db1f4
--- /dev/null
+++ b/fuzzer/corpus/481fe58bfa684ed3e01059d2f6b613ab0edf7c17
Binary files differ
diff --git a/fuzzer/corpus/48936ec5fdcca6e2d54051d2b5e2943e2894f2ef b/fuzzer/corpus/48936ec5fdcca6e2d54051d2b5e2943e2894f2ef
new file mode 100644
index 0000000..a2a0c4a
--- /dev/null
+++ b/fuzzer/corpus/48936ec5fdcca6e2d54051d2b5e2943e2894f2ef
Binary files differ
diff --git a/fuzzer/corpus/4895768f927ac10572d9ede5d3bdd301ffdc8ff4 b/fuzzer/corpus/4895768f927ac10572d9ede5d3bdd301ffdc8ff4
new file mode 100644
index 0000000..59a2c02
--- /dev/null
+++ b/fuzzer/corpus/4895768f927ac10572d9ede5d3bdd301ffdc8ff4
Binary files differ
diff --git a/fuzzer/corpus/48ec9ee1da218d48c07791145a7082d619a8e91e b/fuzzer/corpus/48ec9ee1da218d48c07791145a7082d619a8e91e
new file mode 100644
index 0000000..ae7659c
--- /dev/null
+++ b/fuzzer/corpus/48ec9ee1da218d48c07791145a7082d619a8e91e
Binary files differ
diff --git a/fuzzer/corpus/492c4cc59923d3323c34d620755f49db08a1287b b/fuzzer/corpus/492c4cc59923d3323c34d620755f49db08a1287b
new file mode 100644
index 0000000..dabf1ea
--- /dev/null
+++ b/fuzzer/corpus/492c4cc59923d3323c34d620755f49db08a1287b
Binary files differ
diff --git a/fuzzer/corpus/492db680886a5f6596808da294e4f55793c3d78b b/fuzzer/corpus/492db680886a5f6596808da294e4f55793c3d78b
new file mode 100644
index 0000000..fb87805
--- /dev/null
+++ b/fuzzer/corpus/492db680886a5f6596808da294e4f55793c3d78b
Binary files differ
diff --git a/fuzzer/corpus/494f88aaf4b5b8af268d6544b453ed46bd656e7d b/fuzzer/corpus/494f88aaf4b5b8af268d6544b453ed46bd656e7d
new file mode 100644
index 0000000..68694ca
--- /dev/null
+++ b/fuzzer/corpus/494f88aaf4b5b8af268d6544b453ed46bd656e7d
Binary files differ
diff --git a/fuzzer/corpus/4966309a70277b9c5588b56c0cd160039a17b3f2 b/fuzzer/corpus/4966309a70277b9c5588b56c0cd160039a17b3f2
new file mode 100644
index 0000000..e0a13d8
--- /dev/null
+++ b/fuzzer/corpus/4966309a70277b9c5588b56c0cd160039a17b3f2
Binary files differ
diff --git a/fuzzer/corpus/49808e0f614be22eea31e052f23741e0d28fe1e4 b/fuzzer/corpus/49808e0f614be22eea31e052f23741e0d28fe1e4
new file mode 100644
index 0000000..1adb232
--- /dev/null
+++ b/fuzzer/corpus/49808e0f614be22eea31e052f23741e0d28fe1e4
Binary files differ
diff --git a/fuzzer/corpus/49a59eea737e131cb4d706b30843d8e8a025d2d1 b/fuzzer/corpus/49a59eea737e131cb4d706b30843d8e8a025d2d1
new file mode 100644
index 0000000..49e5d3b
--- /dev/null
+++ b/fuzzer/corpus/49a59eea737e131cb4d706b30843d8e8a025d2d1
Binary files differ
diff --git a/fuzzer/corpus/49ad6606238e6a58ad8d79088492aaead6c32e6b b/fuzzer/corpus/49ad6606238e6a58ad8d79088492aaead6c32e6b
new file mode 100644
index 0000000..341665f
--- /dev/null
+++ b/fuzzer/corpus/49ad6606238e6a58ad8d79088492aaead6c32e6b
Binary files differ
diff --git a/fuzzer/corpus/49b49874138ada8be9f6ce4be49ef37e4fc2c50a b/fuzzer/corpus/49b49874138ada8be9f6ce4be49ef37e4fc2c50a
new file mode 100644
index 0000000..cf75f18
--- /dev/null
+++ b/fuzzer/corpus/49b49874138ada8be9f6ce4be49ef37e4fc2c50a
Binary files differ
diff --git a/fuzzer/corpus/4a0b5ed9b9184687f0350584abb89ba3cd3b6260 b/fuzzer/corpus/4a0b5ed9b9184687f0350584abb89ba3cd3b6260
new file mode 100644
index 0000000..8517242
--- /dev/null
+++ b/fuzzer/corpus/4a0b5ed9b9184687f0350584abb89ba3cd3b6260
Binary files differ
diff --git a/fuzzer/corpus/4a3c9992ceb5151e25867043cff3b70b0615975a b/fuzzer/corpus/4a3c9992ceb5151e25867043cff3b70b0615975a
new file mode 100644
index 0000000..79e710c
--- /dev/null
+++ b/fuzzer/corpus/4a3c9992ceb5151e25867043cff3b70b0615975a
Binary files differ
diff --git a/fuzzer/corpus/4a5d59b9bbf454e26e5b8da35934fbe5e56cd5e3 b/fuzzer/corpus/4a5d59b9bbf454e26e5b8da35934fbe5e56cd5e3
new file mode 100644
index 0000000..d4a051a
--- /dev/null
+++ b/fuzzer/corpus/4a5d59b9bbf454e26e5b8da35934fbe5e56cd5e3
Binary files differ
diff --git a/fuzzer/corpus/4a6bf78cf8487aaf4dc9504f580290c58cd3865d b/fuzzer/corpus/4a6bf78cf8487aaf4dc9504f580290c58cd3865d
new file mode 100644
index 0000000..22d2ce0
--- /dev/null
+++ b/fuzzer/corpus/4a6bf78cf8487aaf4dc9504f580290c58cd3865d
Binary files differ
diff --git a/fuzzer/corpus/4a8b6c80b64fa974b7a5f514ea78291aff7267c9 b/fuzzer/corpus/4a8b6c80b64fa974b7a5f514ea78291aff7267c9
new file mode 100644
index 0000000..93a1f6d
--- /dev/null
+++ b/fuzzer/corpus/4a8b6c80b64fa974b7a5f514ea78291aff7267c9
Binary files differ
diff --git a/fuzzer/corpus/4ace626cc3e3115df77d85a5c313b24e3a2d2695 b/fuzzer/corpus/4ace626cc3e3115df77d85a5c313b24e3a2d2695
new file mode 100644
index 0000000..9262dd3
--- /dev/null
+++ b/fuzzer/corpus/4ace626cc3e3115df77d85a5c313b24e3a2d2695
Binary files differ
diff --git a/fuzzer/corpus/4b108731bb41e672ad5c98713f0250e026616d2c b/fuzzer/corpus/4b108731bb41e672ad5c98713f0250e026616d2c
new file mode 100644
index 0000000..fe1d49f
--- /dev/null
+++ b/fuzzer/corpus/4b108731bb41e672ad5c98713f0250e026616d2c
Binary files differ
diff --git a/fuzzer/corpus/4b1e095f3fec59b21d71f93800e6b57e3f70cf35 b/fuzzer/corpus/4b1e095f3fec59b21d71f93800e6b57e3f70cf35
new file mode 100644
index 0000000..4bcbcc7
--- /dev/null
+++ b/fuzzer/corpus/4b1e095f3fec59b21d71f93800e6b57e3f70cf35
Binary files differ
diff --git a/fuzzer/corpus/4b6d6914f78e22b64597583a9226be7526e73397 b/fuzzer/corpus/4b6d6914f78e22b64597583a9226be7526e73397
new file mode 100644
index 0000000..dcf8006
--- /dev/null
+++ b/fuzzer/corpus/4b6d6914f78e22b64597583a9226be7526e73397
Binary files differ
diff --git a/fuzzer/corpus/4b8afa2b5592ef534919776fb45430967d939775 b/fuzzer/corpus/4b8afa2b5592ef534919776fb45430967d939775
new file mode 100644
index 0000000..606ae9c
--- /dev/null
+++ b/fuzzer/corpus/4b8afa2b5592ef534919776fb45430967d939775
Binary files differ
diff --git a/fuzzer/corpus/4b8e8b45144512387e4c6a3fa6b131170564ca57 b/fuzzer/corpus/4b8e8b45144512387e4c6a3fa6b131170564ca57
new file mode 100644
index 0000000..93a7ac3
--- /dev/null
+++ b/fuzzer/corpus/4b8e8b45144512387e4c6a3fa6b131170564ca57
Binary files differ
diff --git a/fuzzer/corpus/4b9f834b48b7fc4252cbf27c7a86e7438b11fe98 b/fuzzer/corpus/4b9f834b48b7fc4252cbf27c7a86e7438b11fe98
new file mode 100644
index 0000000..6eac407
--- /dev/null
+++ b/fuzzer/corpus/4b9f834b48b7fc4252cbf27c7a86e7438b11fe98
Binary files differ
diff --git a/fuzzer/corpus/4bb28aaf30e244c6270e338f040d5f0328680be6 b/fuzzer/corpus/4bb28aaf30e244c6270e338f040d5f0328680be6
new file mode 100644
index 0000000..dc880ba
--- /dev/null
+++ b/fuzzer/corpus/4bb28aaf30e244c6270e338f040d5f0328680be6
Binary files differ
diff --git a/fuzzer/corpus/4bc35a79dc6599fc0cfbcd77712d7c98c253222c b/fuzzer/corpus/4bc35a79dc6599fc0cfbcd77712d7c98c253222c
new file mode 100644
index 0000000..470dfc7
--- /dev/null
+++ b/fuzzer/corpus/4bc35a79dc6599fc0cfbcd77712d7c98c253222c
Binary files differ
diff --git a/fuzzer/corpus/4bf138f9eb681100aea715ea17431f737857743c b/fuzzer/corpus/4bf138f9eb681100aea715ea17431f737857743c
new file mode 100644
index 0000000..f2a5b2d
--- /dev/null
+++ b/fuzzer/corpus/4bf138f9eb681100aea715ea17431f737857743c
Binary files differ
diff --git a/fuzzer/corpus/4bf43cac903b57260989e5fa2fe06812eabbc932 b/fuzzer/corpus/4bf43cac903b57260989e5fa2fe06812eabbc932
new file mode 100644
index 0000000..58e3210
--- /dev/null
+++ b/fuzzer/corpus/4bf43cac903b57260989e5fa2fe06812eabbc932
Binary files differ
diff --git a/fuzzer/corpus/4bfc7f56dcd681c4cb0ac7564c9202ecb957c411 b/fuzzer/corpus/4bfc7f56dcd681c4cb0ac7564c9202ecb957c411
new file mode 100644
index 0000000..4ed8ede
--- /dev/null
+++ b/fuzzer/corpus/4bfc7f56dcd681c4cb0ac7564c9202ecb957c411
Binary files differ
diff --git a/fuzzer/corpus/4c2efcd1ba3a6c5b4363ccbf8ef4b5b9b1703a9a b/fuzzer/corpus/4c2efcd1ba3a6c5b4363ccbf8ef4b5b9b1703a9a
new file mode 100644
index 0000000..8904492
--- /dev/null
+++ b/fuzzer/corpus/4c2efcd1ba3a6c5b4363ccbf8ef4b5b9b1703a9a
Binary files differ
diff --git a/fuzzer/corpus/4c4b0bc074912f4c7b56b8e410e182f2337061d5 b/fuzzer/corpus/4c4b0bc074912f4c7b56b8e410e182f2337061d5
new file mode 100644
index 0000000..a269b20
--- /dev/null
+++ b/fuzzer/corpus/4c4b0bc074912f4c7b56b8e410e182f2337061d5
Binary files differ
diff --git a/fuzzer/corpus/4c5426c031fcd5aebd60c559cca78d725222b4d1 b/fuzzer/corpus/4c5426c031fcd5aebd60c559cca78d725222b4d1
new file mode 100644
index 0000000..0ed228f
--- /dev/null
+++ b/fuzzer/corpus/4c5426c031fcd5aebd60c559cca78d725222b4d1
Binary files differ
diff --git a/fuzzer/corpus/4c63c52327e53cb7ec69e322c3e5e4d16d127c13 b/fuzzer/corpus/4c63c52327e53cb7ec69e322c3e5e4d16d127c13
new file mode 100644
index 0000000..740b379
--- /dev/null
+++ b/fuzzer/corpus/4c63c52327e53cb7ec69e322c3e5e4d16d127c13
Binary files differ
diff --git a/fuzzer/corpus/4c6e73b844b72584d3fd49553db60e9a8c8af22f b/fuzzer/corpus/4c6e73b844b72584d3fd49553db60e9a8c8af22f
new file mode 100644
index 0000000..b8f9441
--- /dev/null
+++ b/fuzzer/corpus/4c6e73b844b72584d3fd49553db60e9a8c8af22f
Binary files differ
diff --git a/fuzzer/corpus/4c8426e1c7917411b91516c601b15c344c5adbf6 b/fuzzer/corpus/4c8426e1c7917411b91516c601b15c344c5adbf6
new file mode 100644
index 0000000..02944f2
--- /dev/null
+++ b/fuzzer/corpus/4c8426e1c7917411b91516c601b15c344c5adbf6
Binary files differ
diff --git a/fuzzer/corpus/4c8c516495d0ebf82ba2e9cf13e50bf1870dad2a b/fuzzer/corpus/4c8c516495d0ebf82ba2e9cf13e50bf1870dad2a
new file mode 100644
index 0000000..6708d63
--- /dev/null
+++ b/fuzzer/corpus/4c8c516495d0ebf82ba2e9cf13e50bf1870dad2a
Binary files differ
diff --git a/fuzzer/corpus/4c91acd8996e220bd56bd35f88fe8552c233ddcf b/fuzzer/corpus/4c91acd8996e220bd56bd35f88fe8552c233ddcf
new file mode 100644
index 0000000..0221b96
--- /dev/null
+++ b/fuzzer/corpus/4c91acd8996e220bd56bd35f88fe8552c233ddcf
Binary files differ
diff --git a/fuzzer/corpus/4caf611587e949b11d2873a26ed09b9482b3f893 b/fuzzer/corpus/4caf611587e949b11d2873a26ed09b9482b3f893
new file mode 100644
index 0000000..fe03479
--- /dev/null
+++ b/fuzzer/corpus/4caf611587e949b11d2873a26ed09b9482b3f893
Binary files differ
diff --git a/fuzzer/corpus/4cd6f1e44b814d74bc5628a097736295f7db45b2 b/fuzzer/corpus/4cd6f1e44b814d74bc5628a097736295f7db45b2
new file mode 100644
index 0000000..10d9271
--- /dev/null
+++ b/fuzzer/corpus/4cd6f1e44b814d74bc5628a097736295f7db45b2
Binary files differ
diff --git a/fuzzer/corpus/4cee4f3d2d5cdca267340f62aba696d2e2b8fbc4 b/fuzzer/corpus/4cee4f3d2d5cdca267340f62aba696d2e2b8fbc4
new file mode 100644
index 0000000..35fe464
--- /dev/null
+++ b/fuzzer/corpus/4cee4f3d2d5cdca267340f62aba696d2e2b8fbc4
Binary files differ
diff --git a/fuzzer/corpus/4cee5e4e9f91bbb7378f83da87e3cbcdc198a790 b/fuzzer/corpus/4cee5e4e9f91bbb7378f83da87e3cbcdc198a790
new file mode 100644
index 0000000..d1e6ae6
--- /dev/null
+++ b/fuzzer/corpus/4cee5e4e9f91bbb7378f83da87e3cbcdc198a790
Binary files differ
diff --git a/fuzzer/corpus/4ceeb92459a82ce4a6045dd52f7a9523f38aea80 b/fuzzer/corpus/4ceeb92459a82ce4a6045dd52f7a9523f38aea80
new file mode 100644
index 0000000..c55b63e
--- /dev/null
+++ b/fuzzer/corpus/4ceeb92459a82ce4a6045dd52f7a9523f38aea80
Binary files differ
diff --git a/fuzzer/corpus/4d054e710f51b8c97c7a22cd1aac848aa2006612 b/fuzzer/corpus/4d054e710f51b8c97c7a22cd1aac848aa2006612
new file mode 100644
index 0000000..0bc55d6
--- /dev/null
+++ b/fuzzer/corpus/4d054e710f51b8c97c7a22cd1aac848aa2006612
Binary files differ
diff --git a/fuzzer/corpus/4d1c477534c42641c9b0b9a49f6c057e1cde7db4 b/fuzzer/corpus/4d1c477534c42641c9b0b9a49f6c057e1cde7db4
new file mode 100644
index 0000000..1f3076e
--- /dev/null
+++ b/fuzzer/corpus/4d1c477534c42641c9b0b9a49f6c057e1cde7db4
Binary files differ
diff --git a/fuzzer/corpus/4d49541f67c134d92a2703fc1e3637a35be8135b b/fuzzer/corpus/4d49541f67c134d92a2703fc1e3637a35be8135b
new file mode 100644
index 0000000..821f6a3
--- /dev/null
+++ b/fuzzer/corpus/4d49541f67c134d92a2703fc1e3637a35be8135b
Binary files differ
diff --git a/fuzzer/corpus/4dae34734a9e1f19378b8344110b583ee40f4e83 b/fuzzer/corpus/4dae34734a9e1f19378b8344110b583ee40f4e83
new file mode 100644
index 0000000..b080229
--- /dev/null
+++ b/fuzzer/corpus/4dae34734a9e1f19378b8344110b583ee40f4e83
Binary files differ
diff --git a/fuzzer/corpus/4dc314104fbcdd1e05b81d8a76db145121b1b464 b/fuzzer/corpus/4dc314104fbcdd1e05b81d8a76db145121b1b464
new file mode 100644
index 0000000..59684cf
--- /dev/null
+++ b/fuzzer/corpus/4dc314104fbcdd1e05b81d8a76db145121b1b464
Binary files differ
diff --git a/fuzzer/corpus/4e192a34709c41ec0ff89952d29d77143563f3f1 b/fuzzer/corpus/4e192a34709c41ec0ff89952d29d77143563f3f1
new file mode 100644
index 0000000..0ff40bb
--- /dev/null
+++ b/fuzzer/corpus/4e192a34709c41ec0ff89952d29d77143563f3f1
Binary files differ
diff --git a/fuzzer/corpus/4e87292c228f8738cbba6e08e7309aa7be7903e5 b/fuzzer/corpus/4e87292c228f8738cbba6e08e7309aa7be7903e5
new file mode 100644
index 0000000..2ae290a
--- /dev/null
+++ b/fuzzer/corpus/4e87292c228f8738cbba6e08e7309aa7be7903e5
Binary files differ
diff --git a/fuzzer/corpus/4e91084a57241b0a79a1e1017e469635285c8fd6 b/fuzzer/corpus/4e91084a57241b0a79a1e1017e469635285c8fd6
new file mode 100644
index 0000000..5a6a369
--- /dev/null
+++ b/fuzzer/corpus/4e91084a57241b0a79a1e1017e469635285c8fd6
Binary files differ
diff --git a/fuzzer/corpus/4eb13aab6d110ba031cf58579a3aa65d196a177d b/fuzzer/corpus/4eb13aab6d110ba031cf58579a3aa65d196a177d
new file mode 100644
index 0000000..5b15d2a
--- /dev/null
+++ b/fuzzer/corpus/4eb13aab6d110ba031cf58579a3aa65d196a177d
Binary files differ
diff --git a/fuzzer/corpus/4f0d2ded2ea1fb09399d5baf8d0426fef5ee932a b/fuzzer/corpus/4f0d2ded2ea1fb09399d5baf8d0426fef5ee932a
new file mode 100644
index 0000000..aaac3ff
--- /dev/null
+++ b/fuzzer/corpus/4f0d2ded2ea1fb09399d5baf8d0426fef5ee932a
Binary files differ
diff --git a/fuzzer/corpus/4f0e3f83c981ba7b753340d23f7f5543ddb36ee5 b/fuzzer/corpus/4f0e3f83c981ba7b753340d23f7f5543ddb36ee5
new file mode 100644
index 0000000..bdded5e
--- /dev/null
+++ b/fuzzer/corpus/4f0e3f83c981ba7b753340d23f7f5543ddb36ee5
Binary files differ
diff --git a/fuzzer/corpus/4f31000f5101f0168e01a3c0f98d5bcb12300e66 b/fuzzer/corpus/4f31000f5101f0168e01a3c0f98d5bcb12300e66
new file mode 100644
index 0000000..1115213
--- /dev/null
+++ b/fuzzer/corpus/4f31000f5101f0168e01a3c0f98d5bcb12300e66
Binary files differ
diff --git a/fuzzer/corpus/4f5021168e063c367a32ba82304c09fd8144065e b/fuzzer/corpus/4f5021168e063c367a32ba82304c09fd8144065e
new file mode 100644
index 0000000..5a2d223
--- /dev/null
+++ b/fuzzer/corpus/4f5021168e063c367a32ba82304c09fd8144065e
Binary files differ
diff --git a/fuzzer/corpus/4f516f048cf57bc27abda74d5ed7ed85ea43806d b/fuzzer/corpus/4f516f048cf57bc27abda74d5ed7ed85ea43806d
new file mode 100644
index 0000000..5aa3538
--- /dev/null
+++ b/fuzzer/corpus/4f516f048cf57bc27abda74d5ed7ed85ea43806d
Binary files differ
diff --git a/fuzzer/corpus/4f6c0d8cc12b50e35b0007d6d24a7320c22c92e7 b/fuzzer/corpus/4f6c0d8cc12b50e35b0007d6d24a7320c22c92e7
new file mode 100644
index 0000000..5d5d3c7
--- /dev/null
+++ b/fuzzer/corpus/4f6c0d8cc12b50e35b0007d6d24a7320c22c92e7
Binary files differ
diff --git a/fuzzer/corpus/4fa8b27a309641f206e149b137988ef92b57af15 b/fuzzer/corpus/4fa8b27a309641f206e149b137988ef92b57af15
new file mode 100644
index 0000000..0f68738
--- /dev/null
+++ b/fuzzer/corpus/4fa8b27a309641f206e149b137988ef92b57af15
Binary files differ
diff --git a/fuzzer/corpus/4fb887ac3b5beb5ceb252e42134f064fbc645234 b/fuzzer/corpus/4fb887ac3b5beb5ceb252e42134f064fbc645234
new file mode 100644
index 0000000..09cb6fc
--- /dev/null
+++ b/fuzzer/corpus/4fb887ac3b5beb5ceb252e42134f064fbc645234
Binary files differ
diff --git a/fuzzer/corpus/4fb8accd2d976661f63fd26140a3f6b82934a253 b/fuzzer/corpus/4fb8accd2d976661f63fd26140a3f6b82934a253
new file mode 100644
index 0000000..7237c9f
--- /dev/null
+++ b/fuzzer/corpus/4fb8accd2d976661f63fd26140a3f6b82934a253
Binary files differ
diff --git a/fuzzer/corpus/4fba302e5ab0006c79bc187f414c1f2508c21bcc b/fuzzer/corpus/4fba302e5ab0006c79bc187f414c1f2508c21bcc
new file mode 100644
index 0000000..4a3ac61
--- /dev/null
+++ b/fuzzer/corpus/4fba302e5ab0006c79bc187f414c1f2508c21bcc
Binary files differ
diff --git a/fuzzer/corpus/4fc051a19cebce0a9fa46fd3086d296d1ce4f768 b/fuzzer/corpus/4fc051a19cebce0a9fa46fd3086d296d1ce4f768
new file mode 100644
index 0000000..a72fdb1
--- /dev/null
+++ b/fuzzer/corpus/4fc051a19cebce0a9fa46fd3086d296d1ce4f768
Binary files differ
diff --git a/fuzzer/corpus/4fc0c97126d20173535a93372152b8ccc353923b b/fuzzer/corpus/4fc0c97126d20173535a93372152b8ccc353923b
new file mode 100644
index 0000000..e27897a
--- /dev/null
+++ b/fuzzer/corpus/4fc0c97126d20173535a93372152b8ccc353923b
Binary files differ
diff --git a/fuzzer/corpus/4ffa879630136e59cc52c1bdf983dc82627a6ab5 b/fuzzer/corpus/4ffa879630136e59cc52c1bdf983dc82627a6ab5
new file mode 100644
index 0000000..6eda41f
--- /dev/null
+++ b/fuzzer/corpus/4ffa879630136e59cc52c1bdf983dc82627a6ab5
Binary files differ
diff --git a/fuzzer/corpus/503fa851d5bfe40f5a30ad59c26118790cad5e01 b/fuzzer/corpus/503fa851d5bfe40f5a30ad59c26118790cad5e01
new file mode 100644
index 0000000..7ec917a
--- /dev/null
+++ b/fuzzer/corpus/503fa851d5bfe40f5a30ad59c26118790cad5e01
Binary files differ
diff --git a/fuzzer/corpus/5066166ab1196da51226b9c132a6f0c7c1cbe22b b/fuzzer/corpus/5066166ab1196da51226b9c132a6f0c7c1cbe22b
new file mode 100644
index 0000000..6d42b83
--- /dev/null
+++ b/fuzzer/corpus/5066166ab1196da51226b9c132a6f0c7c1cbe22b
Binary files differ
diff --git a/fuzzer/corpus/507021a3175cadd66970ba070a29878ed6520f23 b/fuzzer/corpus/507021a3175cadd66970ba070a29878ed6520f23
new file mode 100644
index 0000000..dd143d4
--- /dev/null
+++ b/fuzzer/corpus/507021a3175cadd66970ba070a29878ed6520f23
Binary files differ
diff --git a/fuzzer/corpus/50bd31f8a41c5c705594112b9329b6ec3eab6f10 b/fuzzer/corpus/50bd31f8a41c5c705594112b9329b6ec3eab6f10
new file mode 100644
index 0000000..5e9a129
--- /dev/null
+++ b/fuzzer/corpus/50bd31f8a41c5c705594112b9329b6ec3eab6f10
Binary files differ
diff --git a/fuzzer/corpus/50c152827e67573a02deb9d9a30329e2d55fb74d b/fuzzer/corpus/50c152827e67573a02deb9d9a30329e2d55fb74d
new file mode 100644
index 0000000..3263ede
--- /dev/null
+++ b/fuzzer/corpus/50c152827e67573a02deb9d9a30329e2d55fb74d
Binary files differ
diff --git a/fuzzer/corpus/50f397d584965ccdf5ab70a6bd75bf740f7a358e b/fuzzer/corpus/50f397d584965ccdf5ab70a6bd75bf740f7a358e
new file mode 100644
index 0000000..86f9cce
--- /dev/null
+++ b/fuzzer/corpus/50f397d584965ccdf5ab70a6bd75bf740f7a358e
Binary files differ
diff --git a/fuzzer/corpus/518e2b27db6127d24d2c06636b9fb145db4452eb b/fuzzer/corpus/518e2b27db6127d24d2c06636b9fb145db4452eb
new file mode 100644
index 0000000..c4d014e
--- /dev/null
+++ b/fuzzer/corpus/518e2b27db6127d24d2c06636b9fb145db4452eb
Binary files differ
diff --git a/fuzzer/corpus/5191a0357a3358dd3290f61cddcd563021505012 b/fuzzer/corpus/5191a0357a3358dd3290f61cddcd563021505012
new file mode 100644
index 0000000..a6531d4
--- /dev/null
+++ b/fuzzer/corpus/5191a0357a3358dd3290f61cddcd563021505012
Binary files differ
diff --git a/fuzzer/corpus/51c4b7732852c0709b0438a0f37717cd7499b24d b/fuzzer/corpus/51c4b7732852c0709b0438a0f37717cd7499b24d
new file mode 100644
index 0000000..c3df97f
--- /dev/null
+++ b/fuzzer/corpus/51c4b7732852c0709b0438a0f37717cd7499b24d
Binary files differ
diff --git a/fuzzer/corpus/51ca2d31463c473b3abac0e275e3fdbcfa32bc85 b/fuzzer/corpus/51ca2d31463c473b3abac0e275e3fdbcfa32bc85
new file mode 100644
index 0000000..45b4372
--- /dev/null
+++ b/fuzzer/corpus/51ca2d31463c473b3abac0e275e3fdbcfa32bc85
Binary files differ
diff --git a/fuzzer/corpus/51e52a805dcf6774afe3c4876f54034f32aae495 b/fuzzer/corpus/51e52a805dcf6774afe3c4876f54034f32aae495
new file mode 100644
index 0000000..64de3b6
--- /dev/null
+++ b/fuzzer/corpus/51e52a805dcf6774afe3c4876f54034f32aae495
Binary files differ
diff --git a/fuzzer/corpus/51e5aefb13840b34db2a876123f56f3d2810cc8d b/fuzzer/corpus/51e5aefb13840b34db2a876123f56f3d2810cc8d
new file mode 100644
index 0000000..0d3115c
--- /dev/null
+++ b/fuzzer/corpus/51e5aefb13840b34db2a876123f56f3d2810cc8d
Binary files differ
diff --git a/fuzzer/corpus/520b82ffdce9643af41fb4113ae76a121f6a33a1 b/fuzzer/corpus/520b82ffdce9643af41fb4113ae76a121f6a33a1
new file mode 100644
index 0000000..3e55efc
--- /dev/null
+++ b/fuzzer/corpus/520b82ffdce9643af41fb4113ae76a121f6a33a1
Binary files differ
diff --git a/fuzzer/corpus/52228d0291c8ba4a0f9749dd9a803362d6ad0efa b/fuzzer/corpus/52228d0291c8ba4a0f9749dd9a803362d6ad0efa
new file mode 100644
index 0000000..f79dbe3
--- /dev/null
+++ b/fuzzer/corpus/52228d0291c8ba4a0f9749dd9a803362d6ad0efa
Binary files differ
diff --git a/fuzzer/corpus/523985886f09a66395616f0fc28f68e6cea0e38f b/fuzzer/corpus/523985886f09a66395616f0fc28f68e6cea0e38f
new file mode 100644
index 0000000..ac18dea
--- /dev/null
+++ b/fuzzer/corpus/523985886f09a66395616f0fc28f68e6cea0e38f
Binary files differ
diff --git a/fuzzer/corpus/526f1564cc0ea0a19ca78d9324c8638ff72477e9 b/fuzzer/corpus/526f1564cc0ea0a19ca78d9324c8638ff72477e9
new file mode 100644
index 0000000..1212436
--- /dev/null
+++ b/fuzzer/corpus/526f1564cc0ea0a19ca78d9324c8638ff72477e9
Binary files differ
diff --git a/fuzzer/corpus/532c36b979af8b1003ffbe124f4f1e1dca212516 b/fuzzer/corpus/532c36b979af8b1003ffbe124f4f1e1dca212516
new file mode 100644
index 0000000..4cb0803
--- /dev/null
+++ b/fuzzer/corpus/532c36b979af8b1003ffbe124f4f1e1dca212516
Binary files differ
diff --git a/fuzzer/corpus/53b62164ae11fd3c45e2062d9806c6bb51a9bbee b/fuzzer/corpus/53b62164ae11fd3c45e2062d9806c6bb51a9bbee
new file mode 100644
index 0000000..1700199
--- /dev/null
+++ b/fuzzer/corpus/53b62164ae11fd3c45e2062d9806c6bb51a9bbee
Binary files differ
diff --git a/fuzzer/corpus/53ffeb0791f8111cbf6c1280a2f8815b66d37a96 b/fuzzer/corpus/53ffeb0791f8111cbf6c1280a2f8815b66d37a96
new file mode 100644
index 0000000..53a98d3
--- /dev/null
+++ b/fuzzer/corpus/53ffeb0791f8111cbf6c1280a2f8815b66d37a96
Binary files differ
diff --git a/fuzzer/corpus/54286dc58e34b136b358bf3593882ed78a1b99e7 b/fuzzer/corpus/54286dc58e34b136b358bf3593882ed78a1b99e7
new file mode 100644
index 0000000..39dfe76
--- /dev/null
+++ b/fuzzer/corpus/54286dc58e34b136b358bf3593882ed78a1b99e7
Binary files differ
diff --git a/fuzzer/corpus/54553aed9bc6f2427aecf1b7fc547898cc21230b b/fuzzer/corpus/54553aed9bc6f2427aecf1b7fc547898cc21230b
new file mode 100644
index 0000000..16dac50
--- /dev/null
+++ b/fuzzer/corpus/54553aed9bc6f2427aecf1b7fc547898cc21230b
Binary files differ
diff --git a/fuzzer/corpus/5456e481d33928590f6151e34693cb1cc497c2d2 b/fuzzer/corpus/5456e481d33928590f6151e34693cb1cc497c2d2
new file mode 100644
index 0000000..d0e0ccf
--- /dev/null
+++ b/fuzzer/corpus/5456e481d33928590f6151e34693cb1cc497c2d2
Binary files differ
diff --git a/fuzzer/corpus/547dc3ebdd8776281f996bfcb3e9f69ad97974d6 b/fuzzer/corpus/547dc3ebdd8776281f996bfcb3e9f69ad97974d6
new file mode 100644
index 0000000..c9547be
--- /dev/null
+++ b/fuzzer/corpus/547dc3ebdd8776281f996bfcb3e9f69ad97974d6
Binary files differ
diff --git a/fuzzer/corpus/549f9773b9bc7ecc0b0ba7f26c0bdd8d3b0abf54 b/fuzzer/corpus/549f9773b9bc7ecc0b0ba7f26c0bdd8d3b0abf54
new file mode 100644
index 0000000..51664db
--- /dev/null
+++ b/fuzzer/corpus/549f9773b9bc7ecc0b0ba7f26c0bdd8d3b0abf54
Binary files differ
diff --git a/fuzzer/corpus/54b6695b808e5bf6565b2939b3ba6b2123234a6d b/fuzzer/corpus/54b6695b808e5bf6565b2939b3ba6b2123234a6d
new file mode 100644
index 0000000..896a383
--- /dev/null
+++ b/fuzzer/corpus/54b6695b808e5bf6565b2939b3ba6b2123234a6d
Binary files differ
diff --git a/fuzzer/corpus/54b813a24e01e8357c43f5275aa8f5b9bd8b06d5 b/fuzzer/corpus/54b813a24e01e8357c43f5275aa8f5b9bd8b06d5
new file mode 100644
index 0000000..8777c4f
--- /dev/null
+++ b/fuzzer/corpus/54b813a24e01e8357c43f5275aa8f5b9bd8b06d5
Binary files differ
diff --git a/fuzzer/corpus/54c6b0ff97fdf452114f9359b4d8a07cee10a0f4 b/fuzzer/corpus/54c6b0ff97fdf452114f9359b4d8a07cee10a0f4
new file mode 100644
index 0000000..e820aed
--- /dev/null
+++ b/fuzzer/corpus/54c6b0ff97fdf452114f9359b4d8a07cee10a0f4
Binary files differ
diff --git a/fuzzer/corpus/54c767f752d5b845f29062012dd30c58f90eb170 b/fuzzer/corpus/54c767f752d5b845f29062012dd30c58f90eb170
new file mode 100644
index 0000000..b50fa7f
--- /dev/null
+++ b/fuzzer/corpus/54c767f752d5b845f29062012dd30c58f90eb170
Binary files differ
diff --git a/fuzzer/corpus/54eabcdf24bad3d8029203a754988def9d2f4d8f b/fuzzer/corpus/54eabcdf24bad3d8029203a754988def9d2f4d8f
new file mode 100644
index 0000000..063f7fa
--- /dev/null
+++ b/fuzzer/corpus/54eabcdf24bad3d8029203a754988def9d2f4d8f
Binary files differ
diff --git a/fuzzer/corpus/55022bdea04bef0d4770f2496c9dbb0c0c8d92c8 b/fuzzer/corpus/55022bdea04bef0d4770f2496c9dbb0c0c8d92c8
new file mode 100644
index 0000000..9a7d7a9
--- /dev/null
+++ b/fuzzer/corpus/55022bdea04bef0d4770f2496c9dbb0c0c8d92c8
Binary files differ
diff --git a/fuzzer/corpus/5520e0231a9026268e73739f5006c3a7a3605701 b/fuzzer/corpus/5520e0231a9026268e73739f5006c3a7a3605701
new file mode 100644
index 0000000..c70e304
--- /dev/null
+++ b/fuzzer/corpus/5520e0231a9026268e73739f5006c3a7a3605701
Binary files differ
diff --git a/fuzzer/corpus/553402a2a319ba6c83bf602f993b7728b5b00273 b/fuzzer/corpus/553402a2a319ba6c83bf602f993b7728b5b00273
new file mode 100644
index 0000000..4574396
--- /dev/null
+++ b/fuzzer/corpus/553402a2a319ba6c83bf602f993b7728b5b00273
Binary files differ
diff --git a/fuzzer/corpus/554884ce961a82608cc14679fa8f93dfa3707bca b/fuzzer/corpus/554884ce961a82608cc14679fa8f93dfa3707bca
new file mode 100644
index 0000000..b31f41d
--- /dev/null
+++ b/fuzzer/corpus/554884ce961a82608cc14679fa8f93dfa3707bca
Binary files differ
diff --git a/fuzzer/corpus/558d59eba1bee63332fa787ad31a66030ac890bc b/fuzzer/corpus/558d59eba1bee63332fa787ad31a66030ac890bc
new file mode 100644
index 0000000..128b0a9
--- /dev/null
+++ b/fuzzer/corpus/558d59eba1bee63332fa787ad31a66030ac890bc
Binary files differ
diff --git a/fuzzer/corpus/55d105dace85e02cb95ecb9e1c8dc78b3ace8bb5 b/fuzzer/corpus/55d105dace85e02cb95ecb9e1c8dc78b3ace8bb5
new file mode 100644
index 0000000..d7d20d1
--- /dev/null
+++ b/fuzzer/corpus/55d105dace85e02cb95ecb9e1c8dc78b3ace8bb5
Binary files differ
diff --git a/fuzzer/corpus/55dc1e38a4fdb1b1aef71b65a08523376171d8eb b/fuzzer/corpus/55dc1e38a4fdb1b1aef71b65a08523376171d8eb
new file mode 100644
index 0000000..9db7834
--- /dev/null
+++ b/fuzzer/corpus/55dc1e38a4fdb1b1aef71b65a08523376171d8eb
Binary files differ
diff --git a/fuzzer/corpus/55f5592b8c6806a1ef9f8c438ca06e3f30b5e1f3 b/fuzzer/corpus/55f5592b8c6806a1ef9f8c438ca06e3f30b5e1f3
new file mode 100644
index 0000000..3f357c3
--- /dev/null
+++ b/fuzzer/corpus/55f5592b8c6806a1ef9f8c438ca06e3f30b5e1f3
Binary files differ
diff --git a/fuzzer/corpus/5603da87ba03b13667501638a1d9788036c4634c b/fuzzer/corpus/5603da87ba03b13667501638a1d9788036c4634c
new file mode 100644
index 0000000..885541c
--- /dev/null
+++ b/fuzzer/corpus/5603da87ba03b13667501638a1d9788036c4634c
Binary files differ
diff --git a/fuzzer/corpus/562ebbe8126d4344da90d35c7249294b52d4a6ae b/fuzzer/corpus/562ebbe8126d4344da90d35c7249294b52d4a6ae
new file mode 100644
index 0000000..ecad266
--- /dev/null
+++ b/fuzzer/corpus/562ebbe8126d4344da90d35c7249294b52d4a6ae
Binary files differ
diff --git a/fuzzer/corpus/563a9475b5b449fd62634f1df5bb3e00907be925 b/fuzzer/corpus/563a9475b5b449fd62634f1df5bb3e00907be925
new file mode 100644
index 0000000..50e36db
--- /dev/null
+++ b/fuzzer/corpus/563a9475b5b449fd62634f1df5bb3e00907be925
Binary files differ
diff --git a/fuzzer/corpus/566cb4d31a6fcc30c90f98c08afd1dce884649cc b/fuzzer/corpus/566cb4d31a6fcc30c90f98c08afd1dce884649cc
new file mode 100644
index 0000000..371e08a
--- /dev/null
+++ b/fuzzer/corpus/566cb4d31a6fcc30c90f98c08afd1dce884649cc
Binary files differ
diff --git a/fuzzer/corpus/56d8fb3d29f055ddae16b829cb094bb0ed754a18 b/fuzzer/corpus/56d8fb3d29f055ddae16b829cb094bb0ed754a18
new file mode 100644
index 0000000..69c5f42
--- /dev/null
+++ b/fuzzer/corpus/56d8fb3d29f055ddae16b829cb094bb0ed754a18
Binary files differ
diff --git a/fuzzer/corpus/574195f4c56357d6e3ab2c688ace9f7c5526872d b/fuzzer/corpus/574195f4c56357d6e3ab2c688ace9f7c5526872d
new file mode 100644
index 0000000..71cc130
--- /dev/null
+++ b/fuzzer/corpus/574195f4c56357d6e3ab2c688ace9f7c5526872d
Binary files differ
diff --git a/fuzzer/corpus/574754a107554e54128a886ae4ee46e8df527827 b/fuzzer/corpus/574754a107554e54128a886ae4ee46e8df527827
new file mode 100644
index 0000000..1f01cd0
--- /dev/null
+++ b/fuzzer/corpus/574754a107554e54128a886ae4ee46e8df527827
Binary files differ
diff --git a/fuzzer/corpus/5754d14d803f9268f6cbb6cf305d0e8dcc2bf4e0 b/fuzzer/corpus/5754d14d803f9268f6cbb6cf305d0e8dcc2bf4e0
new file mode 100644
index 0000000..8f346fe
--- /dev/null
+++ b/fuzzer/corpus/5754d14d803f9268f6cbb6cf305d0e8dcc2bf4e0
Binary files differ
diff --git a/fuzzer/corpus/57de5380db49002b5f581b318ca337f7c6ba7b0d b/fuzzer/corpus/57de5380db49002b5f581b318ca337f7c6ba7b0d
new file mode 100644
index 0000000..8510639
--- /dev/null
+++ b/fuzzer/corpus/57de5380db49002b5f581b318ca337f7c6ba7b0d
Binary files differ
diff --git a/fuzzer/corpus/57e00ddcd6236f2c282b1b57d8d67b3fd4a28eb1 b/fuzzer/corpus/57e00ddcd6236f2c282b1b57d8d67b3fd4a28eb1
new file mode 100644
index 0000000..eb0487e
--- /dev/null
+++ b/fuzzer/corpus/57e00ddcd6236f2c282b1b57d8d67b3fd4a28eb1
Binary files differ
diff --git a/fuzzer/corpus/57e57debf4de3850f747f985bed9784124047c0d b/fuzzer/corpus/57e57debf4de3850f747f985bed9784124047c0d
new file mode 100644
index 0000000..7d6ce73
--- /dev/null
+++ b/fuzzer/corpus/57e57debf4de3850f747f985bed9784124047c0d
Binary files differ
diff --git a/fuzzer/corpus/583b5f47f4aaf0611fb0d3c51036a539e2e4a629 b/fuzzer/corpus/583b5f47f4aaf0611fb0d3c51036a539e2e4a629
new file mode 100644
index 0000000..47e7ad3
--- /dev/null
+++ b/fuzzer/corpus/583b5f47f4aaf0611fb0d3c51036a539e2e4a629
Binary files differ
diff --git a/fuzzer/corpus/5877ed503eb8389c81bc0692e2362f979c1eb075 b/fuzzer/corpus/5877ed503eb8389c81bc0692e2362f979c1eb075
new file mode 100644
index 0000000..d06d564
--- /dev/null
+++ b/fuzzer/corpus/5877ed503eb8389c81bc0692e2362f979c1eb075
Binary files differ
diff --git a/fuzzer/corpus/589e034121a252d445e72104dacc057c387c7d4e b/fuzzer/corpus/589e034121a252d445e72104dacc057c387c7d4e
new file mode 100644
index 0000000..1f4549b
--- /dev/null
+++ b/fuzzer/corpus/589e034121a252d445e72104dacc057c387c7d4e
Binary files differ
diff --git a/fuzzer/corpus/58a3195b9dad3b35b48f68b9ee2bd5f8a4d187a8 b/fuzzer/corpus/58a3195b9dad3b35b48f68b9ee2bd5f8a4d187a8
new file mode 100644
index 0000000..193d44f
--- /dev/null
+++ b/fuzzer/corpus/58a3195b9dad3b35b48f68b9ee2bd5f8a4d187a8
Binary files differ
diff --git a/fuzzer/corpus/58a3dc918b9fd6004263929c54b81b880d2069d7 b/fuzzer/corpus/58a3dc918b9fd6004263929c54b81b880d2069d7
new file mode 100644
index 0000000..17143dd
--- /dev/null
+++ b/fuzzer/corpus/58a3dc918b9fd6004263929c54b81b880d2069d7
Binary files differ
diff --git a/fuzzer/corpus/58a966b45ac74ebf015a47770686ca4d61f372d8 b/fuzzer/corpus/58a966b45ac74ebf015a47770686ca4d61f372d8
new file mode 100644
index 0000000..b730e0d
--- /dev/null
+++ b/fuzzer/corpus/58a966b45ac74ebf015a47770686ca4d61f372d8
Binary files differ
diff --git a/fuzzer/corpus/58c34f65a8fc98e52e2039dded3f230c3bfdf099 b/fuzzer/corpus/58c34f65a8fc98e52e2039dded3f230c3bfdf099
new file mode 100644
index 0000000..c5a1b18
--- /dev/null
+++ b/fuzzer/corpus/58c34f65a8fc98e52e2039dded3f230c3bfdf099
Binary files differ
diff --git a/fuzzer/corpus/58c440c190619330a10ea3a88c453abee1956bfd b/fuzzer/corpus/58c440c190619330a10ea3a88c453abee1956bfd
new file mode 100644
index 0000000..3572dd0
--- /dev/null
+++ b/fuzzer/corpus/58c440c190619330a10ea3a88c453abee1956bfd
Binary files differ
diff --git a/fuzzer/corpus/58c61f6124427c2e45eb0ad6761e702618f969c4 b/fuzzer/corpus/58c61f6124427c2e45eb0ad6761e702618f969c4
new file mode 100644
index 0000000..00e8c9c
--- /dev/null
+++ b/fuzzer/corpus/58c61f6124427c2e45eb0ad6761e702618f969c4
Binary files differ
diff --git a/fuzzer/corpus/58f7d611e702da8140ea3cfba8ff69abfe6d2d46 b/fuzzer/corpus/58f7d611e702da8140ea3cfba8ff69abfe6d2d46
new file mode 100644
index 0000000..2da07d1
--- /dev/null
+++ b/fuzzer/corpus/58f7d611e702da8140ea3cfba8ff69abfe6d2d46
Binary files differ
diff --git a/fuzzer/corpus/58f9e0111a6833627938e0dfbaad4c901d107df8 b/fuzzer/corpus/58f9e0111a6833627938e0dfbaad4c901d107df8
new file mode 100644
index 0000000..32e650e
--- /dev/null
+++ b/fuzzer/corpus/58f9e0111a6833627938e0dfbaad4c901d107df8
Binary files differ
diff --git a/fuzzer/corpus/590e3b30215b7d037913d0c26b8ae24c0843a452 b/fuzzer/corpus/590e3b30215b7d037913d0c26b8ae24c0843a452
new file mode 100644
index 0000000..81aafc0
--- /dev/null
+++ b/fuzzer/corpus/590e3b30215b7d037913d0c26b8ae24c0843a452
Binary files differ
diff --git a/fuzzer/corpus/5934c811fcae83db8a8a576efc1a2472c08eea1d b/fuzzer/corpus/5934c811fcae83db8a8a576efc1a2472c08eea1d
new file mode 100644
index 0000000..fecd69f
--- /dev/null
+++ b/fuzzer/corpus/5934c811fcae83db8a8a576efc1a2472c08eea1d
Binary files differ
diff --git a/fuzzer/corpus/5951b46082cb84e45c8bebf9d5ea3f6a1018733f b/fuzzer/corpus/5951b46082cb84e45c8bebf9d5ea3f6a1018733f
new file mode 100644
index 0000000..2e1f24a
--- /dev/null
+++ b/fuzzer/corpus/5951b46082cb84e45c8bebf9d5ea3f6a1018733f
Binary files differ
diff --git a/fuzzer/corpus/5977f8d34f45745f63ff61e271623427d41da0c2 b/fuzzer/corpus/5977f8d34f45745f63ff61e271623427d41da0c2
new file mode 100644
index 0000000..46fa98a
--- /dev/null
+++ b/fuzzer/corpus/5977f8d34f45745f63ff61e271623427d41da0c2
Binary files differ
diff --git a/fuzzer/corpus/59983fa03a6675fdd23b40b1cfd51debc20726ee b/fuzzer/corpus/59983fa03a6675fdd23b40b1cfd51debc20726ee
new file mode 100644
index 0000000..fbf6607
--- /dev/null
+++ b/fuzzer/corpus/59983fa03a6675fdd23b40b1cfd51debc20726ee
Binary files differ
diff --git a/fuzzer/corpus/599a6b95c82ebc7b9f00050ecebb14392abe51c3 b/fuzzer/corpus/599a6b95c82ebc7b9f00050ecebb14392abe51c3
new file mode 100644
index 0000000..38d13d7
--- /dev/null
+++ b/fuzzer/corpus/599a6b95c82ebc7b9f00050ecebb14392abe51c3
Binary files differ
diff --git a/fuzzer/corpus/59b4a9f480a1c995f5d9c5fca19d1eac5c367017 b/fuzzer/corpus/59b4a9f480a1c995f5d9c5fca19d1eac5c367017
new file mode 100644
index 0000000..a62291b
--- /dev/null
+++ b/fuzzer/corpus/59b4a9f480a1c995f5d9c5fca19d1eac5c367017
Binary files differ
diff --git a/fuzzer/corpus/5a0667e778e29501120b35a61c79eb6d6766acf1 b/fuzzer/corpus/5a0667e778e29501120b35a61c79eb6d6766acf1
new file mode 100644
index 0000000..6169d5f
--- /dev/null
+++ b/fuzzer/corpus/5a0667e778e29501120b35a61c79eb6d6766acf1
Binary files differ
diff --git a/fuzzer/corpus/5a0adbb9d45f626e8fb08e03d1fac37b33bf6ada b/fuzzer/corpus/5a0adbb9d45f626e8fb08e03d1fac37b33bf6ada
new file mode 100644
index 0000000..d23404d
--- /dev/null
+++ b/fuzzer/corpus/5a0adbb9d45f626e8fb08e03d1fac37b33bf6ada
Binary files differ
diff --git a/fuzzer/corpus/5a3ec3051c1e08289c821a3ba9de31c94cc07787 b/fuzzer/corpus/5a3ec3051c1e08289c821a3ba9de31c94cc07787
new file mode 100644
index 0000000..2ac0635
--- /dev/null
+++ b/fuzzer/corpus/5a3ec3051c1e08289c821a3ba9de31c94cc07787
Binary files differ
diff --git a/fuzzer/corpus/5a7930a948550d09baa6ee015b329e072581fade b/fuzzer/corpus/5a7930a948550d09baa6ee015b329e072581fade
new file mode 100644
index 0000000..0ebc988
--- /dev/null
+++ b/fuzzer/corpus/5a7930a948550d09baa6ee015b329e072581fade
Binary files differ
diff --git a/fuzzer/corpus/5aa9b976c14d72f436487381eff2b555371cc2f3 b/fuzzer/corpus/5aa9b976c14d72f436487381eff2b555371cc2f3
new file mode 100644
index 0000000..83afd6e
--- /dev/null
+++ b/fuzzer/corpus/5aa9b976c14d72f436487381eff2b555371cc2f3
Binary files differ
diff --git a/fuzzer/corpus/5aaafe06a140849cbc6e14647b219241b85cd867 b/fuzzer/corpus/5aaafe06a140849cbc6e14647b219241b85cd867
new file mode 100644
index 0000000..44bb5f7
--- /dev/null
+++ b/fuzzer/corpus/5aaafe06a140849cbc6e14647b219241b85cd867
Binary files differ
diff --git a/fuzzer/corpus/5ab4f4c621236226bf559041e869257f28131ecb b/fuzzer/corpus/5ab4f4c621236226bf559041e869257f28131ecb
new file mode 100644
index 0000000..cece132
--- /dev/null
+++ b/fuzzer/corpus/5ab4f4c621236226bf559041e869257f28131ecb
Binary files differ
diff --git a/fuzzer/corpus/5add5469d7e867fe432d6958178e6863be5af6c9 b/fuzzer/corpus/5add5469d7e867fe432d6958178e6863be5af6c9
new file mode 100644
index 0000000..71dc220
--- /dev/null
+++ b/fuzzer/corpus/5add5469d7e867fe432d6958178e6863be5af6c9
Binary files differ
diff --git a/fuzzer/corpus/5b010a8b7dcaa3e995f9032893010eb4d0e4ebe9 b/fuzzer/corpus/5b010a8b7dcaa3e995f9032893010eb4d0e4ebe9
new file mode 100644
index 0000000..7315ff4
--- /dev/null
+++ b/fuzzer/corpus/5b010a8b7dcaa3e995f9032893010eb4d0e4ebe9
Binary files differ
diff --git a/fuzzer/corpus/5b35017750540a5b1cdd4008558347708b568a84 b/fuzzer/corpus/5b35017750540a5b1cdd4008558347708b568a84
new file mode 100644
index 0000000..7752bd0
--- /dev/null
+++ b/fuzzer/corpus/5b35017750540a5b1cdd4008558347708b568a84
Binary files differ
diff --git a/fuzzer/corpus/5b53d0a4e6ee6bc73a29391ad5f4cd6fa2d3017e b/fuzzer/corpus/5b53d0a4e6ee6bc73a29391ad5f4cd6fa2d3017e
new file mode 100644
index 0000000..7ad7dd8
--- /dev/null
+++ b/fuzzer/corpus/5b53d0a4e6ee6bc73a29391ad5f4cd6fa2d3017e
Binary files differ
diff --git a/fuzzer/corpus/5b7ea3bba13d17d8fa4176ffa5cea0bc7a7f6c44 b/fuzzer/corpus/5b7ea3bba13d17d8fa4176ffa5cea0bc7a7f6c44
new file mode 100644
index 0000000..f3de685
--- /dev/null
+++ b/fuzzer/corpus/5b7ea3bba13d17d8fa4176ffa5cea0bc7a7f6c44
Binary files differ
diff --git a/fuzzer/corpus/5b9d48b61c7c6c9abc2669ad417cb1487b9934aa b/fuzzer/corpus/5b9d48b61c7c6c9abc2669ad417cb1487b9934aa
new file mode 100644
index 0000000..c4de1a4
--- /dev/null
+++ b/fuzzer/corpus/5b9d48b61c7c6c9abc2669ad417cb1487b9934aa
Binary files differ
diff --git a/fuzzer/corpus/5ba0b298eb42875f33ba8e5e0471faafa7b49e7d b/fuzzer/corpus/5ba0b298eb42875f33ba8e5e0471faafa7b49e7d
new file mode 100644
index 0000000..c681ea7
--- /dev/null
+++ b/fuzzer/corpus/5ba0b298eb42875f33ba8e5e0471faafa7b49e7d
Binary files differ
diff --git a/fuzzer/corpus/5bd352048873f6d2ac8fbc0356ea7e7d05918ddd b/fuzzer/corpus/5bd352048873f6d2ac8fbc0356ea7e7d05918ddd
new file mode 100644
index 0000000..868e43c
--- /dev/null
+++ b/fuzzer/corpus/5bd352048873f6d2ac8fbc0356ea7e7d05918ddd
Binary files differ
diff --git a/fuzzer/corpus/5bf83221f44d32022c5c3adf4241f715f0794461 b/fuzzer/corpus/5bf83221f44d32022c5c3adf4241f715f0794461
new file mode 100644
index 0000000..92ee9ad
--- /dev/null
+++ b/fuzzer/corpus/5bf83221f44d32022c5c3adf4241f715f0794461
Binary files differ
diff --git a/fuzzer/corpus/5bffd900d1d343c268a7cdfa08c8faf000319974 b/fuzzer/corpus/5bffd900d1d343c268a7cdfa08c8faf000319974
new file mode 100644
index 0000000..5ea03c8
--- /dev/null
+++ b/fuzzer/corpus/5bffd900d1d343c268a7cdfa08c8faf000319974
Binary files differ
diff --git a/fuzzer/corpus/5c1ab7ce9dfefe55249e883d3359ade7e76e5ce0 b/fuzzer/corpus/5c1ab7ce9dfefe55249e883d3359ade7e76e5ce0
new file mode 100644
index 0000000..b4b796a
--- /dev/null
+++ b/fuzzer/corpus/5c1ab7ce9dfefe55249e883d3359ade7e76e5ce0
Binary files differ
diff --git a/fuzzer/corpus/5c50457a8a183a1b286327c78b52a83a8c5e4c60 b/fuzzer/corpus/5c50457a8a183a1b286327c78b52a83a8c5e4c60
new file mode 100644
index 0000000..765afad
--- /dev/null
+++ b/fuzzer/corpus/5c50457a8a183a1b286327c78b52a83a8c5e4c60
Binary files differ
diff --git a/fuzzer/corpus/5c65a7b3d7df8b9a962fc82df75b0d7b930a81b0 b/fuzzer/corpus/5c65a7b3d7df8b9a962fc82df75b0d7b930a81b0
new file mode 100644
index 0000000..dde671f
--- /dev/null
+++ b/fuzzer/corpus/5c65a7b3d7df8b9a962fc82df75b0d7b930a81b0
Binary files differ
diff --git a/fuzzer/corpus/5c7b86ea4762bf763c3134ec0aa3580f82cc70f9 b/fuzzer/corpus/5c7b86ea4762bf763c3134ec0aa3580f82cc70f9
new file mode 100644
index 0000000..4af04ef
--- /dev/null
+++ b/fuzzer/corpus/5c7b86ea4762bf763c3134ec0aa3580f82cc70f9
Binary files differ
diff --git a/fuzzer/corpus/5c818e280c90078b385ac1cd9316bd4465144508 b/fuzzer/corpus/5c818e280c90078b385ac1cd9316bd4465144508
new file mode 100644
index 0000000..a9a99d6
--- /dev/null
+++ b/fuzzer/corpus/5c818e280c90078b385ac1cd9316bd4465144508
Binary files differ
diff --git a/fuzzer/corpus/5caeea41da4372ca05b0e28a15c4533d7517b203 b/fuzzer/corpus/5caeea41da4372ca05b0e28a15c4533d7517b203
new file mode 100644
index 0000000..a1ec99d
--- /dev/null
+++ b/fuzzer/corpus/5caeea41da4372ca05b0e28a15c4533d7517b203
Binary files differ
diff --git a/fuzzer/corpus/5cbd957537442bcf267687c9e3fae175a93da3a9 b/fuzzer/corpus/5cbd957537442bcf267687c9e3fae175a93da3a9
new file mode 100644
index 0000000..18c3eaf
--- /dev/null
+++ b/fuzzer/corpus/5cbd957537442bcf267687c9e3fae175a93da3a9
Binary files differ
diff --git a/fuzzer/corpus/5cf363baadf037f6b2d9ba6bc43274685aebf7bd b/fuzzer/corpus/5cf363baadf037f6b2d9ba6bc43274685aebf7bd
new file mode 100644
index 0000000..eb6d057
--- /dev/null
+++ b/fuzzer/corpus/5cf363baadf037f6b2d9ba6bc43274685aebf7bd
Binary files differ
diff --git a/fuzzer/corpus/5cfd0e042d6237d0436a3ca12d8c1dfb536f8be3 b/fuzzer/corpus/5cfd0e042d6237d0436a3ca12d8c1dfb536f8be3
new file mode 100644
index 0000000..fe91a38
--- /dev/null
+++ b/fuzzer/corpus/5cfd0e042d6237d0436a3ca12d8c1dfb536f8be3
Binary files differ
diff --git a/fuzzer/corpus/5d01f5a9544ad63f156ec2b9e9a30326e35d67b0 b/fuzzer/corpus/5d01f5a9544ad63f156ec2b9e9a30326e35d67b0
new file mode 100644
index 0000000..8e88242
--- /dev/null
+++ b/fuzzer/corpus/5d01f5a9544ad63f156ec2b9e9a30326e35d67b0
Binary files differ
diff --git a/fuzzer/corpus/5d0a2b8e5ab4c6220f70b408d5d82bf08a723732 b/fuzzer/corpus/5d0a2b8e5ab4c6220f70b408d5d82bf08a723732
new file mode 100644
index 0000000..9e7921e
--- /dev/null
+++ b/fuzzer/corpus/5d0a2b8e5ab4c6220f70b408d5d82bf08a723732
Binary files differ
diff --git a/fuzzer/corpus/5d7a38cb9399eeda448bc84e1449e7a5bab0f5e6 b/fuzzer/corpus/5d7a38cb9399eeda448bc84e1449e7a5bab0f5e6
new file mode 100644
index 0000000..5b0ebf6
--- /dev/null
+++ b/fuzzer/corpus/5d7a38cb9399eeda448bc84e1449e7a5bab0f5e6
Binary files differ
diff --git a/fuzzer/corpus/5d813c4465a4269409085a072f39cdf4234ef6fa b/fuzzer/corpus/5d813c4465a4269409085a072f39cdf4234ef6fa
new file mode 100644
index 0000000..03a9dd2
--- /dev/null
+++ b/fuzzer/corpus/5d813c4465a4269409085a072f39cdf4234ef6fa
Binary files differ
diff --git a/fuzzer/corpus/5d9c2ba3bf785afa9339494d24e0c36fbea03ff6 b/fuzzer/corpus/5d9c2ba3bf785afa9339494d24e0c36fbea03ff6
new file mode 100644
index 0000000..a7b77f6
--- /dev/null
+++ b/fuzzer/corpus/5d9c2ba3bf785afa9339494d24e0c36fbea03ff6
Binary files differ
diff --git a/fuzzer/corpus/5d9e462a5151e631a1389f52fd7f220fd8c6a3d6 b/fuzzer/corpus/5d9e462a5151e631a1389f52fd7f220fd8c6a3d6
new file mode 100644
index 0000000..e9f05b0
--- /dev/null
+++ b/fuzzer/corpus/5d9e462a5151e631a1389f52fd7f220fd8c6a3d6
Binary files differ
diff --git a/fuzzer/corpus/5dd124861b5618cade180cb240caf3678b42c591 b/fuzzer/corpus/5dd124861b5618cade180cb240caf3678b42c591
new file mode 100644
index 0000000..dcaa43d
--- /dev/null
+++ b/fuzzer/corpus/5dd124861b5618cade180cb240caf3678b42c591
Binary files differ
diff --git a/fuzzer/corpus/5e065bc6b58574b3c83484e7dc6e1faf3fa5d161 b/fuzzer/corpus/5e065bc6b58574b3c83484e7dc6e1faf3fa5d161
new file mode 100644
index 0000000..5df9766
--- /dev/null
+++ b/fuzzer/corpus/5e065bc6b58574b3c83484e7dc6e1faf3fa5d161
Binary files differ
diff --git a/fuzzer/corpus/5e1a550e7021865bfcc959952a844d3b6a6bda24 b/fuzzer/corpus/5e1a550e7021865bfcc959952a844d3b6a6bda24
new file mode 100644
index 0000000..adffcad
--- /dev/null
+++ b/fuzzer/corpus/5e1a550e7021865bfcc959952a844d3b6a6bda24
Binary files differ
diff --git a/fuzzer/corpus/5e1a5b7ad4d785ddcb1849465ada15d4d3beaf83 b/fuzzer/corpus/5e1a5b7ad4d785ddcb1849465ada15d4d3beaf83
new file mode 100644
index 0000000..3f23ebd
--- /dev/null
+++ b/fuzzer/corpus/5e1a5b7ad4d785ddcb1849465ada15d4d3beaf83
Binary files differ
diff --git a/fuzzer/corpus/5e1f0fb312d887f114c0faf847c95ee3219a757f b/fuzzer/corpus/5e1f0fb312d887f114c0faf847c95ee3219a757f
new file mode 100644
index 0000000..8b32f63
--- /dev/null
+++ b/fuzzer/corpus/5e1f0fb312d887f114c0faf847c95ee3219a757f
Binary files differ
diff --git a/fuzzer/corpus/5e47a25d23087289945f9226c0a37f9668dc1942 b/fuzzer/corpus/5e47a25d23087289945f9226c0a37f9668dc1942
new file mode 100644
index 0000000..bd78b34
--- /dev/null
+++ b/fuzzer/corpus/5e47a25d23087289945f9226c0a37f9668dc1942
Binary files differ
diff --git a/fuzzer/corpus/5e625071f529dad68777f7a1f675743a528d366c b/fuzzer/corpus/5e625071f529dad68777f7a1f675743a528d366c
new file mode 100644
index 0000000..97f760f
--- /dev/null
+++ b/fuzzer/corpus/5e625071f529dad68777f7a1f675743a528d366c
Binary files differ
diff --git a/fuzzer/corpus/5e739c9eb9d9e4cbd0ecbaef1bdeb999d28a2d48 b/fuzzer/corpus/5e739c9eb9d9e4cbd0ecbaef1bdeb999d28a2d48
new file mode 100644
index 0000000..fc9556d
--- /dev/null
+++ b/fuzzer/corpus/5e739c9eb9d9e4cbd0ecbaef1bdeb999d28a2d48
Binary files differ
diff --git a/fuzzer/corpus/5e8a84ddf667f21a9b423ae1c08fc8feb7e5ce8f b/fuzzer/corpus/5e8a84ddf667f21a9b423ae1c08fc8feb7e5ce8f
new file mode 100644
index 0000000..642180d
--- /dev/null
+++ b/fuzzer/corpus/5e8a84ddf667f21a9b423ae1c08fc8feb7e5ce8f
Binary files differ
diff --git a/fuzzer/corpus/5eae25a49caeb548e54a3ef3c984fab8d9902622 b/fuzzer/corpus/5eae25a49caeb548e54a3ef3c984fab8d9902622
new file mode 100644
index 0000000..cf791dc
--- /dev/null
+++ b/fuzzer/corpus/5eae25a49caeb548e54a3ef3c984fab8d9902622
Binary files differ
diff --git a/fuzzer/corpus/5eb71bd7ad624545905508d552b6dc10a2f847bb b/fuzzer/corpus/5eb71bd7ad624545905508d552b6dc10a2f847bb
new file mode 100644
index 0000000..9074f0c
--- /dev/null
+++ b/fuzzer/corpus/5eb71bd7ad624545905508d552b6dc10a2f847bb
Binary files differ
diff --git a/fuzzer/corpus/5ebcffacdabd75a178673efcbdeefb1f79ed394b b/fuzzer/corpus/5ebcffacdabd75a178673efcbdeefb1f79ed394b
new file mode 100644
index 0000000..88eeaab
--- /dev/null
+++ b/fuzzer/corpus/5ebcffacdabd75a178673efcbdeefb1f79ed394b
Binary files differ
diff --git a/fuzzer/corpus/5ec15755d11256b26300505f389936752ffe31c7 b/fuzzer/corpus/5ec15755d11256b26300505f389936752ffe31c7
new file mode 100644
index 0000000..e4a5ef4
--- /dev/null
+++ b/fuzzer/corpus/5ec15755d11256b26300505f389936752ffe31c7
Binary files differ
diff --git a/fuzzer/corpus/5ee63fec474fb8683ba8926218ae3de284e07282 b/fuzzer/corpus/5ee63fec474fb8683ba8926218ae3de284e07282
new file mode 100644
index 0000000..222ecec
--- /dev/null
+++ b/fuzzer/corpus/5ee63fec474fb8683ba8926218ae3de284e07282
Binary files differ
diff --git a/fuzzer/corpus/5f140446c99237df25e408d21c553069f5c891ba b/fuzzer/corpus/5f140446c99237df25e408d21c553069f5c891ba
new file mode 100644
index 0000000..bd4ba44
--- /dev/null
+++ b/fuzzer/corpus/5f140446c99237df25e408d21c553069f5c891ba
Binary files differ
diff --git a/fuzzer/corpus/5f41358a7ecee7c3300274553aa6c2b8761e45ec b/fuzzer/corpus/5f41358a7ecee7c3300274553aa6c2b8761e45ec
new file mode 100644
index 0000000..206b400
--- /dev/null
+++ b/fuzzer/corpus/5f41358a7ecee7c3300274553aa6c2b8761e45ec
Binary files differ
diff --git a/fuzzer/corpus/5f456be4a8881ef761297b4ee2b2396be9cd06f8 b/fuzzer/corpus/5f456be4a8881ef761297b4ee2b2396be9cd06f8
new file mode 100644
index 0000000..fe34a9c
--- /dev/null
+++ b/fuzzer/corpus/5f456be4a8881ef761297b4ee2b2396be9cd06f8
Binary files differ
diff --git a/fuzzer/corpus/5f4a78fae92e6d4e3cdc99e83ad125a2f7818c8f b/fuzzer/corpus/5f4a78fae92e6d4e3cdc99e83ad125a2f7818c8f
new file mode 100644
index 0000000..88bee1c
--- /dev/null
+++ b/fuzzer/corpus/5f4a78fae92e6d4e3cdc99e83ad125a2f7818c8f
Binary files differ
diff --git a/fuzzer/corpus/5fb6f5c740bc17d3b279ab715fd08fa81686d5b1 b/fuzzer/corpus/5fb6f5c740bc17d3b279ab715fd08fa81686d5b1
new file mode 100644
index 0000000..b07d872
--- /dev/null
+++ b/fuzzer/corpus/5fb6f5c740bc17d3b279ab715fd08fa81686d5b1
Binary files differ
diff --git a/fuzzer/corpus/5fcbf48d19223180ace1731b23b2c23e386d576b b/fuzzer/corpus/5fcbf48d19223180ace1731b23b2c23e386d576b
new file mode 100644
index 0000000..e7acb77
--- /dev/null
+++ b/fuzzer/corpus/5fcbf48d19223180ace1731b23b2c23e386d576b
Binary files differ
diff --git a/fuzzer/corpus/5fe2d782d294f56e1391600e414ee2eeff844f08 b/fuzzer/corpus/5fe2d782d294f56e1391600e414ee2eeff844f08
new file mode 100644
index 0000000..011dbee
--- /dev/null
+++ b/fuzzer/corpus/5fe2d782d294f56e1391600e414ee2eeff844f08
Binary files differ
diff --git a/fuzzer/corpus/5ffd8ca2bda62b93f05301fc0a06c7e73a416bc8 b/fuzzer/corpus/5ffd8ca2bda62b93f05301fc0a06c7e73a416bc8
new file mode 100644
index 0000000..3810390
--- /dev/null
+++ b/fuzzer/corpus/5ffd8ca2bda62b93f05301fc0a06c7e73a416bc8
Binary files differ
diff --git a/fuzzer/corpus/603367d28ab8b9045648cb64bbc5030d1d15e5d9 b/fuzzer/corpus/603367d28ab8b9045648cb64bbc5030d1d15e5d9
new file mode 100644
index 0000000..f9ace3c
--- /dev/null
+++ b/fuzzer/corpus/603367d28ab8b9045648cb64bbc5030d1d15e5d9
Binary files differ
diff --git a/fuzzer/corpus/6042bfb5a12f07ee9eb070e5e2dff8697cad3908 b/fuzzer/corpus/6042bfb5a12f07ee9eb070e5e2dff8697cad3908
new file mode 100644
index 0000000..48761ac
--- /dev/null
+++ b/fuzzer/corpus/6042bfb5a12f07ee9eb070e5e2dff8697cad3908
Binary files differ
diff --git a/fuzzer/corpus/6043853a809a2e832897ad614133f55e14e2455a b/fuzzer/corpus/6043853a809a2e832897ad614133f55e14e2455a
new file mode 100644
index 0000000..3e3492d
--- /dev/null
+++ b/fuzzer/corpus/6043853a809a2e832897ad614133f55e14e2455a
Binary files differ
diff --git a/fuzzer/corpus/6073e7130e4f96a16e97395e06e222a81366cc3a b/fuzzer/corpus/6073e7130e4f96a16e97395e06e222a81366cc3a
new file mode 100644
index 0000000..d059ca2
--- /dev/null
+++ b/fuzzer/corpus/6073e7130e4f96a16e97395e06e222a81366cc3a
Binary files differ
diff --git a/fuzzer/corpus/609a69b86e5efde2de102c337a161b03e9c8876e b/fuzzer/corpus/609a69b86e5efde2de102c337a161b03e9c8876e
new file mode 100644
index 0000000..b27f587
--- /dev/null
+++ b/fuzzer/corpus/609a69b86e5efde2de102c337a161b03e9c8876e
Binary files differ
diff --git a/fuzzer/corpus/60b0c36b3f192b5f6316e5e0b9a417df091b37d5 b/fuzzer/corpus/60b0c36b3f192b5f6316e5e0b9a417df091b37d5
new file mode 100644
index 0000000..850ebe8
--- /dev/null
+++ b/fuzzer/corpus/60b0c36b3f192b5f6316e5e0b9a417df091b37d5
Binary files differ
diff --git a/fuzzer/corpus/60b765c94aed815e0f753d1afbde5ee97bfb72ff b/fuzzer/corpus/60b765c94aed815e0f753d1afbde5ee97bfb72ff
new file mode 100644
index 0000000..4d96728
--- /dev/null
+++ b/fuzzer/corpus/60b765c94aed815e0f753d1afbde5ee97bfb72ff
Binary files differ
diff --git a/fuzzer/corpus/60c6babf6298dbab7c90c76280d5a94c88ea9222 b/fuzzer/corpus/60c6babf6298dbab7c90c76280d5a94c88ea9222
new file mode 100644
index 0000000..bfde6be
--- /dev/null
+++ b/fuzzer/corpus/60c6babf6298dbab7c90c76280d5a94c88ea9222
Binary files differ
diff --git a/fuzzer/corpus/60c9128e76153d16fe8e7ba2adbb9ab7bbb220cc b/fuzzer/corpus/60c9128e76153d16fe8e7ba2adbb9ab7bbb220cc
new file mode 100644
index 0000000..d2c2d5b
--- /dev/null
+++ b/fuzzer/corpus/60c9128e76153d16fe8e7ba2adbb9ab7bbb220cc
Binary files differ
diff --git a/fuzzer/corpus/60d0b929af1da32a0e54a72d27ee4407284a10f2 b/fuzzer/corpus/60d0b929af1da32a0e54a72d27ee4407284a10f2
new file mode 100644
index 0000000..6f0da99
--- /dev/null
+++ b/fuzzer/corpus/60d0b929af1da32a0e54a72d27ee4407284a10f2
Binary files differ
diff --git a/fuzzer/corpus/60e4e9b585c7e41a5becab1dcbc0225e68d563d0 b/fuzzer/corpus/60e4e9b585c7e41a5becab1dcbc0225e68d563d0
new file mode 100644
index 0000000..d49c875
--- /dev/null
+++ b/fuzzer/corpus/60e4e9b585c7e41a5becab1dcbc0225e68d563d0
Binary files differ
diff --git a/fuzzer/corpus/60e7223c4b5304a98587b2478afdead8125c22aa b/fuzzer/corpus/60e7223c4b5304a98587b2478afdead8125c22aa
new file mode 100644
index 0000000..8bb88e0
--- /dev/null
+++ b/fuzzer/corpus/60e7223c4b5304a98587b2478afdead8125c22aa
Binary files differ
diff --git a/fuzzer/corpus/60f3638d7c58e1d52e2638cf50e68fa0cf3491db b/fuzzer/corpus/60f3638d7c58e1d52e2638cf50e68fa0cf3491db
new file mode 100644
index 0000000..394a6ba
--- /dev/null
+++ b/fuzzer/corpus/60f3638d7c58e1d52e2638cf50e68fa0cf3491db
Binary files differ
diff --git a/fuzzer/corpus/61177a0f4a0c9ee089cb9388d13ef562be8831bd b/fuzzer/corpus/61177a0f4a0c9ee089cb9388d13ef562be8831bd
new file mode 100644
index 0000000..8c3c6f8
--- /dev/null
+++ b/fuzzer/corpus/61177a0f4a0c9ee089cb9388d13ef562be8831bd
Binary files differ
diff --git a/fuzzer/corpus/613413787bc761296f663cb8d45a447118b001cc b/fuzzer/corpus/613413787bc761296f663cb8d45a447118b001cc
new file mode 100644
index 0000000..a7e9f37
--- /dev/null
+++ b/fuzzer/corpus/613413787bc761296f663cb8d45a447118b001cc
Binary files differ
diff --git a/fuzzer/corpus/6138aa043c89611152dcdf360c687f014ca2a219 b/fuzzer/corpus/6138aa043c89611152dcdf360c687f014ca2a219
new file mode 100644
index 0000000..8469d65
--- /dev/null
+++ b/fuzzer/corpus/6138aa043c89611152dcdf360c687f014ca2a219
Binary files differ
diff --git a/fuzzer/corpus/614e63bb137505589f4486d646ad255bf62d39da b/fuzzer/corpus/614e63bb137505589f4486d646ad255bf62d39da
new file mode 100644
index 0000000..92d324b
--- /dev/null
+++ b/fuzzer/corpus/614e63bb137505589f4486d646ad255bf62d39da
Binary files differ
diff --git a/fuzzer/corpus/617962216ea9a3e7d6b293fab5df70773c10c552 b/fuzzer/corpus/617962216ea9a3e7d6b293fab5df70773c10c552
new file mode 100644
index 0000000..03ccdb1
--- /dev/null
+++ b/fuzzer/corpus/617962216ea9a3e7d6b293fab5df70773c10c552
Binary files differ
diff --git a/fuzzer/corpus/618221ce08ce7422808dc657b7aedeb762b31b09 b/fuzzer/corpus/618221ce08ce7422808dc657b7aedeb762b31b09
new file mode 100644
index 0000000..d3a6fc6
--- /dev/null
+++ b/fuzzer/corpus/618221ce08ce7422808dc657b7aedeb762b31b09
Binary files differ
diff --git a/fuzzer/corpus/61a0f4708cac4433f56b999985950ffbf610dc92 b/fuzzer/corpus/61a0f4708cac4433f56b999985950ffbf610dc92
new file mode 100644
index 0000000..b7a0d02
--- /dev/null
+++ b/fuzzer/corpus/61a0f4708cac4433f56b999985950ffbf610dc92
Binary files differ
diff --git a/fuzzer/corpus/61ab084dc7aa99e837e0309fcd63f2e199cf0aae b/fuzzer/corpus/61ab084dc7aa99e837e0309fcd63f2e199cf0aae
new file mode 100644
index 0000000..c21585d
--- /dev/null
+++ b/fuzzer/corpus/61ab084dc7aa99e837e0309fcd63f2e199cf0aae
Binary files differ
diff --git a/fuzzer/corpus/61f39c557fde0b40d5e2fe7fbb3747d5c8b822a7 b/fuzzer/corpus/61f39c557fde0b40d5e2fe7fbb3747d5c8b822a7
new file mode 100644
index 0000000..cedcab4
--- /dev/null
+++ b/fuzzer/corpus/61f39c557fde0b40d5e2fe7fbb3747d5c8b822a7
Binary files differ
diff --git a/fuzzer/corpus/622482024bba090a3fdcf1683e6e82f3382d8086 b/fuzzer/corpus/622482024bba090a3fdcf1683e6e82f3382d8086
new file mode 100644
index 0000000..3135c08
--- /dev/null
+++ b/fuzzer/corpus/622482024bba090a3fdcf1683e6e82f3382d8086
Binary files differ
diff --git a/fuzzer/corpus/623a1074c0969b1c02dc5f11fc7efc12fea52d24 b/fuzzer/corpus/623a1074c0969b1c02dc5f11fc7efc12fea52d24
new file mode 100644
index 0000000..e6d9afa
--- /dev/null
+++ b/fuzzer/corpus/623a1074c0969b1c02dc5f11fc7efc12fea52d24
Binary files differ
diff --git a/fuzzer/corpus/6240592d3790fdf15fbd60321b06dd507cf22831 b/fuzzer/corpus/6240592d3790fdf15fbd60321b06dd507cf22831
new file mode 100644
index 0000000..356e6da
--- /dev/null
+++ b/fuzzer/corpus/6240592d3790fdf15fbd60321b06dd507cf22831
Binary files differ
diff --git a/fuzzer/corpus/626b74498e05ec6bc5d445f60f4dc60dba76336a b/fuzzer/corpus/626b74498e05ec6bc5d445f60f4dc60dba76336a
new file mode 100644
index 0000000..c0c6973
--- /dev/null
+++ b/fuzzer/corpus/626b74498e05ec6bc5d445f60f4dc60dba76336a
Binary files differ
diff --git a/fuzzer/corpus/627d90fcc60f0bf1f70d75c9a31d84139216e488 b/fuzzer/corpus/627d90fcc60f0bf1f70d75c9a31d84139216e488
new file mode 100644
index 0000000..0a79665
--- /dev/null
+++ b/fuzzer/corpus/627d90fcc60f0bf1f70d75c9a31d84139216e488
Binary files differ
diff --git a/fuzzer/corpus/629382ca7562123161a091d5f0d795a235b5ca95 b/fuzzer/corpus/629382ca7562123161a091d5f0d795a235b5ca95
new file mode 100644
index 0000000..0f8068d
--- /dev/null
+++ b/fuzzer/corpus/629382ca7562123161a091d5f0d795a235b5ca95
Binary files differ
diff --git a/fuzzer/corpus/62959435635107ddca7d9e4126a6f5d0c76fb1fd b/fuzzer/corpus/62959435635107ddca7d9e4126a6f5d0c76fb1fd
new file mode 100644
index 0000000..094f7f7
--- /dev/null
+++ b/fuzzer/corpus/62959435635107ddca7d9e4126a6f5d0c76fb1fd
Binary files differ
diff --git a/fuzzer/corpus/62aa7143e0e3298c6876a5f4dd7246847f6af3c7 b/fuzzer/corpus/62aa7143e0e3298c6876a5f4dd7246847f6af3c7
new file mode 100644
index 0000000..82562cd
--- /dev/null
+++ b/fuzzer/corpus/62aa7143e0e3298c6876a5f4dd7246847f6af3c7
Binary files differ
diff --git a/fuzzer/corpus/62b23c4cd05662a84d93389e973a6da6a2b8b410 b/fuzzer/corpus/62b23c4cd05662a84d93389e973a6da6a2b8b410
new file mode 100644
index 0000000..3840190
--- /dev/null
+++ b/fuzzer/corpus/62b23c4cd05662a84d93389e973a6da6a2b8b410
Binary files differ
diff --git a/fuzzer/corpus/6300716f023e6c5963aae1d4a456de340e099717 b/fuzzer/corpus/6300716f023e6c5963aae1d4a456de340e099717
new file mode 100644
index 0000000..b66735e
--- /dev/null
+++ b/fuzzer/corpus/6300716f023e6c5963aae1d4a456de340e099717
Binary files differ
diff --git a/fuzzer/corpus/630d4de33f784094077355d0d707a77a258d7848 b/fuzzer/corpus/630d4de33f784094077355d0d707a77a258d7848
new file mode 100644
index 0000000..8f7b684
--- /dev/null
+++ b/fuzzer/corpus/630d4de33f784094077355d0d707a77a258d7848
Binary files differ
diff --git a/fuzzer/corpus/6314c3808ec7e85751b4d7b742cdefdb1d6e5856 b/fuzzer/corpus/6314c3808ec7e85751b4d7b742cdefdb1d6e5856
new file mode 100644
index 0000000..52c97d6
--- /dev/null
+++ b/fuzzer/corpus/6314c3808ec7e85751b4d7b742cdefdb1d6e5856
Binary files differ
diff --git a/fuzzer/corpus/6317f6a493095cac0ca169a694f660d878919b01 b/fuzzer/corpus/6317f6a493095cac0ca169a694f660d878919b01
new file mode 100644
index 0000000..5f8a95d
--- /dev/null
+++ b/fuzzer/corpus/6317f6a493095cac0ca169a694f660d878919b01
Binary files differ
diff --git a/fuzzer/corpus/6364e84f407080cfe95722fe371595fce30ede1e b/fuzzer/corpus/6364e84f407080cfe95722fe371595fce30ede1e
new file mode 100644
index 0000000..6388fd3
--- /dev/null
+++ b/fuzzer/corpus/6364e84f407080cfe95722fe371595fce30ede1e
Binary files differ
diff --git a/fuzzer/corpus/6374541bb9f70f78ffa594342ea59578337b8b18 b/fuzzer/corpus/6374541bb9f70f78ffa594342ea59578337b8b18
new file mode 100644
index 0000000..6f3ef32
--- /dev/null
+++ b/fuzzer/corpus/6374541bb9f70f78ffa594342ea59578337b8b18
Binary files differ
diff --git a/fuzzer/corpus/63961e70de1b626a269c1da07b22e12d1bdbc080 b/fuzzer/corpus/63961e70de1b626a269c1da07b22e12d1bdbc080
new file mode 100644
index 0000000..16670b2
--- /dev/null
+++ b/fuzzer/corpus/63961e70de1b626a269c1da07b22e12d1bdbc080
Binary files differ
diff --git a/fuzzer/corpus/63bf338dc5d47dffab0f003a1c5a7c5621cca9ad b/fuzzer/corpus/63bf338dc5d47dffab0f003a1c5a7c5621cca9ad
new file mode 100644
index 0000000..50cc6f6
--- /dev/null
+++ b/fuzzer/corpus/63bf338dc5d47dffab0f003a1c5a7c5621cca9ad
Binary files differ
diff --git a/fuzzer/corpus/63ca389b82b7722d6a57d17ccf887e94dc378f68 b/fuzzer/corpus/63ca389b82b7722d6a57d17ccf887e94dc378f68
new file mode 100644
index 0000000..9b763b0
--- /dev/null
+++ b/fuzzer/corpus/63ca389b82b7722d6a57d17ccf887e94dc378f68
Binary files differ
diff --git a/fuzzer/corpus/63e4e38559bec6e6f834d2ef344929d0cad600ba b/fuzzer/corpus/63e4e38559bec6e6f834d2ef344929d0cad600ba
new file mode 100644
index 0000000..1ffff1c
--- /dev/null
+++ b/fuzzer/corpus/63e4e38559bec6e6f834d2ef344929d0cad600ba
Binary files differ
diff --git a/fuzzer/corpus/63e69871719679ce08615d1de566a614371cb4e3 b/fuzzer/corpus/63e69871719679ce08615d1de566a614371cb4e3
new file mode 100644
index 0000000..9a4aef9
--- /dev/null
+++ b/fuzzer/corpus/63e69871719679ce08615d1de566a614371cb4e3
Binary files differ
diff --git a/fuzzer/corpus/640580c9fd14ff70774f93394b5ca76cd2e83529 b/fuzzer/corpus/640580c9fd14ff70774f93394b5ca76cd2e83529
new file mode 100644
index 0000000..9bc232a
--- /dev/null
+++ b/fuzzer/corpus/640580c9fd14ff70774f93394b5ca76cd2e83529
Binary files differ
diff --git a/fuzzer/corpus/642a6b1533f4e765b30b75b115672a85d01e4365 b/fuzzer/corpus/642a6b1533f4e765b30b75b115672a85d01e4365
new file mode 100644
index 0000000..9168d6c
--- /dev/null
+++ b/fuzzer/corpus/642a6b1533f4e765b30b75b115672a85d01e4365
Binary files differ
diff --git a/fuzzer/corpus/64777b1e4c8a4527989efb144e2226f2fda89c78 b/fuzzer/corpus/64777b1e4c8a4527989efb144e2226f2fda89c78
new file mode 100644
index 0000000..b576f72
--- /dev/null
+++ b/fuzzer/corpus/64777b1e4c8a4527989efb144e2226f2fda89c78
Binary files differ
diff --git a/fuzzer/corpus/648e42a480516eb541712b5431709d711167b633 b/fuzzer/corpus/648e42a480516eb541712b5431709d711167b633
new file mode 100644
index 0000000..7c56a60
--- /dev/null
+++ b/fuzzer/corpus/648e42a480516eb541712b5431709d711167b633
Binary files differ
diff --git a/fuzzer/corpus/64913d4d83f772e4fe0423803e2852b30d0fefb0 b/fuzzer/corpus/64913d4d83f772e4fe0423803e2852b30d0fefb0
new file mode 100644
index 0000000..cbaf6be
--- /dev/null
+++ b/fuzzer/corpus/64913d4d83f772e4fe0423803e2852b30d0fefb0
Binary files differ
diff --git a/fuzzer/corpus/649666a82a6e54135c69c0570d39af075c72b74d b/fuzzer/corpus/649666a82a6e54135c69c0570d39af075c72b74d
new file mode 100644
index 0000000..36b7f9d
--- /dev/null
+++ b/fuzzer/corpus/649666a82a6e54135c69c0570d39af075c72b74d
Binary files differ
diff --git a/fuzzer/corpus/64a0471018b066406886ee21802fc46eac77c8b4 b/fuzzer/corpus/64a0471018b066406886ee21802fc46eac77c8b4
new file mode 100644
index 0000000..e1bae3a
--- /dev/null
+++ b/fuzzer/corpus/64a0471018b066406886ee21802fc46eac77c8b4
Binary files differ
diff --git a/fuzzer/corpus/64b49b5bd2d20ba64bea48d0d7766ad2c79408a6 b/fuzzer/corpus/64b49b5bd2d20ba64bea48d0d7766ad2c79408a6
new file mode 100644
index 0000000..760b2ce
--- /dev/null
+++ b/fuzzer/corpus/64b49b5bd2d20ba64bea48d0d7766ad2c79408a6
Binary files differ
diff --git a/fuzzer/corpus/64b549f9658ff3b1d1ab5649b705f77f72120898 b/fuzzer/corpus/64b549f9658ff3b1d1ab5649b705f77f72120898
new file mode 100644
index 0000000..38ce82c
--- /dev/null
+++ b/fuzzer/corpus/64b549f9658ff3b1d1ab5649b705f77f72120898
Binary files differ
diff --git a/fuzzer/corpus/64bc29377bd012c7df1b8a7bdc7f5475a4f0643d b/fuzzer/corpus/64bc29377bd012c7df1b8a7bdc7f5475a4f0643d
new file mode 100644
index 0000000..3f67686
--- /dev/null
+++ b/fuzzer/corpus/64bc29377bd012c7df1b8a7bdc7f5475a4f0643d
Binary files differ
diff --git a/fuzzer/corpus/64c4a66da785d46d25a68f571261e07d669019a3 b/fuzzer/corpus/64c4a66da785d46d25a68f571261e07d669019a3
new file mode 100644
index 0000000..b39c16d
--- /dev/null
+++ b/fuzzer/corpus/64c4a66da785d46d25a68f571261e07d669019a3
Binary files differ
diff --git a/fuzzer/corpus/64dc6434cd5154dbca58a499214a180c006662ce b/fuzzer/corpus/64dc6434cd5154dbca58a499214a180c006662ce
new file mode 100644
index 0000000..769e78a
--- /dev/null
+++ b/fuzzer/corpus/64dc6434cd5154dbca58a499214a180c006662ce
Binary files differ
diff --git a/fuzzer/corpus/65169785c05132f61cb0fe7a4cac4d83eccfc261 b/fuzzer/corpus/65169785c05132f61cb0fe7a4cac4d83eccfc261
new file mode 100644
index 0000000..512fe7a
--- /dev/null
+++ b/fuzzer/corpus/65169785c05132f61cb0fe7a4cac4d83eccfc261
Binary files differ
diff --git a/fuzzer/corpus/6519b017ccf082ce0b1a7670929e1e73547c16f5 b/fuzzer/corpus/6519b017ccf082ce0b1a7670929e1e73547c16f5
new file mode 100644
index 0000000..b5779a2
--- /dev/null
+++ b/fuzzer/corpus/6519b017ccf082ce0b1a7670929e1e73547c16f5
Binary files differ
diff --git a/fuzzer/corpus/654041ce1022141719a977cf50e702d2686afb2d b/fuzzer/corpus/654041ce1022141719a977cf50e702d2686afb2d
new file mode 100644
index 0000000..989c095
--- /dev/null
+++ b/fuzzer/corpus/654041ce1022141719a977cf50e702d2686afb2d
Binary files differ
diff --git a/fuzzer/corpus/654638b7d49e574401a253175531490edc4bd788 b/fuzzer/corpus/654638b7d49e574401a253175531490edc4bd788
new file mode 100644
index 0000000..5ec696b
--- /dev/null
+++ b/fuzzer/corpus/654638b7d49e574401a253175531490edc4bd788
Binary files differ
diff --git a/fuzzer/corpus/65505a2237073f73dbf9cf827e743adef46e97c0 b/fuzzer/corpus/65505a2237073f73dbf9cf827e743adef46e97c0
new file mode 100644
index 0000000..76a4648
--- /dev/null
+++ b/fuzzer/corpus/65505a2237073f73dbf9cf827e743adef46e97c0
Binary files differ
diff --git a/fuzzer/corpus/6552662b273f17b5c04d28e15daa334e7dd1e283 b/fuzzer/corpus/6552662b273f17b5c04d28e15daa334e7dd1e283
new file mode 100644
index 0000000..64a454e
--- /dev/null
+++ b/fuzzer/corpus/6552662b273f17b5c04d28e15daa334e7dd1e283
Binary files differ
diff --git a/fuzzer/corpus/655e5fa01790ddc5c121f3c41e0a06c6d3dfb41a b/fuzzer/corpus/655e5fa01790ddc5c121f3c41e0a06c6d3dfb41a
new file mode 100644
index 0000000..98f87f1
--- /dev/null
+++ b/fuzzer/corpus/655e5fa01790ddc5c121f3c41e0a06c6d3dfb41a
Binary files differ
diff --git a/fuzzer/corpus/656817d0384adc45c1846f58001d4a2817d6dfe8 b/fuzzer/corpus/656817d0384adc45c1846f58001d4a2817d6dfe8
new file mode 100644
index 0000000..1c98012
--- /dev/null
+++ b/fuzzer/corpus/656817d0384adc45c1846f58001d4a2817d6dfe8
Binary files differ
diff --git a/fuzzer/corpus/65686a887886829e0edc41d9d34cafecea09eb11 b/fuzzer/corpus/65686a887886829e0edc41d9d34cafecea09eb11
new file mode 100644
index 0000000..8ca96c3
--- /dev/null
+++ b/fuzzer/corpus/65686a887886829e0edc41d9d34cafecea09eb11
Binary files differ
diff --git a/fuzzer/corpus/65690bee1d02b8c2a2c5b7b02b0e4d5e79d25934 b/fuzzer/corpus/65690bee1d02b8c2a2c5b7b02b0e4d5e79d25934
new file mode 100644
index 0000000..a490b99
--- /dev/null
+++ b/fuzzer/corpus/65690bee1d02b8c2a2c5b7b02b0e4d5e79d25934
Binary files differ
diff --git a/fuzzer/corpus/65a24581d01b510d102c9b5a29b48dd081f9fbf8 b/fuzzer/corpus/65a24581d01b510d102c9b5a29b48dd081f9fbf8
new file mode 100644
index 0000000..65ca1ff
--- /dev/null
+++ b/fuzzer/corpus/65a24581d01b510d102c9b5a29b48dd081f9fbf8
Binary files differ
diff --git a/fuzzer/corpus/65ba55f8e41894702c8d2e9df35b8b17197345d1 b/fuzzer/corpus/65ba55f8e41894702c8d2e9df35b8b17197345d1
new file mode 100644
index 0000000..74bb08f
--- /dev/null
+++ b/fuzzer/corpus/65ba55f8e41894702c8d2e9df35b8b17197345d1
Binary files differ
diff --git a/fuzzer/corpus/65dda6438e7d606cc149433add5df57db4e2dc62 b/fuzzer/corpus/65dda6438e7d606cc149433add5df57db4e2dc62
new file mode 100644
index 0000000..970ac01
--- /dev/null
+++ b/fuzzer/corpus/65dda6438e7d606cc149433add5df57db4e2dc62
Binary files differ
diff --git a/fuzzer/corpus/65fda704bb8e39446ad2aa103004305ad1eafabf b/fuzzer/corpus/65fda704bb8e39446ad2aa103004305ad1eafabf
new file mode 100644
index 0000000..abc298a
--- /dev/null
+++ b/fuzzer/corpus/65fda704bb8e39446ad2aa103004305ad1eafabf
Binary files differ
diff --git a/fuzzer/corpus/661f78aeacd3ba77d84959e5824fb5842d375da8 b/fuzzer/corpus/661f78aeacd3ba77d84959e5824fb5842d375da8
new file mode 100644
index 0000000..4fe460b
--- /dev/null
+++ b/fuzzer/corpus/661f78aeacd3ba77d84959e5824fb5842d375da8
Binary files differ
diff --git a/fuzzer/corpus/6622b04b6c6539d170a6c203f7c8047a2627ef1a b/fuzzer/corpus/6622b04b6c6539d170a6c203f7c8047a2627ef1a
new file mode 100644
index 0000000..0e79b60
--- /dev/null
+++ b/fuzzer/corpus/6622b04b6c6539d170a6c203f7c8047a2627ef1a
Binary files differ
diff --git a/fuzzer/corpus/666c2f6d446832815b4142f23c41f946c744a506 b/fuzzer/corpus/666c2f6d446832815b4142f23c41f946c744a506
new file mode 100644
index 0000000..831f2b6
--- /dev/null
+++ b/fuzzer/corpus/666c2f6d446832815b4142f23c41f946c744a506
Binary files differ
diff --git a/fuzzer/corpus/66701a843b5dffba78ad7e1e6c44cfc806ab31ff b/fuzzer/corpus/66701a843b5dffba78ad7e1e6c44cfc806ab31ff
new file mode 100644
index 0000000..8c4c3aa
--- /dev/null
+++ b/fuzzer/corpus/66701a843b5dffba78ad7e1e6c44cfc806ab31ff
Binary files differ
diff --git a/fuzzer/corpus/668d1a8784fc7de20c2eb87f613a517cbf42d080 b/fuzzer/corpus/668d1a8784fc7de20c2eb87f613a517cbf42d080
new file mode 100644
index 0000000..26c4c2e
--- /dev/null
+++ b/fuzzer/corpus/668d1a8784fc7de20c2eb87f613a517cbf42d080
Binary files differ
diff --git a/fuzzer/corpus/66b27b57d4d7de1c90d7ee89bbd43c5468f21f52 b/fuzzer/corpus/66b27b57d4d7de1c90d7ee89bbd43c5468f21f52
new file mode 100644
index 0000000..6b44c5a
--- /dev/null
+++ b/fuzzer/corpus/66b27b57d4d7de1c90d7ee89bbd43c5468f21f52
Binary files differ
diff --git a/fuzzer/corpus/66b586f381f61302f2e7058a5b53361e7b8135f2 b/fuzzer/corpus/66b586f381f61302f2e7058a5b53361e7b8135f2
new file mode 100644
index 0000000..3356fa2
--- /dev/null
+++ b/fuzzer/corpus/66b586f381f61302f2e7058a5b53361e7b8135f2
Binary files differ
diff --git a/fuzzer/corpus/66b87b59b7233b0c628c1061b6058336157f50cf b/fuzzer/corpus/66b87b59b7233b0c628c1061b6058336157f50cf
new file mode 100644
index 0000000..a4d031f
--- /dev/null
+++ b/fuzzer/corpus/66b87b59b7233b0c628c1061b6058336157f50cf
Binary files differ
diff --git a/fuzzer/corpus/66ba0612397b891e0d5ec9a985b824650ba536c4 b/fuzzer/corpus/66ba0612397b891e0d5ec9a985b824650ba536c4
new file mode 100644
index 0000000..208d249
--- /dev/null
+++ b/fuzzer/corpus/66ba0612397b891e0d5ec9a985b824650ba536c4
Binary files differ
diff --git a/fuzzer/corpus/66e5621c43fc9403d3e093d20018379455932343 b/fuzzer/corpus/66e5621c43fc9403d3e093d20018379455932343
new file mode 100644
index 0000000..703f139
--- /dev/null
+++ b/fuzzer/corpus/66e5621c43fc9403d3e093d20018379455932343
Binary files differ
diff --git a/fuzzer/corpus/67278b928ece08b649bb41dd10a477f20f965570 b/fuzzer/corpus/67278b928ece08b649bb41dd10a477f20f965570
new file mode 100644
index 0000000..7b10a81
--- /dev/null
+++ b/fuzzer/corpus/67278b928ece08b649bb41dd10a477f20f965570
Binary files differ
diff --git a/fuzzer/corpus/6745bbeb17c4281b97cee9be2f04b25f9b0bffe8 b/fuzzer/corpus/6745bbeb17c4281b97cee9be2f04b25f9b0bffe8
new file mode 100644
index 0000000..84a5924
--- /dev/null
+++ b/fuzzer/corpus/6745bbeb17c4281b97cee9be2f04b25f9b0bffe8
Binary files differ
diff --git a/fuzzer/corpus/6756444b0a6fed74818a7ee4e7f56c23577ca520 b/fuzzer/corpus/6756444b0a6fed74818a7ee4e7f56c23577ca520
new file mode 100644
index 0000000..05b83fd
--- /dev/null
+++ b/fuzzer/corpus/6756444b0a6fed74818a7ee4e7f56c23577ca520
Binary files differ
diff --git a/fuzzer/corpus/67630f5a980563718164a404ee8e24148c120bb8 b/fuzzer/corpus/67630f5a980563718164a404ee8e24148c120bb8
new file mode 100644
index 0000000..bcf712e
--- /dev/null
+++ b/fuzzer/corpus/67630f5a980563718164a404ee8e24148c120bb8
Binary files differ
diff --git a/fuzzer/corpus/680ac624889085a04c01325b19dca2ebddb9beda b/fuzzer/corpus/680ac624889085a04c01325b19dca2ebddb9beda
new file mode 100644
index 0000000..40deee7
--- /dev/null
+++ b/fuzzer/corpus/680ac624889085a04c01325b19dca2ebddb9beda
Binary files differ
diff --git a/fuzzer/corpus/6852c0ab304a4b0503da5ab3c4c3bb2cb47fb964 b/fuzzer/corpus/6852c0ab304a4b0503da5ab3c4c3bb2cb47fb964
new file mode 100644
index 0000000..e90b07b
--- /dev/null
+++ b/fuzzer/corpus/6852c0ab304a4b0503da5ab3c4c3bb2cb47fb964
Binary files differ
diff --git a/fuzzer/corpus/68655185e37a948f14d5e22748576cb4d8ab7cc5 b/fuzzer/corpus/68655185e37a948f14d5e22748576cb4d8ab7cc5
new file mode 100644
index 0000000..9e80356
--- /dev/null
+++ b/fuzzer/corpus/68655185e37a948f14d5e22748576cb4d8ab7cc5
Binary files differ
diff --git a/fuzzer/corpus/687375f623183b3f91d4dbbc6d811d3772a94fe4 b/fuzzer/corpus/687375f623183b3f91d4dbbc6d811d3772a94fe4
new file mode 100644
index 0000000..de7fc32
--- /dev/null
+++ b/fuzzer/corpus/687375f623183b3f91d4dbbc6d811d3772a94fe4
Binary files differ
diff --git a/fuzzer/corpus/6883b75c90df30d660e6d7b966c1ec516df0171e b/fuzzer/corpus/6883b75c90df30d660e6d7b966c1ec516df0171e
new file mode 100644
index 0000000..0b4a6f1
--- /dev/null
+++ b/fuzzer/corpus/6883b75c90df30d660e6d7b966c1ec516df0171e
Binary files differ
diff --git a/fuzzer/corpus/6896f40df04bf1bdfcfa03df222b6e99bbb7aadd b/fuzzer/corpus/6896f40df04bf1bdfcfa03df222b6e99bbb7aadd
new file mode 100644
index 0000000..c5f88e7
--- /dev/null
+++ b/fuzzer/corpus/6896f40df04bf1bdfcfa03df222b6e99bbb7aadd
Binary files differ
diff --git a/fuzzer/corpus/689b5a59a782b95c72f11da560c6e6a13259eea0 b/fuzzer/corpus/689b5a59a782b95c72f11da560c6e6a13259eea0
new file mode 100644
index 0000000..4d7bf23
--- /dev/null
+++ b/fuzzer/corpus/689b5a59a782b95c72f11da560c6e6a13259eea0
Binary files differ
diff --git a/fuzzer/corpus/68afd8113b1f5dc78c6e363fa7b3235bb9f3e998 b/fuzzer/corpus/68afd8113b1f5dc78c6e363fa7b3235bb9f3e998
new file mode 100644
index 0000000..aea831a
--- /dev/null
+++ b/fuzzer/corpus/68afd8113b1f5dc78c6e363fa7b3235bb9f3e998
Binary files differ
diff --git a/fuzzer/corpus/68cd0772f3b8b697bf0883a6b3324ecceb820962 b/fuzzer/corpus/68cd0772f3b8b697bf0883a6b3324ecceb820962
new file mode 100644
index 0000000..e63676c
--- /dev/null
+++ b/fuzzer/corpus/68cd0772f3b8b697bf0883a6b3324ecceb820962
Binary files differ
diff --git a/fuzzer/corpus/68f7d41620a0c7ddec132492611badf720f6b5cd b/fuzzer/corpus/68f7d41620a0c7ddec132492611badf720f6b5cd
new file mode 100644
index 0000000..8f26808
--- /dev/null
+++ b/fuzzer/corpus/68f7d41620a0c7ddec132492611badf720f6b5cd
Binary files differ
diff --git a/fuzzer/corpus/691f85fd1300bd2e5746fdc9bef75768040ece0b b/fuzzer/corpus/691f85fd1300bd2e5746fdc9bef75768040ece0b
new file mode 100644
index 0000000..69066f4
--- /dev/null
+++ b/fuzzer/corpus/691f85fd1300bd2e5746fdc9bef75768040ece0b
Binary files differ
diff --git a/fuzzer/corpus/69217d1e52829e915878d9886d2219317400a4fb b/fuzzer/corpus/69217d1e52829e915878d9886d2219317400a4fb
new file mode 100644
index 0000000..dcc0ee3
--- /dev/null
+++ b/fuzzer/corpus/69217d1e52829e915878d9886d2219317400a4fb
Binary files differ
diff --git a/fuzzer/corpus/6967d470ff997b6398be723dc3d3ce9364a56885 b/fuzzer/corpus/6967d470ff997b6398be723dc3d3ce9364a56885
new file mode 100644
index 0000000..f7e8d73
--- /dev/null
+++ b/fuzzer/corpus/6967d470ff997b6398be723dc3d3ce9364a56885
Binary files differ
diff --git a/fuzzer/corpus/69c251669ae44e3eced748d2199b1dc431196b6c b/fuzzer/corpus/69c251669ae44e3eced748d2199b1dc431196b6c
new file mode 100644
index 0000000..b55917f
--- /dev/null
+++ b/fuzzer/corpus/69c251669ae44e3eced748d2199b1dc431196b6c
Binary files differ
diff --git a/fuzzer/corpus/69c3e05de7d033aefde7f8044c9ee29988c2046d b/fuzzer/corpus/69c3e05de7d033aefde7f8044c9ee29988c2046d
new file mode 100644
index 0000000..8439d4f
--- /dev/null
+++ b/fuzzer/corpus/69c3e05de7d033aefde7f8044c9ee29988c2046d
Binary files differ
diff --git a/fuzzer/corpus/69c3fde5efff19e925d9ddd1d3ea12111a603aac b/fuzzer/corpus/69c3fde5efff19e925d9ddd1d3ea12111a603aac
new file mode 100644
index 0000000..9b48ab4
--- /dev/null
+++ b/fuzzer/corpus/69c3fde5efff19e925d9ddd1d3ea12111a603aac
Binary files differ
diff --git a/fuzzer/corpus/69cae98d93cf1a78af05aec89b343ff693445378 b/fuzzer/corpus/69cae98d93cf1a78af05aec89b343ff693445378
new file mode 100644
index 0000000..fd26658
--- /dev/null
+++ b/fuzzer/corpus/69cae98d93cf1a78af05aec89b343ff693445378
Binary files differ
diff --git a/fuzzer/corpus/6a0592a9b603e91657d7ef842fe0343287577d83 b/fuzzer/corpus/6a0592a9b603e91657d7ef842fe0343287577d83
new file mode 100644
index 0000000..69bc843
--- /dev/null
+++ b/fuzzer/corpus/6a0592a9b603e91657d7ef842fe0343287577d83
Binary files differ
diff --git a/fuzzer/corpus/6a237c7db7dd04afb407ebb379f5cec036c6f6ad b/fuzzer/corpus/6a237c7db7dd04afb407ebb379f5cec036c6f6ad
new file mode 100644
index 0000000..8914fd9
--- /dev/null
+++ b/fuzzer/corpus/6a237c7db7dd04afb407ebb379f5cec036c6f6ad
Binary files differ
diff --git a/fuzzer/corpus/6a2e403401c57d45174788ef50b720afdd9b9d4b b/fuzzer/corpus/6a2e403401c57d45174788ef50b720afdd9b9d4b
new file mode 100644
index 0000000..9bca8bd
--- /dev/null
+++ b/fuzzer/corpus/6a2e403401c57d45174788ef50b720afdd9b9d4b
Binary files differ
diff --git a/fuzzer/corpus/6a716e6e19ded33bf8a122c334d86e4b24be29fa b/fuzzer/corpus/6a716e6e19ded33bf8a122c334d86e4b24be29fa
new file mode 100644
index 0000000..06424b4
--- /dev/null
+++ b/fuzzer/corpus/6a716e6e19ded33bf8a122c334d86e4b24be29fa
Binary files differ
diff --git a/fuzzer/corpus/6a7460d2afcb28811279ace5576a11f8b308b7ec b/fuzzer/corpus/6a7460d2afcb28811279ace5576a11f8b308b7ec
new file mode 100644
index 0000000..8791ab5
--- /dev/null
+++ b/fuzzer/corpus/6a7460d2afcb28811279ace5576a11f8b308b7ec
Binary files differ
diff --git a/fuzzer/corpus/6a9b91a7baaaf95e8f33593d92a08fbfe955d256 b/fuzzer/corpus/6a9b91a7baaaf95e8f33593d92a08fbfe955d256
new file mode 100644
index 0000000..bc68fdf
--- /dev/null
+++ b/fuzzer/corpus/6a9b91a7baaaf95e8f33593d92a08fbfe955d256
Binary files differ
diff --git a/fuzzer/corpus/6abba7f854ad692202a9cd2f470a548f41c7c587 b/fuzzer/corpus/6abba7f854ad692202a9cd2f470a548f41c7c587
new file mode 100644
index 0000000..d8dabc9
--- /dev/null
+++ b/fuzzer/corpus/6abba7f854ad692202a9cd2f470a548f41c7c587
Binary files differ
diff --git a/fuzzer/corpus/6ac1f2adf0a276b930ac333f30e61009d3932ba0 b/fuzzer/corpus/6ac1f2adf0a276b930ac333f30e61009d3932ba0
new file mode 100644
index 0000000..93f45bb
--- /dev/null
+++ b/fuzzer/corpus/6ac1f2adf0a276b930ac333f30e61009d3932ba0
Binary files differ
diff --git a/fuzzer/corpus/6afe5384c398e825595d124e174f5e403153e1b8 b/fuzzer/corpus/6afe5384c398e825595d124e174f5e403153e1b8
new file mode 100644
index 0000000..a06dc60
--- /dev/null
+++ b/fuzzer/corpus/6afe5384c398e825595d124e174f5e403153e1b8
Binary files differ
diff --git a/fuzzer/corpus/6b1393f61366e6ab27d618e095db5652dd640853 b/fuzzer/corpus/6b1393f61366e6ab27d618e095db5652dd640853
new file mode 100644
index 0000000..43f209e
--- /dev/null
+++ b/fuzzer/corpus/6b1393f61366e6ab27d618e095db5652dd640853
Binary files differ
diff --git a/fuzzer/corpus/6b285d460e5309ad9d2e141c37ee6e50432f06a1 b/fuzzer/corpus/6b285d460e5309ad9d2e141c37ee6e50432f06a1
new file mode 100644
index 0000000..d84446e
--- /dev/null
+++ b/fuzzer/corpus/6b285d460e5309ad9d2e141c37ee6e50432f06a1
Binary files differ
diff --git a/fuzzer/corpus/6b296b18dc6f859767385a7a1afb4e873b758285 b/fuzzer/corpus/6b296b18dc6f859767385a7a1afb4e873b758285
new file mode 100644
index 0000000..74fa6df
--- /dev/null
+++ b/fuzzer/corpus/6b296b18dc6f859767385a7a1afb4e873b758285
Binary files differ
diff --git a/fuzzer/corpus/6b4e197ca4238a48008c54faa8e6a44a3447cd74 b/fuzzer/corpus/6b4e197ca4238a48008c54faa8e6a44a3447cd74
new file mode 100644
index 0000000..76be326
--- /dev/null
+++ b/fuzzer/corpus/6b4e197ca4238a48008c54faa8e6a44a3447cd74
Binary files differ
diff --git a/fuzzer/corpus/6b5f61a47bbe9c1058e2d7b6248f2c4a532ae0c2 b/fuzzer/corpus/6b5f61a47bbe9c1058e2d7b6248f2c4a532ae0c2
new file mode 100644
index 0000000..ada096d
--- /dev/null
+++ b/fuzzer/corpus/6b5f61a47bbe9c1058e2d7b6248f2c4a532ae0c2
Binary files differ
diff --git a/fuzzer/corpus/6ba5f404e1f4c1a61205ca8819686c19b8a7e72d b/fuzzer/corpus/6ba5f404e1f4c1a61205ca8819686c19b8a7e72d
new file mode 100644
index 0000000..ade91dc
--- /dev/null
+++ b/fuzzer/corpus/6ba5f404e1f4c1a61205ca8819686c19b8a7e72d
Binary files differ
diff --git a/fuzzer/corpus/6bc23a666a9a3964a045462b36d4ac19f0355323 b/fuzzer/corpus/6bc23a666a9a3964a045462b36d4ac19f0355323
new file mode 100644
index 0000000..7198c45
--- /dev/null
+++ b/fuzzer/corpus/6bc23a666a9a3964a045462b36d4ac19f0355323
Binary files differ
diff --git a/fuzzer/corpus/6bc8f0d768c1b81bd2280da42902103f8feb64c7 b/fuzzer/corpus/6bc8f0d768c1b81bd2280da42902103f8feb64c7
new file mode 100644
index 0000000..425adcd
--- /dev/null
+++ b/fuzzer/corpus/6bc8f0d768c1b81bd2280da42902103f8feb64c7
Binary files differ
diff --git a/fuzzer/corpus/6bdde9f513ee4f442b4a3b1eea8b3cc47d812e5e b/fuzzer/corpus/6bdde9f513ee4f442b4a3b1eea8b3cc47d812e5e
new file mode 100644
index 0000000..712d42c
--- /dev/null
+++ b/fuzzer/corpus/6bdde9f513ee4f442b4a3b1eea8b3cc47d812e5e
Binary files differ
diff --git a/fuzzer/corpus/6c165f1717d532249cdf43720fd746883396d020 b/fuzzer/corpus/6c165f1717d532249cdf43720fd746883396d020
new file mode 100644
index 0000000..b876c28
--- /dev/null
+++ b/fuzzer/corpus/6c165f1717d532249cdf43720fd746883396d020
Binary files differ
diff --git a/fuzzer/corpus/6c1cc0329fd20f56a8d91897348cf5faa5f953c3 b/fuzzer/corpus/6c1cc0329fd20f56a8d91897348cf5faa5f953c3
new file mode 100644
index 0000000..6ce0fa4
--- /dev/null
+++ b/fuzzer/corpus/6c1cc0329fd20f56a8d91897348cf5faa5f953c3
Binary files differ
diff --git a/fuzzer/corpus/6c232a2066785dafb0b517009ee1c90380c5fe24 b/fuzzer/corpus/6c232a2066785dafb0b517009ee1c90380c5fe24
new file mode 100644
index 0000000..ac4e4a7
--- /dev/null
+++ b/fuzzer/corpus/6c232a2066785dafb0b517009ee1c90380c5fe24
Binary files differ
diff --git a/fuzzer/corpus/6c464ff758fc5da32f56415ea4d312ea0787fe52 b/fuzzer/corpus/6c464ff758fc5da32f56415ea4d312ea0787fe52
new file mode 100644
index 0000000..4f509ab
--- /dev/null
+++ b/fuzzer/corpus/6c464ff758fc5da32f56415ea4d312ea0787fe52
Binary files differ
diff --git a/fuzzer/corpus/6c506ead05f651d80e1ae8bd0d4510ea68174972 b/fuzzer/corpus/6c506ead05f651d80e1ae8bd0d4510ea68174972
new file mode 100644
index 0000000..31b206a
--- /dev/null
+++ b/fuzzer/corpus/6c506ead05f651d80e1ae8bd0d4510ea68174972
Binary files differ
diff --git a/fuzzer/corpus/6c5328b0c624f44f8ccf49ea0c819e94d4afebfd b/fuzzer/corpus/6c5328b0c624f44f8ccf49ea0c819e94d4afebfd
new file mode 100644
index 0000000..cf928c6
--- /dev/null
+++ b/fuzzer/corpus/6c5328b0c624f44f8ccf49ea0c819e94d4afebfd
Binary files differ
diff --git a/fuzzer/corpus/6c61eeb721779feda1ea0e9c706ac4cb858e5d6d b/fuzzer/corpus/6c61eeb721779feda1ea0e9c706ac4cb858e5d6d
new file mode 100644
index 0000000..fdba90a
--- /dev/null
+++ b/fuzzer/corpus/6c61eeb721779feda1ea0e9c706ac4cb858e5d6d
Binary files differ
diff --git a/fuzzer/corpus/6cabfbf82683b2378758215959a71fa0afa7bb2b b/fuzzer/corpus/6cabfbf82683b2378758215959a71fa0afa7bb2b
new file mode 100644
index 0000000..e13182d
--- /dev/null
+++ b/fuzzer/corpus/6cabfbf82683b2378758215959a71fa0afa7bb2b
Binary files differ
diff --git a/fuzzer/corpus/6cf49e1edbe3662a9f9c3eda6c221edfc1ae1de3 b/fuzzer/corpus/6cf49e1edbe3662a9f9c3eda6c221edfc1ae1de3
new file mode 100644
index 0000000..7ed19b4
--- /dev/null
+++ b/fuzzer/corpus/6cf49e1edbe3662a9f9c3eda6c221edfc1ae1de3
Binary files differ
diff --git a/fuzzer/corpus/6d63a35f78c5150ceb4ce1ca98ec8ff95f4684e6 b/fuzzer/corpus/6d63a35f78c5150ceb4ce1ca98ec8ff95f4684e6
new file mode 100644
index 0000000..06b3f05
--- /dev/null
+++ b/fuzzer/corpus/6d63a35f78c5150ceb4ce1ca98ec8ff95f4684e6
Binary files differ
diff --git a/fuzzer/corpus/6d6c93b5582cdc7fdad3d1dd778c61c6e1990b9a b/fuzzer/corpus/6d6c93b5582cdc7fdad3d1dd778c61c6e1990b9a
new file mode 100644
index 0000000..8d459d9
--- /dev/null
+++ b/fuzzer/corpus/6d6c93b5582cdc7fdad3d1dd778c61c6e1990b9a
Binary files differ
diff --git a/fuzzer/corpus/6d8e0536752ddbb305adfd65f1be91358ff7aa99 b/fuzzer/corpus/6d8e0536752ddbb305adfd65f1be91358ff7aa99
new file mode 100644
index 0000000..3b43389
--- /dev/null
+++ b/fuzzer/corpus/6d8e0536752ddbb305adfd65f1be91358ff7aa99
Binary files differ
diff --git a/fuzzer/corpus/6d8e5a6ba49e6fb393694bc7fdcdf4034aa59583 b/fuzzer/corpus/6d8e5a6ba49e6fb393694bc7fdcdf4034aa59583
new file mode 100644
index 0000000..e6451ce
--- /dev/null
+++ b/fuzzer/corpus/6d8e5a6ba49e6fb393694bc7fdcdf4034aa59583
Binary files differ
diff --git a/fuzzer/corpus/6d9bcef0193d298b54d7d03635f2a5d755e3ad2c b/fuzzer/corpus/6d9bcef0193d298b54d7d03635f2a5d755e3ad2c
new file mode 100644
index 0000000..0507b02
--- /dev/null
+++ b/fuzzer/corpus/6d9bcef0193d298b54d7d03635f2a5d755e3ad2c
Binary files differ
diff --git a/fuzzer/corpus/6da3f86619934a68744f1f90bd569cc8d53e97d5 b/fuzzer/corpus/6da3f86619934a68744f1f90bd569cc8d53e97d5
new file mode 100644
index 0000000..7ddb4ba
--- /dev/null
+++ b/fuzzer/corpus/6da3f86619934a68744f1f90bd569cc8d53e97d5
Binary files differ
diff --git a/fuzzer/corpus/6da74210deac7eeed903ca6c059d2b0adb942a8e b/fuzzer/corpus/6da74210deac7eeed903ca6c059d2b0adb942a8e
new file mode 100644
index 0000000..990f2c8
--- /dev/null
+++ b/fuzzer/corpus/6da74210deac7eeed903ca6c059d2b0adb942a8e
Binary files differ
diff --git a/fuzzer/corpus/6dc013b62c35f729a9eb71008215d4c64457a0f6 b/fuzzer/corpus/6dc013b62c35f729a9eb71008215d4c64457a0f6
new file mode 100644
index 0000000..91b0909
--- /dev/null
+++ b/fuzzer/corpus/6dc013b62c35f729a9eb71008215d4c64457a0f6
Binary files differ
diff --git a/fuzzer/corpus/6dddd2c93c97ec6b7dfc6e73dd7602bd4099f384 b/fuzzer/corpus/6dddd2c93c97ec6b7dfc6e73dd7602bd4099f384
new file mode 100644
index 0000000..51ff132
--- /dev/null
+++ b/fuzzer/corpus/6dddd2c93c97ec6b7dfc6e73dd7602bd4099f384
Binary files differ
diff --git a/fuzzer/corpus/6dee58677ab1dda486feaa2d72dd789605a4d7e8 b/fuzzer/corpus/6dee58677ab1dda486feaa2d72dd789605a4d7e8
new file mode 100644
index 0000000..3dce7fe
--- /dev/null
+++ b/fuzzer/corpus/6dee58677ab1dda486feaa2d72dd789605a4d7e8
Binary files differ
diff --git a/fuzzer/corpus/6e22495ba490e0ee875284788badb9c14eaa0e69 b/fuzzer/corpus/6e22495ba490e0ee875284788badb9c14eaa0e69
new file mode 100644
index 0000000..cd2d1b1
--- /dev/null
+++ b/fuzzer/corpus/6e22495ba490e0ee875284788badb9c14eaa0e69
Binary files differ
diff --git a/fuzzer/corpus/6e23c1f30efe0d956cb742e503ea7658e07cfa02 b/fuzzer/corpus/6e23c1f30efe0d956cb742e503ea7658e07cfa02
new file mode 100644
index 0000000..de63aa8
--- /dev/null
+++ b/fuzzer/corpus/6e23c1f30efe0d956cb742e503ea7658e07cfa02
Binary files differ
diff --git a/fuzzer/corpus/6e38f2a1804a36b5667b60f6a1731aed2549873f b/fuzzer/corpus/6e38f2a1804a36b5667b60f6a1731aed2549873f
new file mode 100644
index 0000000..737ff94
--- /dev/null
+++ b/fuzzer/corpus/6e38f2a1804a36b5667b60f6a1731aed2549873f
Binary files differ
diff --git a/fuzzer/corpus/6e39726dcdcfe6bb695fd902a5028f4fb8a6fb9a b/fuzzer/corpus/6e39726dcdcfe6bb695fd902a5028f4fb8a6fb9a
new file mode 100644
index 0000000..de69be7
--- /dev/null
+++ b/fuzzer/corpus/6e39726dcdcfe6bb695fd902a5028f4fb8a6fb9a
Binary files differ
diff --git a/fuzzer/corpus/6e42d7365c2f21d5bc4eb1f73135670519597f20 b/fuzzer/corpus/6e42d7365c2f21d5bc4eb1f73135670519597f20
new file mode 100644
index 0000000..e8e92fc
--- /dev/null
+++ b/fuzzer/corpus/6e42d7365c2f21d5bc4eb1f73135670519597f20
Binary files differ
diff --git a/fuzzer/corpus/6e5e3e737a9fb09147a771b5290bfd8cd1f76aa3 b/fuzzer/corpus/6e5e3e737a9fb09147a771b5290bfd8cd1f76aa3
new file mode 100644
index 0000000..a63e27d
--- /dev/null
+++ b/fuzzer/corpus/6e5e3e737a9fb09147a771b5290bfd8cd1f76aa3
Binary files differ
diff --git a/fuzzer/corpus/6e5fa073de61a515f4fdd0117c509fc1ba8edab3 b/fuzzer/corpus/6e5fa073de61a515f4fdd0117c509fc1ba8edab3
new file mode 100644
index 0000000..4844e6c
--- /dev/null
+++ b/fuzzer/corpus/6e5fa073de61a515f4fdd0117c509fc1ba8edab3
Binary files differ
diff --git a/fuzzer/corpus/6e89c0bd2c624eaf3aa5669c2660ecaa499be4ac b/fuzzer/corpus/6e89c0bd2c624eaf3aa5669c2660ecaa499be4ac
new file mode 100644
index 0000000..1bdc9a2
--- /dev/null
+++ b/fuzzer/corpus/6e89c0bd2c624eaf3aa5669c2660ecaa499be4ac
Binary files differ
diff --git a/fuzzer/corpus/6ebb0862deb584ba9219dbdfdc4b4d74109843dd b/fuzzer/corpus/6ebb0862deb584ba9219dbdfdc4b4d74109843dd
new file mode 100644
index 0000000..0a83f61
--- /dev/null
+++ b/fuzzer/corpus/6ebb0862deb584ba9219dbdfdc4b4d74109843dd
Binary files differ
diff --git a/fuzzer/corpus/6ebb3b2e935646d3e2f02eec8f13219db747732d b/fuzzer/corpus/6ebb3b2e935646d3e2f02eec8f13219db747732d
new file mode 100644
index 0000000..8661ab7
--- /dev/null
+++ b/fuzzer/corpus/6ebb3b2e935646d3e2f02eec8f13219db747732d
Binary files differ
diff --git a/fuzzer/corpus/6edde592b588d9013667a98ca56af9cd19af386b b/fuzzer/corpus/6edde592b588d9013667a98ca56af9cd19af386b
new file mode 100644
index 0000000..23d9de2
--- /dev/null
+++ b/fuzzer/corpus/6edde592b588d9013667a98ca56af9cd19af386b
Binary files differ
diff --git a/fuzzer/corpus/6ee0ea0911fe6ce73316255b0b5b2bb3bd103e6c b/fuzzer/corpus/6ee0ea0911fe6ce73316255b0b5b2bb3bd103e6c
new file mode 100644
index 0000000..ac75d5b
--- /dev/null
+++ b/fuzzer/corpus/6ee0ea0911fe6ce73316255b0b5b2bb3bd103e6c
Binary files differ
diff --git a/fuzzer/corpus/6f15d9f4f8330bee8bc89e4b45c8645fe94dc02a b/fuzzer/corpus/6f15d9f4f8330bee8bc89e4b45c8645fe94dc02a
new file mode 100644
index 0000000..0f8c442
--- /dev/null
+++ b/fuzzer/corpus/6f15d9f4f8330bee8bc89e4b45c8645fe94dc02a
Binary files differ
diff --git a/fuzzer/corpus/6f162cea130c89a0059ee343501343de3d01855a b/fuzzer/corpus/6f162cea130c89a0059ee343501343de3d01855a
new file mode 100644
index 0000000..81e6ab9
--- /dev/null
+++ b/fuzzer/corpus/6f162cea130c89a0059ee343501343de3d01855a
Binary files differ
diff --git a/fuzzer/corpus/6f2d29720f689464424daee284b20b078c2c2948 b/fuzzer/corpus/6f2d29720f689464424daee284b20b078c2c2948
new file mode 100644
index 0000000..86ed14d
--- /dev/null
+++ b/fuzzer/corpus/6f2d29720f689464424daee284b20b078c2c2948
Binary files differ
diff --git a/fuzzer/corpus/6f72524ca639aa946a6fbf266661c60fa9a12a12 b/fuzzer/corpus/6f72524ca639aa946a6fbf266661c60fa9a12a12
new file mode 100644
index 0000000..5220b57
--- /dev/null
+++ b/fuzzer/corpus/6f72524ca639aa946a6fbf266661c60fa9a12a12
Binary files differ
diff --git a/fuzzer/corpus/6f99aed6a2d7debe2cf490f4cea897b250a57398 b/fuzzer/corpus/6f99aed6a2d7debe2cf490f4cea897b250a57398
new file mode 100644
index 0000000..62b7731
--- /dev/null
+++ b/fuzzer/corpus/6f99aed6a2d7debe2cf490f4cea897b250a57398
Binary files differ
diff --git a/fuzzer/corpus/6f9f35de55db285af5758d2ababf322255ac4be4 b/fuzzer/corpus/6f9f35de55db285af5758d2ababf322255ac4be4
new file mode 100644
index 0000000..fe7c01b
--- /dev/null
+++ b/fuzzer/corpus/6f9f35de55db285af5758d2ababf322255ac4be4
Binary files differ
diff --git a/fuzzer/corpus/6fa722fc9c87d3928d8ef6026b0251a22b9e755d b/fuzzer/corpus/6fa722fc9c87d3928d8ef6026b0251a22b9e755d
new file mode 100644
index 0000000..d8f9ff6
--- /dev/null
+++ b/fuzzer/corpus/6fa722fc9c87d3928d8ef6026b0251a22b9e755d
Binary files differ
diff --git a/fuzzer/corpus/6fa7c05cb238ec372624a1626cb9d012f1639491 b/fuzzer/corpus/6fa7c05cb238ec372624a1626cb9d012f1639491
new file mode 100644
index 0000000..83c9533
--- /dev/null
+++ b/fuzzer/corpus/6fa7c05cb238ec372624a1626cb9d012f1639491
Binary files differ
diff --git a/fuzzer/corpus/6fb5c7b62731e01283505b7467e5e76e1f74d0fd b/fuzzer/corpus/6fb5c7b62731e01283505b7467e5e76e1f74d0fd
new file mode 100644
index 0000000..ffd918e
--- /dev/null
+++ b/fuzzer/corpus/6fb5c7b62731e01283505b7467e5e76e1f74d0fd
Binary files differ
diff --git a/fuzzer/corpus/6fb69b5f0565450159d46ee596b9ec9232a0b797 b/fuzzer/corpus/6fb69b5f0565450159d46ee596b9ec9232a0b797
new file mode 100644
index 0000000..a720593
--- /dev/null
+++ b/fuzzer/corpus/6fb69b5f0565450159d46ee596b9ec9232a0b797
Binary files differ
diff --git a/fuzzer/corpus/7033ed258d94c307bfbea0a744b17e170ab55770 b/fuzzer/corpus/7033ed258d94c307bfbea0a744b17e170ab55770
new file mode 100644
index 0000000..a73c921
--- /dev/null
+++ b/fuzzer/corpus/7033ed258d94c307bfbea0a744b17e170ab55770
Binary files differ
diff --git a/fuzzer/corpus/7049f5d714d906f4b91b6158edad152aeec36afb b/fuzzer/corpus/7049f5d714d906f4b91b6158edad152aeec36afb
new file mode 100644
index 0000000..8e558c1
--- /dev/null
+++ b/fuzzer/corpus/7049f5d714d906f4b91b6158edad152aeec36afb
Binary files differ
diff --git a/fuzzer/corpus/706e99b5200a33d92fe18770621f8affdc6a418c b/fuzzer/corpus/706e99b5200a33d92fe18770621f8affdc6a418c
new file mode 100644
index 0000000..57609e3
--- /dev/null
+++ b/fuzzer/corpus/706e99b5200a33d92fe18770621f8affdc6a418c
Binary files differ
diff --git a/fuzzer/corpus/7075b3ea0b6a92bf0a84d76fbd52d526ec0b55e7 b/fuzzer/corpus/7075b3ea0b6a92bf0a84d76fbd52d526ec0b55e7
new file mode 100644
index 0000000..e7eac61
--- /dev/null
+++ b/fuzzer/corpus/7075b3ea0b6a92bf0a84d76fbd52d526ec0b55e7
Binary files differ
diff --git a/fuzzer/corpus/70a772af87ee494dc824e44162f95f5f83113e1a b/fuzzer/corpus/70a772af87ee494dc824e44162f95f5f83113e1a
new file mode 100644
index 0000000..65711cd
--- /dev/null
+++ b/fuzzer/corpus/70a772af87ee494dc824e44162f95f5f83113e1a
Binary files differ
diff --git a/fuzzer/corpus/70ace6ab4c748bac8cd6f0d153ebb8dabeb24d20 b/fuzzer/corpus/70ace6ab4c748bac8cd6f0d153ebb8dabeb24d20
new file mode 100644
index 0000000..a6602fc
--- /dev/null
+++ b/fuzzer/corpus/70ace6ab4c748bac8cd6f0d153ebb8dabeb24d20
Binary files differ
diff --git a/fuzzer/corpus/70b2ad450966a79ee222fafce5d7608f72672bf2 b/fuzzer/corpus/70b2ad450966a79ee222fafce5d7608f72672bf2
new file mode 100644
index 0000000..d62cdf3
--- /dev/null
+++ b/fuzzer/corpus/70b2ad450966a79ee222fafce5d7608f72672bf2
Binary files differ
diff --git a/fuzzer/corpus/70b68da82d72f9d9f56c8f563ea751bbc7a08713 b/fuzzer/corpus/70b68da82d72f9d9f56c8f563ea751bbc7a08713
new file mode 100644
index 0000000..0f89b56
--- /dev/null
+++ b/fuzzer/corpus/70b68da82d72f9d9f56c8f563ea751bbc7a08713
Binary files differ
diff --git a/fuzzer/corpus/70bfe0c45d94a9c0fb11584127e1c3718a215392 b/fuzzer/corpus/70bfe0c45d94a9c0fb11584127e1c3718a215392
new file mode 100644
index 0000000..1c2ce65
--- /dev/null
+++ b/fuzzer/corpus/70bfe0c45d94a9c0fb11584127e1c3718a215392
Binary files differ
diff --git a/fuzzer/corpus/70d5c52f63225e602835946dcb386d1aa700078b b/fuzzer/corpus/70d5c52f63225e602835946dcb386d1aa700078b
new file mode 100644
index 0000000..f4325e9
--- /dev/null
+++ b/fuzzer/corpus/70d5c52f63225e602835946dcb386d1aa700078b
Binary files differ
diff --git a/fuzzer/corpus/710b4648ba54b121f44898006b76b69bd8b66cbd b/fuzzer/corpus/710b4648ba54b121f44898006b76b69bd8b66cbd
new file mode 100644
index 0000000..1b6841b
--- /dev/null
+++ b/fuzzer/corpus/710b4648ba54b121f44898006b76b69bd8b66cbd
Binary files differ
diff --git a/fuzzer/corpus/7124f8dec00a51babc1db2595c27e2bf098c02f4 b/fuzzer/corpus/7124f8dec00a51babc1db2595c27e2bf098c02f4
new file mode 100644
index 0000000..fd14b9e
--- /dev/null
+++ b/fuzzer/corpus/7124f8dec00a51babc1db2595c27e2bf098c02f4
Binary files differ
diff --git a/fuzzer/corpus/712e306cce235fd7c07acc4f9542e3e8d176b4f0 b/fuzzer/corpus/712e306cce235fd7c07acc4f9542e3e8d176b4f0
new file mode 100644
index 0000000..d1e101b
--- /dev/null
+++ b/fuzzer/corpus/712e306cce235fd7c07acc4f9542e3e8d176b4f0
Binary files differ
diff --git a/fuzzer/corpus/717743fb883b330706bbea0e9a49afbe3dc907aa b/fuzzer/corpus/717743fb883b330706bbea0e9a49afbe3dc907aa
new file mode 100644
index 0000000..b16b3dd
--- /dev/null
+++ b/fuzzer/corpus/717743fb883b330706bbea0e9a49afbe3dc907aa
Binary files differ
diff --git a/fuzzer/corpus/717c5019bfa5d9d92e954c407084ee36a07f1d48 b/fuzzer/corpus/717c5019bfa5d9d92e954c407084ee36a07f1d48
new file mode 100644
index 0000000..499ab73
--- /dev/null
+++ b/fuzzer/corpus/717c5019bfa5d9d92e954c407084ee36a07f1d48
Binary files differ
diff --git a/fuzzer/corpus/719f9b36bafc225926b18d5b31ea111c0d20571e b/fuzzer/corpus/719f9b36bafc225926b18d5b31ea111c0d20571e
new file mode 100644
index 0000000..d766e80
--- /dev/null
+++ b/fuzzer/corpus/719f9b36bafc225926b18d5b31ea111c0d20571e
Binary files differ
diff --git a/fuzzer/corpus/71cd1c25e8b6affaf2286d31730f641b4d1203d8 b/fuzzer/corpus/71cd1c25e8b6affaf2286d31730f641b4d1203d8
new file mode 100644
index 0000000..05e7aa3
--- /dev/null
+++ b/fuzzer/corpus/71cd1c25e8b6affaf2286d31730f641b4d1203d8
Binary files differ
diff --git a/fuzzer/corpus/71ec5ab0e76d1b30deeefd5304b3733a4597ebe7 b/fuzzer/corpus/71ec5ab0e76d1b30deeefd5304b3733a4597ebe7
new file mode 100644
index 0000000..b8adae3
--- /dev/null
+++ b/fuzzer/corpus/71ec5ab0e76d1b30deeefd5304b3733a4597ebe7
Binary files differ
diff --git a/fuzzer/corpus/720990112fdf8cd26c132d3aace3e5653f0c4756 b/fuzzer/corpus/720990112fdf8cd26c132d3aace3e5653f0c4756
new file mode 100644
index 0000000..5f7d514
--- /dev/null
+++ b/fuzzer/corpus/720990112fdf8cd26c132d3aace3e5653f0c4756
Binary files differ
diff --git a/fuzzer/corpus/721fd414791e3f0e8509752ce857e5743e11016d b/fuzzer/corpus/721fd414791e3f0e8509752ce857e5743e11016d
new file mode 100644
index 0000000..69973d2
--- /dev/null
+++ b/fuzzer/corpus/721fd414791e3f0e8509752ce857e5743e11016d
Binary files differ
diff --git a/fuzzer/corpus/724d34b3d32e78744b9757c8e7282e26389ddd4e b/fuzzer/corpus/724d34b3d32e78744b9757c8e7282e26389ddd4e
new file mode 100644
index 0000000..d773297
--- /dev/null
+++ b/fuzzer/corpus/724d34b3d32e78744b9757c8e7282e26389ddd4e
Binary files differ
diff --git a/fuzzer/corpus/7256851ae102c901118178247d0608dd2bede61c b/fuzzer/corpus/7256851ae102c901118178247d0608dd2bede61c
new file mode 100644
index 0000000..a2ff598
--- /dev/null
+++ b/fuzzer/corpus/7256851ae102c901118178247d0608dd2bede61c
Binary files differ
diff --git a/fuzzer/corpus/7258166ffb827db0f294ad3f169a72c23f2195b7 b/fuzzer/corpus/7258166ffb827db0f294ad3f169a72c23f2195b7
new file mode 100644
index 0000000..4f69520
--- /dev/null
+++ b/fuzzer/corpus/7258166ffb827db0f294ad3f169a72c23f2195b7
Binary files differ
diff --git a/fuzzer/corpus/725f1f53fb6c5be7ab5815edc4ad728801c8f9af b/fuzzer/corpus/725f1f53fb6c5be7ab5815edc4ad728801c8f9af
new file mode 100644
index 0000000..1167c28
--- /dev/null
+++ b/fuzzer/corpus/725f1f53fb6c5be7ab5815edc4ad728801c8f9af
Binary files differ
diff --git a/fuzzer/corpus/72a41f35244bd47df22cff8cb97d7a0c1cbb0c83 b/fuzzer/corpus/72a41f35244bd47df22cff8cb97d7a0c1cbb0c83
new file mode 100644
index 0000000..19c74d4
--- /dev/null
+++ b/fuzzer/corpus/72a41f35244bd47df22cff8cb97d7a0c1cbb0c83
Binary files differ
diff --git a/fuzzer/corpus/72baa8a47cb281f053c39fb483d4af8f45b48ee1 b/fuzzer/corpus/72baa8a47cb281f053c39fb483d4af8f45b48ee1
new file mode 100644
index 0000000..11a5df6
--- /dev/null
+++ b/fuzzer/corpus/72baa8a47cb281f053c39fb483d4af8f45b48ee1
Binary files differ
diff --git a/fuzzer/corpus/72c83d7c35ffb01b9daa045a9a5b5b76bd80657b b/fuzzer/corpus/72c83d7c35ffb01b9daa045a9a5b5b76bd80657b
new file mode 100644
index 0000000..4a9a7c4
--- /dev/null
+++ b/fuzzer/corpus/72c83d7c35ffb01b9daa045a9a5b5b76bd80657b
Binary files differ
diff --git a/fuzzer/corpus/72e12abdb30b4051d58c2336d12455da88bc74bf b/fuzzer/corpus/72e12abdb30b4051d58c2336d12455da88bc74bf
new file mode 100644
index 0000000..313b759
--- /dev/null
+++ b/fuzzer/corpus/72e12abdb30b4051d58c2336d12455da88bc74bf
Binary files differ
diff --git a/fuzzer/corpus/72f6619412fb7889db222ac3afccf525864b5755 b/fuzzer/corpus/72f6619412fb7889db222ac3afccf525864b5755
new file mode 100644
index 0000000..a699ccb
--- /dev/null
+++ b/fuzzer/corpus/72f6619412fb7889db222ac3afccf525864b5755
Binary files differ
diff --git a/fuzzer/corpus/72f69427262628bc7b55884ca42782885ce749bc b/fuzzer/corpus/72f69427262628bc7b55884ca42782885ce749bc
new file mode 100644
index 0000000..531fb31
--- /dev/null
+++ b/fuzzer/corpus/72f69427262628bc7b55884ca42782885ce749bc
Binary files differ
diff --git a/fuzzer/corpus/7300d5491974cf7008bb306f6ce0f28294c3f4ad b/fuzzer/corpus/7300d5491974cf7008bb306f6ce0f28294c3f4ad
new file mode 100644
index 0000000..9981c15
--- /dev/null
+++ b/fuzzer/corpus/7300d5491974cf7008bb306f6ce0f28294c3f4ad
Binary files differ
diff --git a/fuzzer/corpus/7309d83b1f178d7ac52771891d0f87921cd2f282 b/fuzzer/corpus/7309d83b1f178d7ac52771891d0f87921cd2f282
new file mode 100644
index 0000000..f4fb1bf
--- /dev/null
+++ b/fuzzer/corpus/7309d83b1f178d7ac52771891d0f87921cd2f282
Binary files differ
diff --git a/fuzzer/corpus/734c48b7b6f5c2e412aa8036c6bccd849c76dfca b/fuzzer/corpus/734c48b7b6f5c2e412aa8036c6bccd849c76dfca
new file mode 100644
index 0000000..7d53830
--- /dev/null
+++ b/fuzzer/corpus/734c48b7b6f5c2e412aa8036c6bccd849c76dfca
Binary files differ
diff --git a/fuzzer/corpus/7350c3788104634e2be77eaf02556badd86f13de b/fuzzer/corpus/7350c3788104634e2be77eaf02556badd86f13de
new file mode 100644
index 0000000..d330d9a
--- /dev/null
+++ b/fuzzer/corpus/7350c3788104634e2be77eaf02556badd86f13de
Binary files differ
diff --git a/fuzzer/corpus/735add7f4b427ce83da42ae0b564095f4cea3dce b/fuzzer/corpus/735add7f4b427ce83da42ae0b564095f4cea3dce
new file mode 100644
index 0000000..0660ba9
--- /dev/null
+++ b/fuzzer/corpus/735add7f4b427ce83da42ae0b564095f4cea3dce
Binary files differ
diff --git a/fuzzer/corpus/735b475e744643a1e493e9a89ac3a6c41e8e05a6 b/fuzzer/corpus/735b475e744643a1e493e9a89ac3a6c41e8e05a6
new file mode 100644
index 0000000..b8a632e
--- /dev/null
+++ b/fuzzer/corpus/735b475e744643a1e493e9a89ac3a6c41e8e05a6
Binary files differ
diff --git a/fuzzer/corpus/7377effcd188d737f5235d4693db795b9d153167 b/fuzzer/corpus/7377effcd188d737f5235d4693db795b9d153167
new file mode 100644
index 0000000..53149af
--- /dev/null
+++ b/fuzzer/corpus/7377effcd188d737f5235d4693db795b9d153167
Binary files differ
diff --git a/fuzzer/corpus/737d1a08227e4ce4424999f7c884f18607a0a3a8 b/fuzzer/corpus/737d1a08227e4ce4424999f7c884f18607a0a3a8
new file mode 100644
index 0000000..87a3115
--- /dev/null
+++ b/fuzzer/corpus/737d1a08227e4ce4424999f7c884f18607a0a3a8
Binary files differ
diff --git a/fuzzer/corpus/7399da9b1d75f2d484579109e92912ad332539c2 b/fuzzer/corpus/7399da9b1d75f2d484579109e92912ad332539c2
new file mode 100644
index 0000000..6fe3330
--- /dev/null
+++ b/fuzzer/corpus/7399da9b1d75f2d484579109e92912ad332539c2
Binary files differ
diff --git a/fuzzer/corpus/73b2f62c4cc2dbdef1e4fa54ac8295b898862d62 b/fuzzer/corpus/73b2f62c4cc2dbdef1e4fa54ac8295b898862d62
new file mode 100644
index 0000000..e3abcaa
--- /dev/null
+++ b/fuzzer/corpus/73b2f62c4cc2dbdef1e4fa54ac8295b898862d62
Binary files differ
diff --git a/fuzzer/corpus/73e0eea6754e70efff92e2dfee68999220a9f6ac b/fuzzer/corpus/73e0eea6754e70efff92e2dfee68999220a9f6ac
new file mode 100644
index 0000000..b0bfb44
--- /dev/null
+++ b/fuzzer/corpus/73e0eea6754e70efff92e2dfee68999220a9f6ac
Binary files differ
diff --git a/fuzzer/corpus/73fa14e72a41c83f9a884f055b91e0d573add7b5 b/fuzzer/corpus/73fa14e72a41c83f9a884f055b91e0d573add7b5
new file mode 100644
index 0000000..8eddc78
--- /dev/null
+++ b/fuzzer/corpus/73fa14e72a41c83f9a884f055b91e0d573add7b5
Binary files differ
diff --git a/fuzzer/corpus/7400ab608ee8af900cb7263b444387d62b213722 b/fuzzer/corpus/7400ab608ee8af900cb7263b444387d62b213722
new file mode 100644
index 0000000..d4351df
--- /dev/null
+++ b/fuzzer/corpus/7400ab608ee8af900cb7263b444387d62b213722
Binary files differ
diff --git a/fuzzer/corpus/740733262b0594c2fdb0c044a2645a6a958d89d0 b/fuzzer/corpus/740733262b0594c2fdb0c044a2645a6a958d89d0
new file mode 100644
index 0000000..340754a
--- /dev/null
+++ b/fuzzer/corpus/740733262b0594c2fdb0c044a2645a6a958d89d0
Binary files differ
diff --git a/fuzzer/corpus/7408f6d49d112aee38c9fe3d7bada867c97f43c4 b/fuzzer/corpus/7408f6d49d112aee38c9fe3d7bada867c97f43c4
new file mode 100644
index 0000000..d20561a
--- /dev/null
+++ b/fuzzer/corpus/7408f6d49d112aee38c9fe3d7bada867c97f43c4
Binary files differ
diff --git a/fuzzer/corpus/7418b4823963f002f17f45004f69e28a548260c5 b/fuzzer/corpus/7418b4823963f002f17f45004f69e28a548260c5
new file mode 100644
index 0000000..4f314bf
--- /dev/null
+++ b/fuzzer/corpus/7418b4823963f002f17f45004f69e28a548260c5
Binary files differ
diff --git a/fuzzer/corpus/741ac6075767d7cd8a080cf54ecde55c3d287e93 b/fuzzer/corpus/741ac6075767d7cd8a080cf54ecde55c3d287e93
new file mode 100644
index 0000000..fa631b3
--- /dev/null
+++ b/fuzzer/corpus/741ac6075767d7cd8a080cf54ecde55c3d287e93
Binary files differ
diff --git a/fuzzer/corpus/742f841e65a01b5f484eac4a95c4b8b30814358c b/fuzzer/corpus/742f841e65a01b5f484eac4a95c4b8b30814358c
new file mode 100644
index 0000000..b964f58
--- /dev/null
+++ b/fuzzer/corpus/742f841e65a01b5f484eac4a95c4b8b30814358c
Binary files differ
diff --git a/fuzzer/corpus/7437a96fab759f43e25826c80da66186fdcddd3d b/fuzzer/corpus/7437a96fab759f43e25826c80da66186fdcddd3d
new file mode 100644
index 0000000..6b5030f
--- /dev/null
+++ b/fuzzer/corpus/7437a96fab759f43e25826c80da66186fdcddd3d
Binary files differ
diff --git a/fuzzer/corpus/744542b36afbf140eb5e868bba0a56ec55a13fd3 b/fuzzer/corpus/744542b36afbf140eb5e868bba0a56ec55a13fd3
new file mode 100644
index 0000000..787aee6
--- /dev/null
+++ b/fuzzer/corpus/744542b36afbf140eb5e868bba0a56ec55a13fd3
Binary files differ
diff --git a/fuzzer/corpus/74578fad6a1e649a527682134507ac1188c4427d b/fuzzer/corpus/74578fad6a1e649a527682134507ac1188c4427d
new file mode 100644
index 0000000..c2f591b
--- /dev/null
+++ b/fuzzer/corpus/74578fad6a1e649a527682134507ac1188c4427d
Binary files differ
diff --git a/fuzzer/corpus/74737f3ba6fec08624c0adab88eb827a40abdd4a b/fuzzer/corpus/74737f3ba6fec08624c0adab88eb827a40abdd4a
new file mode 100644
index 0000000..30bc487
--- /dev/null
+++ b/fuzzer/corpus/74737f3ba6fec08624c0adab88eb827a40abdd4a
Binary files differ
diff --git a/fuzzer/corpus/747841eb33d25b135b6473f3d38d57da4c82b4fa b/fuzzer/corpus/747841eb33d25b135b6473f3d38d57da4c82b4fa
new file mode 100644
index 0000000..b6bc240
--- /dev/null
+++ b/fuzzer/corpus/747841eb33d25b135b6473f3d38d57da4c82b4fa
Binary files differ
diff --git a/fuzzer/corpus/748ae3bc9858646fa7ff250aae3d42c80453786d b/fuzzer/corpus/748ae3bc9858646fa7ff250aae3d42c80453786d
new file mode 100644
index 0000000..d2f16f9
--- /dev/null
+++ b/fuzzer/corpus/748ae3bc9858646fa7ff250aae3d42c80453786d
Binary files differ
diff --git a/fuzzer/corpus/74a4199d9a46e774a9be78a793a1796554311c26 b/fuzzer/corpus/74a4199d9a46e774a9be78a793a1796554311c26
new file mode 100644
index 0000000..c809019
--- /dev/null
+++ b/fuzzer/corpus/74a4199d9a46e774a9be78a793a1796554311c26
Binary files differ
diff --git a/fuzzer/corpus/74b67a22359f591b61329d8783b312cc359f8aa5 b/fuzzer/corpus/74b67a22359f591b61329d8783b312cc359f8aa5
new file mode 100644
index 0000000..b126434
--- /dev/null
+++ b/fuzzer/corpus/74b67a22359f591b61329d8783b312cc359f8aa5
Binary files differ
diff --git a/fuzzer/corpus/74df8a5ae0458398c81f0be2a0c53d3b20df722f b/fuzzer/corpus/74df8a5ae0458398c81f0be2a0c53d3b20df722f
new file mode 100644
index 0000000..0220d33
--- /dev/null
+++ b/fuzzer/corpus/74df8a5ae0458398c81f0be2a0c53d3b20df722f
Binary files differ
diff --git a/fuzzer/corpus/7504de0f47a357b3a5dbd3edd09cd792c5d84ed7 b/fuzzer/corpus/7504de0f47a357b3a5dbd3edd09cd792c5d84ed7
new file mode 100644
index 0000000..bdde1b9
--- /dev/null
+++ b/fuzzer/corpus/7504de0f47a357b3a5dbd3edd09cd792c5d84ed7
Binary files differ
diff --git a/fuzzer/corpus/7506432336562377cfed58373d1e46e6a1f6f2d4 b/fuzzer/corpus/7506432336562377cfed58373d1e46e6a1f6f2d4
new file mode 100644
index 0000000..fb7f6c3
--- /dev/null
+++ b/fuzzer/corpus/7506432336562377cfed58373d1e46e6a1f6f2d4
Binary files differ
diff --git a/fuzzer/corpus/752d4ae7a84e10fc41d07919fad52db415214535 b/fuzzer/corpus/752d4ae7a84e10fc41d07919fad52db415214535
new file mode 100644
index 0000000..877c02d
--- /dev/null
+++ b/fuzzer/corpus/752d4ae7a84e10fc41d07919fad52db415214535
Binary files differ
diff --git a/fuzzer/corpus/753513327efc6ddee8f2815b143748dc0f88b7e8 b/fuzzer/corpus/753513327efc6ddee8f2815b143748dc0f88b7e8
new file mode 100644
index 0000000..c2e78cb
--- /dev/null
+++ b/fuzzer/corpus/753513327efc6ddee8f2815b143748dc0f88b7e8
Binary files differ
diff --git a/fuzzer/corpus/755ec363058b3d5326029c35fafb59fd13bdafcf b/fuzzer/corpus/755ec363058b3d5326029c35fafb59fd13bdafcf
new file mode 100644
index 0000000..0426360
--- /dev/null
+++ b/fuzzer/corpus/755ec363058b3d5326029c35fafb59fd13bdafcf
Binary files differ
diff --git a/fuzzer/corpus/75615998f9dad6af47a16b949e0f5999afc6ec2c b/fuzzer/corpus/75615998f9dad6af47a16b949e0f5999afc6ec2c
new file mode 100644
index 0000000..68dcfcd
--- /dev/null
+++ b/fuzzer/corpus/75615998f9dad6af47a16b949e0f5999afc6ec2c
Binary files differ
diff --git a/fuzzer/corpus/757f4aac1cb731b1db1aa933e1b8f4695a239550 b/fuzzer/corpus/757f4aac1cb731b1db1aa933e1b8f4695a239550
new file mode 100644
index 0000000..4e86234
--- /dev/null
+++ b/fuzzer/corpus/757f4aac1cb731b1db1aa933e1b8f4695a239550
Binary files differ
diff --git a/fuzzer/corpus/75ad40df9fb13569165c4587a686b8624f4f902e b/fuzzer/corpus/75ad40df9fb13569165c4587a686b8624f4f902e
new file mode 100644
index 0000000..5f40e23
--- /dev/null
+++ b/fuzzer/corpus/75ad40df9fb13569165c4587a686b8624f4f902e
Binary files differ
diff --git a/fuzzer/corpus/75b96fe8745b1f80dbe3a909c8b87d0780279fe5 b/fuzzer/corpus/75b96fe8745b1f80dbe3a909c8b87d0780279fe5
new file mode 100644
index 0000000..cb60160
--- /dev/null
+++ b/fuzzer/corpus/75b96fe8745b1f80dbe3a909c8b87d0780279fe5
Binary files differ
diff --git a/fuzzer/corpus/75d45b9d9d3e7a5a6002b0300ca160d2da6f465a b/fuzzer/corpus/75d45b9d9d3e7a5a6002b0300ca160d2da6f465a
new file mode 100644
index 0000000..a000fba
--- /dev/null
+++ b/fuzzer/corpus/75d45b9d9d3e7a5a6002b0300ca160d2da6f465a
Binary files differ
diff --git a/fuzzer/corpus/76148cce4f02e4e8f1d5ced7e32e93293f22b631 b/fuzzer/corpus/76148cce4f02e4e8f1d5ced7e32e93293f22b631
new file mode 100644
index 0000000..e1527af
--- /dev/null
+++ b/fuzzer/corpus/76148cce4f02e4e8f1d5ced7e32e93293f22b631
Binary files differ
diff --git a/fuzzer/corpus/76567b98296bfd1a9e043a8e7acf8cfca5a6de90 b/fuzzer/corpus/76567b98296bfd1a9e043a8e7acf8cfca5a6de90
new file mode 100644
index 0000000..0d24e98
--- /dev/null
+++ b/fuzzer/corpus/76567b98296bfd1a9e043a8e7acf8cfca5a6de90
Binary files differ
diff --git a/fuzzer/corpus/767297ace089d3ea2baeec77b980188359549401 b/fuzzer/corpus/767297ace089d3ea2baeec77b980188359549401
new file mode 100644
index 0000000..1c54093
--- /dev/null
+++ b/fuzzer/corpus/767297ace089d3ea2baeec77b980188359549401
Binary files differ
diff --git a/fuzzer/corpus/76a452ce995b841d441c1aacc1d31beb1571fd11 b/fuzzer/corpus/76a452ce995b841d441c1aacc1d31beb1571fd11
new file mode 100644
index 0000000..133a5f4
--- /dev/null
+++ b/fuzzer/corpus/76a452ce995b841d441c1aacc1d31beb1571fd11
Binary files differ
diff --git a/fuzzer/corpus/76c051330fe32f41b2b6cd58178d35d7b92c7596 b/fuzzer/corpus/76c051330fe32f41b2b6cd58178d35d7b92c7596
new file mode 100644
index 0000000..ae19eed
--- /dev/null
+++ b/fuzzer/corpus/76c051330fe32f41b2b6cd58178d35d7b92c7596
Binary files differ
diff --git a/fuzzer/corpus/76ca0885b51d330c14e6b8e9188b064b881b13b5 b/fuzzer/corpus/76ca0885b51d330c14e6b8e9188b064b881b13b5
new file mode 100644
index 0000000..4c977c4
--- /dev/null
+++ b/fuzzer/corpus/76ca0885b51d330c14e6b8e9188b064b881b13b5
Binary files differ
diff --git a/fuzzer/corpus/76ce253bab0df4024f59b4fb3b0fdf193285d994 b/fuzzer/corpus/76ce253bab0df4024f59b4fb3b0fdf193285d994
new file mode 100644
index 0000000..7729984
--- /dev/null
+++ b/fuzzer/corpus/76ce253bab0df4024f59b4fb3b0fdf193285d994
Binary files differ
diff --git a/fuzzer/corpus/76fe24e81d0e53ac5d96c74603050609b04e2f4d b/fuzzer/corpus/76fe24e81d0e53ac5d96c74603050609b04e2f4d
new file mode 100644
index 0000000..201e415
--- /dev/null
+++ b/fuzzer/corpus/76fe24e81d0e53ac5d96c74603050609b04e2f4d
Binary files differ
diff --git a/fuzzer/corpus/76ffdbfcb856f1c0e670aca18e7f6a17c26486ee b/fuzzer/corpus/76ffdbfcb856f1c0e670aca18e7f6a17c26486ee
new file mode 100644
index 0000000..91ae43f
--- /dev/null
+++ b/fuzzer/corpus/76ffdbfcb856f1c0e670aca18e7f6a17c26486ee
Binary files differ
diff --git a/fuzzer/corpus/770b4547f11111b3dc124d0fbbba277545378ffa b/fuzzer/corpus/770b4547f11111b3dc124d0fbbba277545378ffa
new file mode 100644
index 0000000..3b285ab
--- /dev/null
+++ b/fuzzer/corpus/770b4547f11111b3dc124d0fbbba277545378ffa
Binary files differ
diff --git a/fuzzer/corpus/773eb63c3671453a04db73568a269b214d983b1d b/fuzzer/corpus/773eb63c3671453a04db73568a269b214d983b1d
new file mode 100644
index 0000000..fd3ae0c
--- /dev/null
+++ b/fuzzer/corpus/773eb63c3671453a04db73568a269b214d983b1d
Binary files differ
diff --git a/fuzzer/corpus/7753101d9b2454fc727f599e4c16de29490a5da0 b/fuzzer/corpus/7753101d9b2454fc727f599e4c16de29490a5da0
new file mode 100644
index 0000000..8d298bb
--- /dev/null
+++ b/fuzzer/corpus/7753101d9b2454fc727f599e4c16de29490a5da0
Binary files differ
diff --git a/fuzzer/corpus/777969909bb16e74240c6ca2ca2dea2170cba15c b/fuzzer/corpus/777969909bb16e74240c6ca2ca2dea2170cba15c
new file mode 100644
index 0000000..494e943
--- /dev/null
+++ b/fuzzer/corpus/777969909bb16e74240c6ca2ca2dea2170cba15c
Binary files differ
diff --git a/fuzzer/corpus/778654fc820b1dfa4e45c2738e7762fbc6a33a55 b/fuzzer/corpus/778654fc820b1dfa4e45c2738e7762fbc6a33a55
new file mode 100644
index 0000000..367706d
--- /dev/null
+++ b/fuzzer/corpus/778654fc820b1dfa4e45c2738e7762fbc6a33a55
Binary files differ
diff --git a/fuzzer/corpus/778817d1a44c3fbfbf636b99f43b1c38ee4fe0ac b/fuzzer/corpus/778817d1a44c3fbfbf636b99f43b1c38ee4fe0ac
new file mode 100644
index 0000000..a8268a5
--- /dev/null
+++ b/fuzzer/corpus/778817d1a44c3fbfbf636b99f43b1c38ee4fe0ac
Binary files differ
diff --git a/fuzzer/corpus/77a8e297472ad2804d69d0ea1f8c19038e2f7c03 b/fuzzer/corpus/77a8e297472ad2804d69d0ea1f8c19038e2f7c03
new file mode 100644
index 0000000..f5aa5fd
--- /dev/null
+++ b/fuzzer/corpus/77a8e297472ad2804d69d0ea1f8c19038e2f7c03
Binary files differ
diff --git a/fuzzer/corpus/77db4cb82f68f1fb6204cf7f61a79e92a532b753 b/fuzzer/corpus/77db4cb82f68f1fb6204cf7f61a79e92a532b753
new file mode 100644
index 0000000..f51d2b5
--- /dev/null
+++ b/fuzzer/corpus/77db4cb82f68f1fb6204cf7f61a79e92a532b753
Binary files differ
diff --git a/fuzzer/corpus/77fb00488655fb39f813b70219866d584997a957 b/fuzzer/corpus/77fb00488655fb39f813b70219866d584997a957
new file mode 100644
index 0000000..cdb08db
--- /dev/null
+++ b/fuzzer/corpus/77fb00488655fb39f813b70219866d584997a957
Binary files differ
diff --git a/fuzzer/corpus/7839ef01eccd990cce7ac41dc1e17d2a53fe5b55 b/fuzzer/corpus/7839ef01eccd990cce7ac41dc1e17d2a53fe5b55
new file mode 100644
index 0000000..393b717
--- /dev/null
+++ b/fuzzer/corpus/7839ef01eccd990cce7ac41dc1e17d2a53fe5b55
Binary files differ
diff --git a/fuzzer/corpus/7851267a92236d4b8a56ff38e4947e43e53005ba b/fuzzer/corpus/7851267a92236d4b8a56ff38e4947e43e53005ba
new file mode 100644
index 0000000..6fd7712
--- /dev/null
+++ b/fuzzer/corpus/7851267a92236d4b8a56ff38e4947e43e53005ba
Binary files differ
diff --git a/fuzzer/corpus/78e5573d0226b65966df449ec5a586c2680856e9 b/fuzzer/corpus/78e5573d0226b65966df449ec5a586c2680856e9
new file mode 100644
index 0000000..535a6e7
--- /dev/null
+++ b/fuzzer/corpus/78e5573d0226b65966df449ec5a586c2680856e9
Binary files differ
diff --git a/fuzzer/corpus/78ef41bd1903fb3df3f29bc6e64f3ab68e8d0c0b b/fuzzer/corpus/78ef41bd1903fb3df3f29bc6e64f3ab68e8d0c0b
new file mode 100644
index 0000000..7652446
--- /dev/null
+++ b/fuzzer/corpus/78ef41bd1903fb3df3f29bc6e64f3ab68e8d0c0b
Binary files differ
diff --git a/fuzzer/corpus/7911c8def6c53751e90ef022b5e8261044366c97 b/fuzzer/corpus/7911c8def6c53751e90ef022b5e8261044366c97
new file mode 100644
index 0000000..0f80525
--- /dev/null
+++ b/fuzzer/corpus/7911c8def6c53751e90ef022b5e8261044366c97
Binary files differ
diff --git a/fuzzer/corpus/7921671356a6afb0fd81d4fa8555f2a0e499af08 b/fuzzer/corpus/7921671356a6afb0fd81d4fa8555f2a0e499af08
new file mode 100644
index 0000000..f033fe0
--- /dev/null
+++ b/fuzzer/corpus/7921671356a6afb0fd81d4fa8555f2a0e499af08
Binary files differ
diff --git a/fuzzer/corpus/79613aa16aea067c77e179ec4c83022027090bdc b/fuzzer/corpus/79613aa16aea067c77e179ec4c83022027090bdc
new file mode 100644
index 0000000..4c92234
--- /dev/null
+++ b/fuzzer/corpus/79613aa16aea067c77e179ec4c83022027090bdc
Binary files differ
diff --git a/fuzzer/corpus/79695c079906ae4e31b451ddab525161a2586380 b/fuzzer/corpus/79695c079906ae4e31b451ddab525161a2586380
new file mode 100644
index 0000000..c260780
--- /dev/null
+++ b/fuzzer/corpus/79695c079906ae4e31b451ddab525161a2586380
Binary files differ
diff --git a/fuzzer/corpus/797e06e44156ed117975201408ca6146d2004405 b/fuzzer/corpus/797e06e44156ed117975201408ca6146d2004405
new file mode 100644
index 0000000..45c518f
--- /dev/null
+++ b/fuzzer/corpus/797e06e44156ed117975201408ca6146d2004405
Binary files differ
diff --git a/fuzzer/corpus/79a337880062772b2e9506af7b16ad596b748492 b/fuzzer/corpus/79a337880062772b2e9506af7b16ad596b748492
new file mode 100644
index 0000000..c47ae0f
--- /dev/null
+++ b/fuzzer/corpus/79a337880062772b2e9506af7b16ad596b748492
Binary files differ
diff --git a/fuzzer/corpus/79ad937dc63af3a8662dc4d66c6b18a1c3b842e9 b/fuzzer/corpus/79ad937dc63af3a8662dc4d66c6b18a1c3b842e9
new file mode 100644
index 0000000..13f77aa
--- /dev/null
+++ b/fuzzer/corpus/79ad937dc63af3a8662dc4d66c6b18a1c3b842e9
Binary files differ
diff --git a/fuzzer/corpus/79c9bcb1d0cc57012537070a9380189eb61d6a7a b/fuzzer/corpus/79c9bcb1d0cc57012537070a9380189eb61d6a7a
new file mode 100644
index 0000000..fbd5b29
--- /dev/null
+++ b/fuzzer/corpus/79c9bcb1d0cc57012537070a9380189eb61d6a7a
Binary files differ
diff --git a/fuzzer/corpus/79d1c3c982af023ec901e48bf5fcceeffc5249db b/fuzzer/corpus/79d1c3c982af023ec901e48bf5fcceeffc5249db
new file mode 100644
index 0000000..8e5a397
--- /dev/null
+++ b/fuzzer/corpus/79d1c3c982af023ec901e48bf5fcceeffc5249db
Binary files differ
diff --git a/fuzzer/corpus/79d5d8e98d9e37778e200f5ce3443dddf5d1e04d b/fuzzer/corpus/79d5d8e98d9e37778e200f5ce3443dddf5d1e04d
new file mode 100644
index 0000000..54aa6ed
--- /dev/null
+++ b/fuzzer/corpus/79d5d8e98d9e37778e200f5ce3443dddf5d1e04d
Binary files differ
diff --git a/fuzzer/corpus/79eefdef46f2001822160fab2b33307ce2451eb2 b/fuzzer/corpus/79eefdef46f2001822160fab2b33307ce2451eb2
new file mode 100644
index 0000000..4a5356f
--- /dev/null
+++ b/fuzzer/corpus/79eefdef46f2001822160fab2b33307ce2451eb2
Binary files differ
diff --git a/fuzzer/corpus/79f89cdf048387b37c2c10ceb9885f63f8304889 b/fuzzer/corpus/79f89cdf048387b37c2c10ceb9885f63f8304889
new file mode 100644
index 0000000..154889d
--- /dev/null
+++ b/fuzzer/corpus/79f89cdf048387b37c2c10ceb9885f63f8304889
Binary files differ
diff --git a/fuzzer/corpus/7a0456f56ad054d9bfec79c63516b38fb28229e3 b/fuzzer/corpus/7a0456f56ad054d9bfec79c63516b38fb28229e3
new file mode 100644
index 0000000..7f51ca9
--- /dev/null
+++ b/fuzzer/corpus/7a0456f56ad054d9bfec79c63516b38fb28229e3
Binary files differ
diff --git a/fuzzer/corpus/7a14e8dd5a57e3e1c3b18b6f2cc7ca46aab0a1eb b/fuzzer/corpus/7a14e8dd5a57e3e1c3b18b6f2cc7ca46aab0a1eb
new file mode 100644
index 0000000..a5bdce8
--- /dev/null
+++ b/fuzzer/corpus/7a14e8dd5a57e3e1c3b18b6f2cc7ca46aab0a1eb
Binary files differ
diff --git a/fuzzer/corpus/7a16d2290d87efa23a0d5007dbada204f16ac844 b/fuzzer/corpus/7a16d2290d87efa23a0d5007dbada204f16ac844
new file mode 100644
index 0000000..7aed254
--- /dev/null
+++ b/fuzzer/corpus/7a16d2290d87efa23a0d5007dbada204f16ac844
Binary files differ
diff --git a/fuzzer/corpus/7a3212a3cc93b425e6c60d3024e319206b65bce4 b/fuzzer/corpus/7a3212a3cc93b425e6c60d3024e319206b65bce4
new file mode 100644
index 0000000..139b912
--- /dev/null
+++ b/fuzzer/corpus/7a3212a3cc93b425e6c60d3024e319206b65bce4
Binary files differ
diff --git a/fuzzer/corpus/7a525c80f2606967be6063d0318a823dfed9fe56 b/fuzzer/corpus/7a525c80f2606967be6063d0318a823dfed9fe56
new file mode 100644
index 0000000..2d419a5
--- /dev/null
+++ b/fuzzer/corpus/7a525c80f2606967be6063d0318a823dfed9fe56
Binary files differ
diff --git a/fuzzer/corpus/7a84c8813991ce79074eb9b3a0645f575bc6f60c b/fuzzer/corpus/7a84c8813991ce79074eb9b3a0645f575bc6f60c
new file mode 100644
index 0000000..9ef1117
--- /dev/null
+++ b/fuzzer/corpus/7a84c8813991ce79074eb9b3a0645f575bc6f60c
Binary files differ
diff --git a/fuzzer/corpus/7a8768f48668207ea5fb42fd647d3ff767a95737 b/fuzzer/corpus/7a8768f48668207ea5fb42fd647d3ff767a95737
new file mode 100644
index 0000000..9fb488b
--- /dev/null
+++ b/fuzzer/corpus/7a8768f48668207ea5fb42fd647d3ff767a95737
Binary files differ
diff --git a/fuzzer/corpus/7aa399e22cb80e5f28f473243c9548a8f325e98e b/fuzzer/corpus/7aa399e22cb80e5f28f473243c9548a8f325e98e
new file mode 100644
index 0000000..55a00f9
--- /dev/null
+++ b/fuzzer/corpus/7aa399e22cb80e5f28f473243c9548a8f325e98e
Binary files differ
diff --git a/fuzzer/corpus/7aa4a10fa9118f949b9495f36b5c7026633b27c1 b/fuzzer/corpus/7aa4a10fa9118f949b9495f36b5c7026633b27c1
new file mode 100644
index 0000000..69df6f8
--- /dev/null
+++ b/fuzzer/corpus/7aa4a10fa9118f949b9495f36b5c7026633b27c1
Binary files differ
diff --git a/fuzzer/corpus/7ac5ceb4aeda387b0a7cc3d10d196a1b38e04189 b/fuzzer/corpus/7ac5ceb4aeda387b0a7cc3d10d196a1b38e04189
new file mode 100644
index 0000000..f9e23ae
--- /dev/null
+++ b/fuzzer/corpus/7ac5ceb4aeda387b0a7cc3d10d196a1b38e04189
Binary files differ
diff --git a/fuzzer/corpus/7b0173b94d1ae43e291ef41258ad5be33a94658a b/fuzzer/corpus/7b0173b94d1ae43e291ef41258ad5be33a94658a
new file mode 100644
index 0000000..44b685e
--- /dev/null
+++ b/fuzzer/corpus/7b0173b94d1ae43e291ef41258ad5be33a94658a
Binary files differ
diff --git a/fuzzer/corpus/7b092f55055ec30d6410db03348db394de41df33 b/fuzzer/corpus/7b092f55055ec30d6410db03348db394de41df33
new file mode 100644
index 0000000..b786244
--- /dev/null
+++ b/fuzzer/corpus/7b092f55055ec30d6410db03348db394de41df33
Binary files differ
diff --git a/fuzzer/corpus/7b151731c7616f4e39723ff6a4f73388409fa5ed b/fuzzer/corpus/7b151731c7616f4e39723ff6a4f73388409fa5ed
new file mode 100644
index 0000000..4b7bfb3
--- /dev/null
+++ b/fuzzer/corpus/7b151731c7616f4e39723ff6a4f73388409fa5ed
Binary files differ
diff --git a/fuzzer/corpus/7b17286a1a5a6aaaa22b7baa5f14470e25275259 b/fuzzer/corpus/7b17286a1a5a6aaaa22b7baa5f14470e25275259
new file mode 100644
index 0000000..91fd1ba
--- /dev/null
+++ b/fuzzer/corpus/7b17286a1a5a6aaaa22b7baa5f14470e25275259
Binary files differ
diff --git a/fuzzer/corpus/7b3b5288678d4dc968f4ff182767222379fca94d b/fuzzer/corpus/7b3b5288678d4dc968f4ff182767222379fca94d
new file mode 100644
index 0000000..2180cac
--- /dev/null
+++ b/fuzzer/corpus/7b3b5288678d4dc968f4ff182767222379fca94d
Binary files differ
diff --git a/fuzzer/corpus/7b3bc04aaa1fbab06b8780b23009eb9134385b55 b/fuzzer/corpus/7b3bc04aaa1fbab06b8780b23009eb9134385b55
new file mode 100644
index 0000000..80e5de5
--- /dev/null
+++ b/fuzzer/corpus/7b3bc04aaa1fbab06b8780b23009eb9134385b55
Binary files differ
diff --git a/fuzzer/corpus/7b82af1637d9bf085bf4691a4c2f6935109d7060 b/fuzzer/corpus/7b82af1637d9bf085bf4691a4c2f6935109d7060
new file mode 100644
index 0000000..d7406db
--- /dev/null
+++ b/fuzzer/corpus/7b82af1637d9bf085bf4691a4c2f6935109d7060
Binary files differ
diff --git a/fuzzer/corpus/7b90c46fa920fb6e34f38d280f8a814d5f7552d3 b/fuzzer/corpus/7b90c46fa920fb6e34f38d280f8a814d5f7552d3
new file mode 100644
index 0000000..0b4c334
--- /dev/null
+++ b/fuzzer/corpus/7b90c46fa920fb6e34f38d280f8a814d5f7552d3
Binary files differ
diff --git a/fuzzer/corpus/7b9368ad86f03fa961b749e2a2c4a49488ee800f b/fuzzer/corpus/7b9368ad86f03fa961b749e2a2c4a49488ee800f
new file mode 100644
index 0000000..f6186c5
--- /dev/null
+++ b/fuzzer/corpus/7b9368ad86f03fa961b749e2a2c4a49488ee800f
Binary files differ
diff --git a/fuzzer/corpus/7be86da7b09883e958b4325169bd6a468172581a b/fuzzer/corpus/7be86da7b09883e958b4325169bd6a468172581a
new file mode 100644
index 0000000..318589e
--- /dev/null
+++ b/fuzzer/corpus/7be86da7b09883e958b4325169bd6a468172581a
Binary files differ
diff --git a/fuzzer/corpus/7c559c7a0a72338b642176e045a69a3e14bcf2b0 b/fuzzer/corpus/7c559c7a0a72338b642176e045a69a3e14bcf2b0
new file mode 100644
index 0000000..d4167df
--- /dev/null
+++ b/fuzzer/corpus/7c559c7a0a72338b642176e045a69a3e14bcf2b0
Binary files differ
diff --git a/fuzzer/corpus/7c6ed8364d243b4150cc551b59fda5913ba459b1 b/fuzzer/corpus/7c6ed8364d243b4150cc551b59fda5913ba459b1
new file mode 100644
index 0000000..dbdc2ff
--- /dev/null
+++ b/fuzzer/corpus/7c6ed8364d243b4150cc551b59fda5913ba459b1
Binary files differ
diff --git a/fuzzer/corpus/7c78a1a959ee5939c74a4b724ef120b566e1d9f9 b/fuzzer/corpus/7c78a1a959ee5939c74a4b724ef120b566e1d9f9
new file mode 100644
index 0000000..18727f4
--- /dev/null
+++ b/fuzzer/corpus/7c78a1a959ee5939c74a4b724ef120b566e1d9f9
Binary files differ
diff --git a/fuzzer/corpus/7c9f31688f3aab10d5ee2520112ae4c643e9a8f1 b/fuzzer/corpus/7c9f31688f3aab10d5ee2520112ae4c643e9a8f1
new file mode 100644
index 0000000..30a0a59
--- /dev/null
+++ b/fuzzer/corpus/7c9f31688f3aab10d5ee2520112ae4c643e9a8f1
Binary files differ
diff --git a/fuzzer/corpus/7ca3bf567198f63f7feaeb6e6f9cf35a66b260cd b/fuzzer/corpus/7ca3bf567198f63f7feaeb6e6f9cf35a66b260cd
new file mode 100644
index 0000000..b33557e
--- /dev/null
+++ b/fuzzer/corpus/7ca3bf567198f63f7feaeb6e6f9cf35a66b260cd
Binary files differ
diff --git a/fuzzer/corpus/7cb3ccde9e7c69c613f6bc03904fb2742fefd85d b/fuzzer/corpus/7cb3ccde9e7c69c613f6bc03904fb2742fefd85d
new file mode 100644
index 0000000..0d2a8f4
--- /dev/null
+++ b/fuzzer/corpus/7cb3ccde9e7c69c613f6bc03904fb2742fefd85d
Binary files differ
diff --git a/fuzzer/corpus/7cf3e801b1ebba0e4eb6fca00efcfcaff610ecbd b/fuzzer/corpus/7cf3e801b1ebba0e4eb6fca00efcfcaff610ecbd
new file mode 100644
index 0000000..bda3c6d
--- /dev/null
+++ b/fuzzer/corpus/7cf3e801b1ebba0e4eb6fca00efcfcaff610ecbd
Binary files differ
diff --git a/fuzzer/corpus/7d18ed36f5b3162c15cfb3564a2f1b96dad2131e b/fuzzer/corpus/7d18ed36f5b3162c15cfb3564a2f1b96dad2131e
new file mode 100644
index 0000000..f9a1dba
--- /dev/null
+++ b/fuzzer/corpus/7d18ed36f5b3162c15cfb3564a2f1b96dad2131e
Binary files differ
diff --git a/fuzzer/corpus/7d70387c8179573c0f1043460320e8e84c45640e b/fuzzer/corpus/7d70387c8179573c0f1043460320e8e84c45640e
new file mode 100644
index 0000000..84f0228
--- /dev/null
+++ b/fuzzer/corpus/7d70387c8179573c0f1043460320e8e84c45640e
Binary files differ
diff --git a/fuzzer/corpus/7d7da6cb9102c0ed89ff8ec9d595ed3b2601eb05 b/fuzzer/corpus/7d7da6cb9102c0ed89ff8ec9d595ed3b2601eb05
new file mode 100644
index 0000000..570c292
--- /dev/null
+++ b/fuzzer/corpus/7d7da6cb9102c0ed89ff8ec9d595ed3b2601eb05
Binary files differ
diff --git a/fuzzer/corpus/7d9bfcaada2b170255bcd0ef2e4b8921abb41779 b/fuzzer/corpus/7d9bfcaada2b170255bcd0ef2e4b8921abb41779
new file mode 100644
index 0000000..f697f72
--- /dev/null
+++ b/fuzzer/corpus/7d9bfcaada2b170255bcd0ef2e4b8921abb41779
Binary files differ
diff --git a/fuzzer/corpus/7db4f5591801a48c9b8a1575ae0cda54eaaeeb47 b/fuzzer/corpus/7db4f5591801a48c9b8a1575ae0cda54eaaeeb47
new file mode 100644
index 0000000..45b2073
--- /dev/null
+++ b/fuzzer/corpus/7db4f5591801a48c9b8a1575ae0cda54eaaeeb47
Binary files differ
diff --git a/fuzzer/corpus/7dbff32be3d3dfdf4cc6893c63969a6c31587d6c b/fuzzer/corpus/7dbff32be3d3dfdf4cc6893c63969a6c31587d6c
new file mode 100644
index 0000000..5dc36d9
--- /dev/null
+++ b/fuzzer/corpus/7dbff32be3d3dfdf4cc6893c63969a6c31587d6c
Binary files differ
diff --git a/fuzzer/corpus/7dc44283cf9cd2fab208ee4a2d853d451ba34c96 b/fuzzer/corpus/7dc44283cf9cd2fab208ee4a2d853d451ba34c96
new file mode 100644
index 0000000..2a19a78
--- /dev/null
+++ b/fuzzer/corpus/7dc44283cf9cd2fab208ee4a2d853d451ba34c96
Binary files differ
diff --git a/fuzzer/corpus/7dd37c3acd5a930bc551075f36f17f73c4a0c58a b/fuzzer/corpus/7dd37c3acd5a930bc551075f36f17f73c4a0c58a
new file mode 100644
index 0000000..b1ae7ae
--- /dev/null
+++ b/fuzzer/corpus/7dd37c3acd5a930bc551075f36f17f73c4a0c58a
Binary files differ
diff --git a/fuzzer/corpus/7dda43e86a2cc6ec3ad573803685b6f699f68e58 b/fuzzer/corpus/7dda43e86a2cc6ec3ad573803685b6f699f68e58
new file mode 100644
index 0000000..48c9058
--- /dev/null
+++ b/fuzzer/corpus/7dda43e86a2cc6ec3ad573803685b6f699f68e58
Binary files differ
diff --git a/fuzzer/corpus/7de45e20cd384ad3c999f012ab690d190b4b99c7 b/fuzzer/corpus/7de45e20cd384ad3c999f012ab690d190b4b99c7
new file mode 100644
index 0000000..96db60e
--- /dev/null
+++ b/fuzzer/corpus/7de45e20cd384ad3c999f012ab690d190b4b99c7
Binary files differ
diff --git a/fuzzer/corpus/7ded496fd531287d3aae5dbb5372e7008809aeff b/fuzzer/corpus/7ded496fd531287d3aae5dbb5372e7008809aeff
new file mode 100644
index 0000000..43a1a6e
--- /dev/null
+++ b/fuzzer/corpus/7ded496fd531287d3aae5dbb5372e7008809aeff
Binary files differ
diff --git a/fuzzer/corpus/7dfc1b2c5c9c6395a72d6f332273e1998d324dc8 b/fuzzer/corpus/7dfc1b2c5c9c6395a72d6f332273e1998d324dc8
new file mode 100644
index 0000000..341cb55
--- /dev/null
+++ b/fuzzer/corpus/7dfc1b2c5c9c6395a72d6f332273e1998d324dc8
Binary files differ
diff --git a/fuzzer/corpus/7e0c26ffa090b8c1f6b7b54d0691f20cf3120065 b/fuzzer/corpus/7e0c26ffa090b8c1f6b7b54d0691f20cf3120065
new file mode 100644
index 0000000..6773f0d
--- /dev/null
+++ b/fuzzer/corpus/7e0c26ffa090b8c1f6b7b54d0691f20cf3120065
Binary files differ
diff --git a/fuzzer/corpus/7e1d8c9ceab68693700ed87c766d82bef1629d9d b/fuzzer/corpus/7e1d8c9ceab68693700ed87c766d82bef1629d9d
new file mode 100644
index 0000000..6b1f903
--- /dev/null
+++ b/fuzzer/corpus/7e1d8c9ceab68693700ed87c766d82bef1629d9d
Binary files differ
diff --git a/fuzzer/corpus/7e421fc80234232df6152662a076cab09aeec677 b/fuzzer/corpus/7e421fc80234232df6152662a076cab09aeec677
new file mode 100644
index 0000000..6fbc804
--- /dev/null
+++ b/fuzzer/corpus/7e421fc80234232df6152662a076cab09aeec677
Binary files differ
diff --git a/fuzzer/corpus/7e4abdd11becb33a0de5bf8b3541f06232528dc2 b/fuzzer/corpus/7e4abdd11becb33a0de5bf8b3541f06232528dc2
new file mode 100644
index 0000000..6942fe7
--- /dev/null
+++ b/fuzzer/corpus/7e4abdd11becb33a0de5bf8b3541f06232528dc2
Binary files differ
diff --git a/fuzzer/corpus/7e4e8fd08e84fe858f4b4285850e9759261a68cb b/fuzzer/corpus/7e4e8fd08e84fe858f4b4285850e9759261a68cb
new file mode 100644
index 0000000..b691f76
--- /dev/null
+++ b/fuzzer/corpus/7e4e8fd08e84fe858f4b4285850e9759261a68cb
Binary files differ
diff --git a/fuzzer/corpus/7e626c5828bf87790da19c322bb8492ce45ce8e0 b/fuzzer/corpus/7e626c5828bf87790da19c322bb8492ce45ce8e0
new file mode 100644
index 0000000..b6f232e
--- /dev/null
+++ b/fuzzer/corpus/7e626c5828bf87790da19c322bb8492ce45ce8e0
Binary files differ
diff --git a/fuzzer/corpus/7e8fecf5af2e8c00c79f14c136a91214b4406ba3 b/fuzzer/corpus/7e8fecf5af2e8c00c79f14c136a91214b4406ba3
new file mode 100644
index 0000000..fae9728
--- /dev/null
+++ b/fuzzer/corpus/7e8fecf5af2e8c00c79f14c136a91214b4406ba3
Binary files differ
diff --git a/fuzzer/corpus/7ea2f73225fbbccd29b5f6bae4b793d73f74021e b/fuzzer/corpus/7ea2f73225fbbccd29b5f6bae4b793d73f74021e
new file mode 100644
index 0000000..1d6de04
--- /dev/null
+++ b/fuzzer/corpus/7ea2f73225fbbccd29b5f6bae4b793d73f74021e
Binary files differ
diff --git a/fuzzer/corpus/7ec74e5bcd1e83890ca96a4d0a465910fc8875c5 b/fuzzer/corpus/7ec74e5bcd1e83890ca96a4d0a465910fc8875c5
new file mode 100644
index 0000000..6da2f33
--- /dev/null
+++ b/fuzzer/corpus/7ec74e5bcd1e83890ca96a4d0a465910fc8875c5
Binary files differ
diff --git a/fuzzer/corpus/7ed2e85d653993c06abd46cea79dbf58c1ed7c92 b/fuzzer/corpus/7ed2e85d653993c06abd46cea79dbf58c1ed7c92
new file mode 100644
index 0000000..e0c4471
--- /dev/null
+++ b/fuzzer/corpus/7ed2e85d653993c06abd46cea79dbf58c1ed7c92
Binary files differ
diff --git a/fuzzer/corpus/7ee74e1d27ad82d986a87c0b0e18b3a62d8cb7cf b/fuzzer/corpus/7ee74e1d27ad82d986a87c0b0e18b3a62d8cb7cf
new file mode 100644
index 0000000..ee835ee
--- /dev/null
+++ b/fuzzer/corpus/7ee74e1d27ad82d986a87c0b0e18b3a62d8cb7cf
Binary files differ
diff --git a/fuzzer/corpus/7f1b44970724cfb5e013b5de190ad898069447ef b/fuzzer/corpus/7f1b44970724cfb5e013b5de190ad898069447ef
new file mode 100644
index 0000000..0a5f0f5
--- /dev/null
+++ b/fuzzer/corpus/7f1b44970724cfb5e013b5de190ad898069447ef
Binary files differ
diff --git a/fuzzer/corpus/7f21d792b84feb969a588ab8701c3c446025639c b/fuzzer/corpus/7f21d792b84feb969a588ab8701c3c446025639c
new file mode 100644
index 0000000..21d58b4
--- /dev/null
+++ b/fuzzer/corpus/7f21d792b84feb969a588ab8701c3c446025639c
Binary files differ
diff --git a/fuzzer/corpus/7f364438e2867951dc144639564bac988e21092f b/fuzzer/corpus/7f364438e2867951dc144639564bac988e21092f
new file mode 100644
index 0000000..0cbe230
--- /dev/null
+++ b/fuzzer/corpus/7f364438e2867951dc144639564bac988e21092f
Binary files differ
diff --git a/fuzzer/corpus/7f4b7b042a57169cd1ae1b289d8c2be8c0e18b91 b/fuzzer/corpus/7f4b7b042a57169cd1ae1b289d8c2be8c0e18b91
new file mode 100644
index 0000000..f7314f5
--- /dev/null
+++ b/fuzzer/corpus/7f4b7b042a57169cd1ae1b289d8c2be8c0e18b91
Binary files differ
diff --git a/fuzzer/corpus/7f5e9cff3c70bb74434b9a6de050e320da341abc b/fuzzer/corpus/7f5e9cff3c70bb74434b9a6de050e320da341abc
new file mode 100644
index 0000000..45e2291
--- /dev/null
+++ b/fuzzer/corpus/7f5e9cff3c70bb74434b9a6de050e320da341abc
Binary files differ
diff --git a/fuzzer/corpus/7f65151263c21b92829afbc48720b396735c625c b/fuzzer/corpus/7f65151263c21b92829afbc48720b396735c625c
new file mode 100644
index 0000000..404b70c
--- /dev/null
+++ b/fuzzer/corpus/7f65151263c21b92829afbc48720b396735c625c
Binary files differ
diff --git a/fuzzer/corpus/7f94db37978e3d1cba15f6b340849c815ae12f7a b/fuzzer/corpus/7f94db37978e3d1cba15f6b340849c815ae12f7a
new file mode 100644
index 0000000..2f2a185
--- /dev/null
+++ b/fuzzer/corpus/7f94db37978e3d1cba15f6b340849c815ae12f7a
Binary files differ
diff --git a/fuzzer/corpus/7fe5b833a6002dcc0a33f9ae66a8b4c74f87eeaf b/fuzzer/corpus/7fe5b833a6002dcc0a33f9ae66a8b4c74f87eeaf
new file mode 100644
index 0000000..a624f2c
--- /dev/null
+++ b/fuzzer/corpus/7fe5b833a6002dcc0a33f9ae66a8b4c74f87eeaf
Binary files differ
diff --git a/fuzzer/corpus/7ff692f4166d9dbf92e3830324ee54b52dba2cfd b/fuzzer/corpus/7ff692f4166d9dbf92e3830324ee54b52dba2cfd
new file mode 100644
index 0000000..09c94ed
--- /dev/null
+++ b/fuzzer/corpus/7ff692f4166d9dbf92e3830324ee54b52dba2cfd
Binary files differ
diff --git a/fuzzer/corpus/7ff77956a3160d1ad80a039dd981553a82e09e6b b/fuzzer/corpus/7ff77956a3160d1ad80a039dd981553a82e09e6b
new file mode 100644
index 0000000..089c757
--- /dev/null
+++ b/fuzzer/corpus/7ff77956a3160d1ad80a039dd981553a82e09e6b
Binary files differ
diff --git a/fuzzer/corpus/801e9ccd13573640ccdc8f0b36b75b51019fb950 b/fuzzer/corpus/801e9ccd13573640ccdc8f0b36b75b51019fb950
new file mode 100644
index 0000000..cb4b13f
--- /dev/null
+++ b/fuzzer/corpus/801e9ccd13573640ccdc8f0b36b75b51019fb950
Binary files differ
diff --git a/fuzzer/corpus/80212c71e8c6f8efe86c4393414aaeb677c7dca2 b/fuzzer/corpus/80212c71e8c6f8efe86c4393414aaeb677c7dca2
new file mode 100644
index 0000000..96995c9
--- /dev/null
+++ b/fuzzer/corpus/80212c71e8c6f8efe86c4393414aaeb677c7dca2
Binary files differ
diff --git a/fuzzer/corpus/8045c1c468387f52dfbc9bcf24be5692627cdd5b b/fuzzer/corpus/8045c1c468387f52dfbc9bcf24be5692627cdd5b
new file mode 100644
index 0000000..08ce513
--- /dev/null
+++ b/fuzzer/corpus/8045c1c468387f52dfbc9bcf24be5692627cdd5b
Binary files differ
diff --git a/fuzzer/corpus/806f296a2c91af5ba074714eecf21e6d850b1afc b/fuzzer/corpus/806f296a2c91af5ba074714eecf21e6d850b1afc
new file mode 100644
index 0000000..264ae05
--- /dev/null
+++ b/fuzzer/corpus/806f296a2c91af5ba074714eecf21e6d850b1afc
Binary files differ
diff --git a/fuzzer/corpus/808cf56bd306ff3c1e886a5950f953eda3514777 b/fuzzer/corpus/808cf56bd306ff3c1e886a5950f953eda3514777
new file mode 100644
index 0000000..8d5988f
--- /dev/null
+++ b/fuzzer/corpus/808cf56bd306ff3c1e886a5950f953eda3514777
Binary files differ
diff --git a/fuzzer/corpus/813c78fcd5c38bc6f770616a33e76f7ef08d3231 b/fuzzer/corpus/813c78fcd5c38bc6f770616a33e76f7ef08d3231
new file mode 100644
index 0000000..5cdda73
--- /dev/null
+++ b/fuzzer/corpus/813c78fcd5c38bc6f770616a33e76f7ef08d3231
Binary files differ
diff --git a/fuzzer/corpus/815656d073ddeaed4b951541ab59e054a248aa04 b/fuzzer/corpus/815656d073ddeaed4b951541ab59e054a248aa04
new file mode 100644
index 0000000..7776607
--- /dev/null
+++ b/fuzzer/corpus/815656d073ddeaed4b951541ab59e054a248aa04
Binary files differ
diff --git a/fuzzer/corpus/81737015d0a8c3794cb59c21478145c97648cbc7 b/fuzzer/corpus/81737015d0a8c3794cb59c21478145c97648cbc7
new file mode 100644
index 0000000..6a42068
--- /dev/null
+++ b/fuzzer/corpus/81737015d0a8c3794cb59c21478145c97648cbc7
Binary files differ
diff --git a/fuzzer/corpus/817a8ca197fdb664759d1f27d2001875926f682b b/fuzzer/corpus/817a8ca197fdb664759d1f27d2001875926f682b
new file mode 100644
index 0000000..12b7d65
--- /dev/null
+++ b/fuzzer/corpus/817a8ca197fdb664759d1f27d2001875926f682b
Binary files differ
diff --git a/fuzzer/corpus/81a2292134efba059d371e783a777d1be421c638 b/fuzzer/corpus/81a2292134efba059d371e783a777d1be421c638
new file mode 100644
index 0000000..070f0fb
--- /dev/null
+++ b/fuzzer/corpus/81a2292134efba059d371e783a777d1be421c638
Binary files differ
diff --git a/fuzzer/corpus/81a5601ccda21f25bab65ca370ab6cad3267060e b/fuzzer/corpus/81a5601ccda21f25bab65ca370ab6cad3267060e
new file mode 100644
index 0000000..5eefdc9
--- /dev/null
+++ b/fuzzer/corpus/81a5601ccda21f25bab65ca370ab6cad3267060e
Binary files differ
diff --git a/fuzzer/corpus/81c14769b1687e311ca6817e0e884fb5e7aa4f00 b/fuzzer/corpus/81c14769b1687e311ca6817e0e884fb5e7aa4f00
new file mode 100644
index 0000000..713409a
--- /dev/null
+++ b/fuzzer/corpus/81c14769b1687e311ca6817e0e884fb5e7aa4f00
Binary files differ
diff --git a/fuzzer/corpus/81d264f99ba15235fb41af077433ee0e5cbcfce9 b/fuzzer/corpus/81d264f99ba15235fb41af077433ee0e5cbcfce9
new file mode 100644
index 0000000..f912724
--- /dev/null
+++ b/fuzzer/corpus/81d264f99ba15235fb41af077433ee0e5cbcfce9
Binary files differ
diff --git a/fuzzer/corpus/81d2a20eae4d639dd5ba25e52e6da04e85da2416 b/fuzzer/corpus/81d2a20eae4d639dd5ba25e52e6da04e85da2416
new file mode 100644
index 0000000..bc1d34b
--- /dev/null
+++ b/fuzzer/corpus/81d2a20eae4d639dd5ba25e52e6da04e85da2416
Binary files differ
diff --git a/fuzzer/corpus/81d74e228936cabbc6c47467e4640c77c5d4906f b/fuzzer/corpus/81d74e228936cabbc6c47467e4640c77c5d4906f
new file mode 100644
index 0000000..ec0c2f7
--- /dev/null
+++ b/fuzzer/corpus/81d74e228936cabbc6c47467e4640c77c5d4906f
Binary files differ
diff --git a/fuzzer/corpus/822f001dc348d448ee53ae991b94fc9c4b4570fb b/fuzzer/corpus/822f001dc348d448ee53ae991b94fc9c4b4570fb
new file mode 100644
index 0000000..647caa8
--- /dev/null
+++ b/fuzzer/corpus/822f001dc348d448ee53ae991b94fc9c4b4570fb
Binary files differ
diff --git a/fuzzer/corpus/823dc6449bb0e35a9cbe57f4fddde5f150e0431c b/fuzzer/corpus/823dc6449bb0e35a9cbe57f4fddde5f150e0431c
new file mode 100644
index 0000000..29405f3
--- /dev/null
+++ b/fuzzer/corpus/823dc6449bb0e35a9cbe57f4fddde5f150e0431c
Binary files differ
diff --git a/fuzzer/corpus/827264583bc9d8cbbe4459306f2955a8924a1b16 b/fuzzer/corpus/827264583bc9d8cbbe4459306f2955a8924a1b16
new file mode 100644
index 0000000..ec050bc
--- /dev/null
+++ b/fuzzer/corpus/827264583bc9d8cbbe4459306f2955a8924a1b16
Binary files differ
diff --git a/fuzzer/corpus/829194fd1fe674b4ef21af7c2de69dbbc5419e2b b/fuzzer/corpus/829194fd1fe674b4ef21af7c2de69dbbc5419e2b
new file mode 100644
index 0000000..b333f99
--- /dev/null
+++ b/fuzzer/corpus/829194fd1fe674b4ef21af7c2de69dbbc5419e2b
Binary files differ
diff --git a/fuzzer/corpus/83295e9beb965d51bca434999f90b4dd3088ea90 b/fuzzer/corpus/83295e9beb965d51bca434999f90b4dd3088ea90
new file mode 100644
index 0000000..b5d6472
--- /dev/null
+++ b/fuzzer/corpus/83295e9beb965d51bca434999f90b4dd3088ea90
Binary files differ
diff --git a/fuzzer/corpus/832ce48d3ac1c9d187e9376e203e2abf3c2bfe83 b/fuzzer/corpus/832ce48d3ac1c9d187e9376e203e2abf3c2bfe83
new file mode 100644
index 0000000..4d2dc9e
--- /dev/null
+++ b/fuzzer/corpus/832ce48d3ac1c9d187e9376e203e2abf3c2bfe83
Binary files differ
diff --git a/fuzzer/corpus/8343f308867a510c80663a1cc5d6d9f5faaa2e4f b/fuzzer/corpus/8343f308867a510c80663a1cc5d6d9f5faaa2e4f
new file mode 100644
index 0000000..cee7311
--- /dev/null
+++ b/fuzzer/corpus/8343f308867a510c80663a1cc5d6d9f5faaa2e4f
Binary files differ
diff --git a/fuzzer/corpus/8357c65dfa723f993a7adc4435dab2e869fb6385 b/fuzzer/corpus/8357c65dfa723f993a7adc4435dab2e869fb6385
new file mode 100644
index 0000000..cee0014
--- /dev/null
+++ b/fuzzer/corpus/8357c65dfa723f993a7adc4435dab2e869fb6385
Binary files differ
diff --git a/fuzzer/corpus/8368128be7299499d47fd820a33e22ba03f0f346 b/fuzzer/corpus/8368128be7299499d47fd820a33e22ba03f0f346
new file mode 100644
index 0000000..b2e467b
--- /dev/null
+++ b/fuzzer/corpus/8368128be7299499d47fd820a33e22ba03f0f346
Binary files differ
diff --git a/fuzzer/corpus/836e8a86b74d983f2ebdf44ccf89aafb43be6728 b/fuzzer/corpus/836e8a86b74d983f2ebdf44ccf89aafb43be6728
new file mode 100644
index 0000000..0d22d1c
--- /dev/null
+++ b/fuzzer/corpus/836e8a86b74d983f2ebdf44ccf89aafb43be6728
Binary files differ
diff --git a/fuzzer/corpus/838fb7515c42cc990117fc4cd9aee4e5e5902901 b/fuzzer/corpus/838fb7515c42cc990117fc4cd9aee4e5e5902901
new file mode 100644
index 0000000..de2d55c
--- /dev/null
+++ b/fuzzer/corpus/838fb7515c42cc990117fc4cd9aee4e5e5902901
Binary files differ
diff --git a/fuzzer/corpus/839bd7f3087b6ef97eb403ad8f9c50dde6113033 b/fuzzer/corpus/839bd7f3087b6ef97eb403ad8f9c50dde6113033
new file mode 100644
index 0000000..6b065d3
--- /dev/null
+++ b/fuzzer/corpus/839bd7f3087b6ef97eb403ad8f9c50dde6113033
Binary files differ
diff --git a/fuzzer/corpus/83aaf656c9cec31abf1df18e5901a4c1ec514d1d b/fuzzer/corpus/83aaf656c9cec31abf1df18e5901a4c1ec514d1d
new file mode 100644
index 0000000..36babec
--- /dev/null
+++ b/fuzzer/corpus/83aaf656c9cec31abf1df18e5901a4c1ec514d1d
Binary files differ
diff --git a/fuzzer/corpus/83ac3bf8271f06e6990d9712e32c62c014c91aad b/fuzzer/corpus/83ac3bf8271f06e6990d9712e32c62c014c91aad
new file mode 100644
index 0000000..769c277
--- /dev/null
+++ b/fuzzer/corpus/83ac3bf8271f06e6990d9712e32c62c014c91aad
Binary files differ
diff --git a/fuzzer/corpus/83c2c8e8d2dab3587107b564be2bfdf77239439e b/fuzzer/corpus/83c2c8e8d2dab3587107b564be2bfdf77239439e
new file mode 100644
index 0000000..72feef0
--- /dev/null
+++ b/fuzzer/corpus/83c2c8e8d2dab3587107b564be2bfdf77239439e
Binary files differ
diff --git a/fuzzer/corpus/83ceb37e0911c1ea340cfe06aae96c9792c0ee2d b/fuzzer/corpus/83ceb37e0911c1ea340cfe06aae96c9792c0ee2d
new file mode 100644
index 0000000..d2539ce
--- /dev/null
+++ b/fuzzer/corpus/83ceb37e0911c1ea340cfe06aae96c9792c0ee2d
Binary files differ
diff --git a/fuzzer/corpus/83ff6a97a76379dbc705cb2a649dcafd3ec5800e b/fuzzer/corpus/83ff6a97a76379dbc705cb2a649dcafd3ec5800e
new file mode 100644
index 0000000..a019202
--- /dev/null
+++ b/fuzzer/corpus/83ff6a97a76379dbc705cb2a649dcafd3ec5800e
Binary files differ
diff --git a/fuzzer/corpus/84169541dea42a9ead48a05467c87e476da5a423 b/fuzzer/corpus/84169541dea42a9ead48a05467c87e476da5a423
new file mode 100644
index 0000000..1c1e3af
--- /dev/null
+++ b/fuzzer/corpus/84169541dea42a9ead48a05467c87e476da5a423
Binary files differ
diff --git a/fuzzer/corpus/84269ef122300aff914d44e874fd289d71952537 b/fuzzer/corpus/84269ef122300aff914d44e874fd289d71952537
new file mode 100644
index 0000000..7b4541a
--- /dev/null
+++ b/fuzzer/corpus/84269ef122300aff914d44e874fd289d71952537
Binary files differ
diff --git a/fuzzer/corpus/843ad218f56b25a9a65e912c5ae5087c051820ec b/fuzzer/corpus/843ad218f56b25a9a65e912c5ae5087c051820ec
new file mode 100644
index 0000000..4584e00
--- /dev/null
+++ b/fuzzer/corpus/843ad218f56b25a9a65e912c5ae5087c051820ec
Binary files differ
diff --git a/fuzzer/corpus/843c395d632a4a7d2ef57d3cdd2f56d26f7e4f99 b/fuzzer/corpus/843c395d632a4a7d2ef57d3cdd2f56d26f7e4f99
new file mode 100644
index 0000000..3e4517b
--- /dev/null
+++ b/fuzzer/corpus/843c395d632a4a7d2ef57d3cdd2f56d26f7e4f99
Binary files differ
diff --git a/fuzzer/corpus/84697aacc5b9d17211b3209c1d2a1ffccf66104d b/fuzzer/corpus/84697aacc5b9d17211b3209c1d2a1ffccf66104d
new file mode 100644
index 0000000..130f222
--- /dev/null
+++ b/fuzzer/corpus/84697aacc5b9d17211b3209c1d2a1ffccf66104d
Binary files differ
diff --git a/fuzzer/corpus/84aa29d9f1c07ed0fce2749b0d6c3ad91d091d72 b/fuzzer/corpus/84aa29d9f1c07ed0fce2749b0d6c3ad91d091d72
new file mode 100644
index 0000000..32babcc
--- /dev/null
+++ b/fuzzer/corpus/84aa29d9f1c07ed0fce2749b0d6c3ad91d091d72
Binary files differ
diff --git a/fuzzer/corpus/84c3b7c1bed5e7bec706d1bc9491ec333cdc14cf b/fuzzer/corpus/84c3b7c1bed5e7bec706d1bc9491ec333cdc14cf
new file mode 100644
index 0000000..e270c9a
--- /dev/null
+++ b/fuzzer/corpus/84c3b7c1bed5e7bec706d1bc9491ec333cdc14cf
Binary files differ
diff --git a/fuzzer/corpus/84d9ee97e80792f722cf3752a050e357a2c73fd9 b/fuzzer/corpus/84d9ee97e80792f722cf3752a050e357a2c73fd9
new file mode 100644
index 0000000..a48813c
--- /dev/null
+++ b/fuzzer/corpus/84d9ee97e80792f722cf3752a050e357a2c73fd9
Binary files differ
diff --git a/fuzzer/corpus/84e0972b0da768a23fd43d01322ec552c1635ad4 b/fuzzer/corpus/84e0972b0da768a23fd43d01322ec552c1635ad4
new file mode 100644
index 0000000..f417217
--- /dev/null
+++ b/fuzzer/corpus/84e0972b0da768a23fd43d01322ec552c1635ad4
Binary files differ
diff --git a/fuzzer/corpus/84e1fe67392229f6c566803ba88cd65c05315735 b/fuzzer/corpus/84e1fe67392229f6c566803ba88cd65c05315735
new file mode 100644
index 0000000..67f50b6
--- /dev/null
+++ b/fuzzer/corpus/84e1fe67392229f6c566803ba88cd65c05315735
Binary files differ
diff --git a/fuzzer/corpus/84f8b5f5b9c5a7c34a40f4eabb333f2d908ee678 b/fuzzer/corpus/84f8b5f5b9c5a7c34a40f4eabb333f2d908ee678
new file mode 100644
index 0000000..05bae2f
--- /dev/null
+++ b/fuzzer/corpus/84f8b5f5b9c5a7c34a40f4eabb333f2d908ee678
Binary files differ
diff --git a/fuzzer/corpus/850557e4b78c6bb31c67e51bfae6235bfcc9b2f3 b/fuzzer/corpus/850557e4b78c6bb31c67e51bfae6235bfcc9b2f3
new file mode 100644
index 0000000..10ea07c
--- /dev/null
+++ b/fuzzer/corpus/850557e4b78c6bb31c67e51bfae6235bfcc9b2f3
Binary files differ
diff --git a/fuzzer/corpus/851beeb3295d1997cadcd226d8ae05c9294df9f0 b/fuzzer/corpus/851beeb3295d1997cadcd226d8ae05c9294df9f0
new file mode 100644
index 0000000..cece54a
--- /dev/null
+++ b/fuzzer/corpus/851beeb3295d1997cadcd226d8ae05c9294df9f0
Binary files differ
diff --git a/fuzzer/corpus/852612e944281ec8139573813dab235aeb6a6cc9 b/fuzzer/corpus/852612e944281ec8139573813dab235aeb6a6cc9
new file mode 100644
index 0000000..81f2319
--- /dev/null
+++ b/fuzzer/corpus/852612e944281ec8139573813dab235aeb6a6cc9
Binary files differ
diff --git a/fuzzer/corpus/85330683dc886c9529e975e47ce499ca5ea93d04 b/fuzzer/corpus/85330683dc886c9529e975e47ce499ca5ea93d04
new file mode 100644
index 0000000..c6d2af8
--- /dev/null
+++ b/fuzzer/corpus/85330683dc886c9529e975e47ce499ca5ea93d04
Binary files differ
diff --git a/fuzzer/corpus/853bee8034cdaf5508442392fd1ddba978ce277a b/fuzzer/corpus/853bee8034cdaf5508442392fd1ddba978ce277a
new file mode 100644
index 0000000..43ce77d
--- /dev/null
+++ b/fuzzer/corpus/853bee8034cdaf5508442392fd1ddba978ce277a
Binary files differ
diff --git a/fuzzer/corpus/856f290a4e613976f50b0c1ae9449cdf60964110 b/fuzzer/corpus/856f290a4e613976f50b0c1ae9449cdf60964110
new file mode 100644
index 0000000..b3342cf
--- /dev/null
+++ b/fuzzer/corpus/856f290a4e613976f50b0c1ae9449cdf60964110
Binary files differ
diff --git a/fuzzer/corpus/85c2117ab7b9c18f6e21eb42bb2d5ab936fa5c3e b/fuzzer/corpus/85c2117ab7b9c18f6e21eb42bb2d5ab936fa5c3e
new file mode 100644
index 0000000..75f1f2f
--- /dev/null
+++ b/fuzzer/corpus/85c2117ab7b9c18f6e21eb42bb2d5ab936fa5c3e
Binary files differ
diff --git a/fuzzer/corpus/85c6633f1c4be30a33c84fba0a4d974478968950 b/fuzzer/corpus/85c6633f1c4be30a33c84fba0a4d974478968950
new file mode 100644
index 0000000..7108608
--- /dev/null
+++ b/fuzzer/corpus/85c6633f1c4be30a33c84fba0a4d974478968950
Binary files differ
diff --git a/fuzzer/corpus/85cd491db9b3e30f8de137fe417210e443c7ed8a b/fuzzer/corpus/85cd491db9b3e30f8de137fe417210e443c7ed8a
new file mode 100644
index 0000000..01de659
--- /dev/null
+++ b/fuzzer/corpus/85cd491db9b3e30f8de137fe417210e443c7ed8a
Binary files differ
diff --git a/fuzzer/corpus/85e378555ca5b283f7d2e9472dc330d98ad3cd52 b/fuzzer/corpus/85e378555ca5b283f7d2e9472dc330d98ad3cd52
new file mode 100644
index 0000000..fd06e0e
--- /dev/null
+++ b/fuzzer/corpus/85e378555ca5b283f7d2e9472dc330d98ad3cd52
Binary files differ
diff --git a/fuzzer/corpus/8600f7f2793a98d56e3d0329772f462d9aaa810e b/fuzzer/corpus/8600f7f2793a98d56e3d0329772f462d9aaa810e
new file mode 100644
index 0000000..25e8b04
--- /dev/null
+++ b/fuzzer/corpus/8600f7f2793a98d56e3d0329772f462d9aaa810e
Binary files differ
diff --git a/fuzzer/corpus/8602854c2537d10d71f0a1feed9a49976d0a17bd b/fuzzer/corpus/8602854c2537d10d71f0a1feed9a49976d0a17bd
new file mode 100644
index 0000000..e7bba9c
--- /dev/null
+++ b/fuzzer/corpus/8602854c2537d10d71f0a1feed9a49976d0a17bd
Binary files differ
diff --git a/fuzzer/corpus/8602c8f5c2f3e050d9825b2661ebeb90aca5520b b/fuzzer/corpus/8602c8f5c2f3e050d9825b2661ebeb90aca5520b
new file mode 100644
index 0000000..b3aec4e
--- /dev/null
+++ b/fuzzer/corpus/8602c8f5c2f3e050d9825b2661ebeb90aca5520b
Binary files differ
diff --git a/fuzzer/corpus/8621400cde2f424219d1db947833e6d78b96a750 b/fuzzer/corpus/8621400cde2f424219d1db947833e6d78b96a750
new file mode 100644
index 0000000..fe4acc9
--- /dev/null
+++ b/fuzzer/corpus/8621400cde2f424219d1db947833e6d78b96a750
Binary files differ
diff --git a/fuzzer/corpus/863d5803a1d1672d1a49af867acac045599e2a57 b/fuzzer/corpus/863d5803a1d1672d1a49af867acac045599e2a57
new file mode 100644
index 0000000..ef65abd
--- /dev/null
+++ b/fuzzer/corpus/863d5803a1d1672d1a49af867acac045599e2a57
Binary files differ
diff --git a/fuzzer/corpus/86809a69ff6837e8ed7a777aa8712f6ce4814cc4 b/fuzzer/corpus/86809a69ff6837e8ed7a777aa8712f6ce4814cc4
new file mode 100644
index 0000000..3e0fe94
--- /dev/null
+++ b/fuzzer/corpus/86809a69ff6837e8ed7a777aa8712f6ce4814cc4
Binary files differ
diff --git a/fuzzer/corpus/8693ddb1919f7d855269474d7dd4d6c2d62f2c6d b/fuzzer/corpus/8693ddb1919f7d855269474d7dd4d6c2d62f2c6d
new file mode 100644
index 0000000..e887c73
--- /dev/null
+++ b/fuzzer/corpus/8693ddb1919f7d855269474d7dd4d6c2d62f2c6d
Binary files differ
diff --git a/fuzzer/corpus/869c67e392cec89e4385c74586f2745ac73227d1 b/fuzzer/corpus/869c67e392cec89e4385c74586f2745ac73227d1
new file mode 100644
index 0000000..98278b3
--- /dev/null
+++ b/fuzzer/corpus/869c67e392cec89e4385c74586f2745ac73227d1
Binary files differ
diff --git a/fuzzer/corpus/86c231d06de82c7b9323381c890c08781cffc920 b/fuzzer/corpus/86c231d06de82c7b9323381c890c08781cffc920
new file mode 100644
index 0000000..c379b1b
--- /dev/null
+++ b/fuzzer/corpus/86c231d06de82c7b9323381c890c08781cffc920
Binary files differ
diff --git a/fuzzer/corpus/8709e064a75e666341bd138cf01ea00c2baa8838 b/fuzzer/corpus/8709e064a75e666341bd138cf01ea00c2baa8838
new file mode 100644
index 0000000..0645619
--- /dev/null
+++ b/fuzzer/corpus/8709e064a75e666341bd138cf01ea00c2baa8838
Binary files differ
diff --git a/fuzzer/corpus/870ab117cdacd7c533576194ec83ae4c4f021361 b/fuzzer/corpus/870ab117cdacd7c533576194ec83ae4c4f021361
new file mode 100644
index 0000000..0b0ca53
--- /dev/null
+++ b/fuzzer/corpus/870ab117cdacd7c533576194ec83ae4c4f021361
Binary files differ
diff --git a/fuzzer/corpus/871a393a6a16621389065074177176ebe605e38d b/fuzzer/corpus/871a393a6a16621389065074177176ebe605e38d
new file mode 100644
index 0000000..a47d548
--- /dev/null
+++ b/fuzzer/corpus/871a393a6a16621389065074177176ebe605e38d
Binary files differ
diff --git a/fuzzer/corpus/871e89cad3d9428e4f9b434ee977fd6115bff4be b/fuzzer/corpus/871e89cad3d9428e4f9b434ee977fd6115bff4be
new file mode 100644
index 0000000..4cd0fef
--- /dev/null
+++ b/fuzzer/corpus/871e89cad3d9428e4f9b434ee977fd6115bff4be
Binary files differ
diff --git a/fuzzer/corpus/87312761190a6d7c95d9ca38bda0312334b0be9b b/fuzzer/corpus/87312761190a6d7c95d9ca38bda0312334b0be9b
new file mode 100644
index 0000000..9b0e55e
--- /dev/null
+++ b/fuzzer/corpus/87312761190a6d7c95d9ca38bda0312334b0be9b
Binary files differ
diff --git a/fuzzer/corpus/875acf905688e648da8ef9cd69730dbbd54e86b7 b/fuzzer/corpus/875acf905688e648da8ef9cd69730dbbd54e86b7
new file mode 100644
index 0000000..0b5e149
--- /dev/null
+++ b/fuzzer/corpus/875acf905688e648da8ef9cd69730dbbd54e86b7
Binary files differ
diff --git a/fuzzer/corpus/876a402c981413c92b7a2b69cec555405f31d5f8 b/fuzzer/corpus/876a402c981413c92b7a2b69cec555405f31d5f8
new file mode 100644
index 0000000..9bcf475
--- /dev/null
+++ b/fuzzer/corpus/876a402c981413c92b7a2b69cec555405f31d5f8
Binary files differ
diff --git a/fuzzer/corpus/876a8dc97ae0d995214c8c724e3f4938a6fe084f b/fuzzer/corpus/876a8dc97ae0d995214c8c724e3f4938a6fe084f
new file mode 100644
index 0000000..f57d161
--- /dev/null
+++ b/fuzzer/corpus/876a8dc97ae0d995214c8c724e3f4938a6fe084f
Binary files differ
diff --git a/fuzzer/corpus/87776d60387b3ce817199d4cd87f77e30bc9a0ce b/fuzzer/corpus/87776d60387b3ce817199d4cd87f77e30bc9a0ce
new file mode 100644
index 0000000..21d9b72
--- /dev/null
+++ b/fuzzer/corpus/87776d60387b3ce817199d4cd87f77e30bc9a0ce
Binary files differ
diff --git a/fuzzer/corpus/879f9560171860c1ebae7be6cebfc308ca8e1c17 b/fuzzer/corpus/879f9560171860c1ebae7be6cebfc308ca8e1c17
new file mode 100644
index 0000000..7ee2842
--- /dev/null
+++ b/fuzzer/corpus/879f9560171860c1ebae7be6cebfc308ca8e1c17
Binary files differ
diff --git a/fuzzer/corpus/87a0d7637479e620efe963d2dec085916fa810fa b/fuzzer/corpus/87a0d7637479e620efe963d2dec085916fa810fa
new file mode 100644
index 0000000..0e390c4
--- /dev/null
+++ b/fuzzer/corpus/87a0d7637479e620efe963d2dec085916fa810fa
Binary files differ
diff --git a/fuzzer/corpus/8836f451454ff9741877b0f856c42e2dabb0ee0e b/fuzzer/corpus/8836f451454ff9741877b0f856c42e2dabb0ee0e
new file mode 100644
index 0000000..cfd4886
--- /dev/null
+++ b/fuzzer/corpus/8836f451454ff9741877b0f856c42e2dabb0ee0e
Binary files differ
diff --git a/fuzzer/corpus/8871564ba0add28be21ffe008f11ce91fd38147a b/fuzzer/corpus/8871564ba0add28be21ffe008f11ce91fd38147a
new file mode 100644
index 0000000..b638a88
--- /dev/null
+++ b/fuzzer/corpus/8871564ba0add28be21ffe008f11ce91fd38147a
Binary files differ
diff --git a/fuzzer/corpus/887fd53302917e27b02fa2cc85ec35b9b5d43041 b/fuzzer/corpus/887fd53302917e27b02fa2cc85ec35b9b5d43041
new file mode 100644
index 0000000..3bb0dc4
--- /dev/null
+++ b/fuzzer/corpus/887fd53302917e27b02fa2cc85ec35b9b5d43041
Binary files differ
diff --git a/fuzzer/corpus/889d9c11977466f0952cf51d726930eaf880f2c5 b/fuzzer/corpus/889d9c11977466f0952cf51d726930eaf880f2c5
new file mode 100644
index 0000000..50a7a93
--- /dev/null
+++ b/fuzzer/corpus/889d9c11977466f0952cf51d726930eaf880f2c5
Binary files differ
diff --git a/fuzzer/corpus/88e331430bbae0eea37b9686b20fb37be874217d b/fuzzer/corpus/88e331430bbae0eea37b9686b20fb37be874217d
new file mode 100644
index 0000000..f99681d
--- /dev/null
+++ b/fuzzer/corpus/88e331430bbae0eea37b9686b20fb37be874217d
Binary files differ
diff --git a/fuzzer/corpus/88f97414425e6fb2ea409a72141e68bca93fd56d b/fuzzer/corpus/88f97414425e6fb2ea409a72141e68bca93fd56d
new file mode 100644
index 0000000..8300887
--- /dev/null
+++ b/fuzzer/corpus/88f97414425e6fb2ea409a72141e68bca93fd56d
Binary files differ
diff --git a/fuzzer/corpus/890c7d9b9112b86ea26820718f2f8540f14c4132 b/fuzzer/corpus/890c7d9b9112b86ea26820718f2f8540f14c4132
new file mode 100644
index 0000000..0507cc9
--- /dev/null
+++ b/fuzzer/corpus/890c7d9b9112b86ea26820718f2f8540f14c4132
Binary files differ
diff --git a/fuzzer/corpus/892c436a5218d714f0b772ba6011cfcd0b77706d b/fuzzer/corpus/892c436a5218d714f0b772ba6011cfcd0b77706d
new file mode 100644
index 0000000..bbba4df
--- /dev/null
+++ b/fuzzer/corpus/892c436a5218d714f0b772ba6011cfcd0b77706d
Binary files differ
diff --git a/fuzzer/corpus/8939a893b12c5a792930d7d8c353408314182391 b/fuzzer/corpus/8939a893b12c5a792930d7d8c353408314182391
new file mode 100644
index 0000000..3e016ad
--- /dev/null
+++ b/fuzzer/corpus/8939a893b12c5a792930d7d8c353408314182391
Binary files differ
diff --git a/fuzzer/corpus/89431df7a1e1f0b7a8f584f0384bdc2a7a511cc4 b/fuzzer/corpus/89431df7a1e1f0b7a8f584f0384bdc2a7a511cc4
new file mode 100644
index 0000000..fd85867
--- /dev/null
+++ b/fuzzer/corpus/89431df7a1e1f0b7a8f584f0384bdc2a7a511cc4
Binary files differ
diff --git a/fuzzer/corpus/898aac0c810f2e2c74f78936540260561fe8b3e4 b/fuzzer/corpus/898aac0c810f2e2c74f78936540260561fe8b3e4
new file mode 100644
index 0000000..44da1fe
--- /dev/null
+++ b/fuzzer/corpus/898aac0c810f2e2c74f78936540260561fe8b3e4
Binary files differ
diff --git a/fuzzer/corpus/89b094c57c741e7b84cb15e900085165b6a54201 b/fuzzer/corpus/89b094c57c741e7b84cb15e900085165b6a54201
new file mode 100644
index 0000000..6486d5d
--- /dev/null
+++ b/fuzzer/corpus/89b094c57c741e7b84cb15e900085165b6a54201
Binary files differ
diff --git a/fuzzer/corpus/89e3d570a222c18bc945408b71bd3f08e143c063 b/fuzzer/corpus/89e3d570a222c18bc945408b71bd3f08e143c063
new file mode 100644
index 0000000..c088542
--- /dev/null
+++ b/fuzzer/corpus/89e3d570a222c18bc945408b71bd3f08e143c063
Binary files differ
diff --git a/fuzzer/corpus/8a0b3eccb0767fabc3f46ba7bf63e31ccce3b02b b/fuzzer/corpus/8a0b3eccb0767fabc3f46ba7bf63e31ccce3b02b
new file mode 100644
index 0000000..ce691af
--- /dev/null
+++ b/fuzzer/corpus/8a0b3eccb0767fabc3f46ba7bf63e31ccce3b02b
Binary files differ
diff --git a/fuzzer/corpus/8a0f401f798207db6c8b01913220e4ff4049cc5e b/fuzzer/corpus/8a0f401f798207db6c8b01913220e4ff4049cc5e
new file mode 100644
index 0000000..3d73d76
--- /dev/null
+++ b/fuzzer/corpus/8a0f401f798207db6c8b01913220e4ff4049cc5e
Binary files differ
diff --git a/fuzzer/corpus/8a22188c29211f7e6906e37f43c4460e2812a832 b/fuzzer/corpus/8a22188c29211f7e6906e37f43c4460e2812a832
new file mode 100644
index 0000000..969cfaa
--- /dev/null
+++ b/fuzzer/corpus/8a22188c29211f7e6906e37f43c4460e2812a832
Binary files differ
diff --git a/fuzzer/corpus/8a33417e455ee41b684d90e2d32cf8806e629fa5 b/fuzzer/corpus/8a33417e455ee41b684d90e2d32cf8806e629fa5
new file mode 100644
index 0000000..14887f2
--- /dev/null
+++ b/fuzzer/corpus/8a33417e455ee41b684d90e2d32cf8806e629fa5
Binary files differ
diff --git a/fuzzer/corpus/8a5b85c717c89c65dc63fac75b01781c118c7c12 b/fuzzer/corpus/8a5b85c717c89c65dc63fac75b01781c118c7c12
new file mode 100644
index 0000000..5ff26a6
--- /dev/null
+++ b/fuzzer/corpus/8a5b85c717c89c65dc63fac75b01781c118c7c12
Binary files differ
diff --git a/fuzzer/corpus/8a71421daf13eacddcb0d8cfd490703916557780 b/fuzzer/corpus/8a71421daf13eacddcb0d8cfd490703916557780
new file mode 100644
index 0000000..9cf248d
--- /dev/null
+++ b/fuzzer/corpus/8a71421daf13eacddcb0d8cfd490703916557780
Binary files differ
diff --git a/fuzzer/corpus/8a7364f68bda9f6fa37d7cd945f89308f2220c6c b/fuzzer/corpus/8a7364f68bda9f6fa37d7cd945f89308f2220c6c
new file mode 100644
index 0000000..2c29ab1
--- /dev/null
+++ b/fuzzer/corpus/8a7364f68bda9f6fa37d7cd945f89308f2220c6c
Binary files differ
diff --git a/fuzzer/corpus/8a7bfff5d38f3462e876e712d0818e4f009e0d53 b/fuzzer/corpus/8a7bfff5d38f3462e876e712d0818e4f009e0d53
new file mode 100644
index 0000000..9337afc
--- /dev/null
+++ b/fuzzer/corpus/8a7bfff5d38f3462e876e712d0818e4f009e0d53
Binary files differ
diff --git a/fuzzer/corpus/8a8e8718644eaec23c0c27e2a7737fde55df8b1b b/fuzzer/corpus/8a8e8718644eaec23c0c27e2a7737fde55df8b1b
new file mode 100644
index 0000000..35721da
--- /dev/null
+++ b/fuzzer/corpus/8a8e8718644eaec23c0c27e2a7737fde55df8b1b
Binary files differ
diff --git a/fuzzer/corpus/8ac69ec669a6cd0f8d68c441915970591f1c8939 b/fuzzer/corpus/8ac69ec669a6cd0f8d68c441915970591f1c8939
new file mode 100644
index 0000000..dd7145f
--- /dev/null
+++ b/fuzzer/corpus/8ac69ec669a6cd0f8d68c441915970591f1c8939
Binary files differ
diff --git a/fuzzer/corpus/8acfcf0fe8b00098ddb6a27a2e096b0e06b47e51 b/fuzzer/corpus/8acfcf0fe8b00098ddb6a27a2e096b0e06b47e51
new file mode 100644
index 0000000..81fafce
--- /dev/null
+++ b/fuzzer/corpus/8acfcf0fe8b00098ddb6a27a2e096b0e06b47e51
Binary files differ
diff --git a/fuzzer/corpus/8ad02a0ed4b7ba475c9ab4ec3e763dd476060fc8 b/fuzzer/corpus/8ad02a0ed4b7ba475c9ab4ec3e763dd476060fc8
new file mode 100644
index 0000000..9010426
--- /dev/null
+++ b/fuzzer/corpus/8ad02a0ed4b7ba475c9ab4ec3e763dd476060fc8
Binary files differ
diff --git a/fuzzer/corpus/8ad93fd0d1962574b6c11eabbd2f10926f8fe761 b/fuzzer/corpus/8ad93fd0d1962574b6c11eabbd2f10926f8fe761
new file mode 100644
index 0000000..dbd9476
--- /dev/null
+++ b/fuzzer/corpus/8ad93fd0d1962574b6c11eabbd2f10926f8fe761
Binary files differ
diff --git a/fuzzer/corpus/8ae43351f05a1f4f7c780ba1b20efba0f094923c b/fuzzer/corpus/8ae43351f05a1f4f7c780ba1b20efba0f094923c
new file mode 100644
index 0000000..74feb94
--- /dev/null
+++ b/fuzzer/corpus/8ae43351f05a1f4f7c780ba1b20efba0f094923c
Binary files differ
diff --git a/fuzzer/corpus/8ae8aaf59850fb7d967e8eba8e3eb0e5d4acbc2b b/fuzzer/corpus/8ae8aaf59850fb7d967e8eba8e3eb0e5d4acbc2b
new file mode 100644
index 0000000..790aeb1
--- /dev/null
+++ b/fuzzer/corpus/8ae8aaf59850fb7d967e8eba8e3eb0e5d4acbc2b
Binary files differ
diff --git a/fuzzer/corpus/8af7b82ad27d65e0cde8609e40578070b3e29982 b/fuzzer/corpus/8af7b82ad27d65e0cde8609e40578070b3e29982
new file mode 100644
index 0000000..f0a3ed3
--- /dev/null
+++ b/fuzzer/corpus/8af7b82ad27d65e0cde8609e40578070b3e29982
Binary files differ
diff --git a/fuzzer/corpus/8b226f84c1593a323c1a1387b5f76ce2d27053df b/fuzzer/corpus/8b226f84c1593a323c1a1387b5f76ce2d27053df
new file mode 100644
index 0000000..dc149be
--- /dev/null
+++ b/fuzzer/corpus/8b226f84c1593a323c1a1387b5f76ce2d27053df
Binary files differ
diff --git a/fuzzer/corpus/8b2e0dda68c540ab2670f0a4a03265b8e5789902 b/fuzzer/corpus/8b2e0dda68c540ab2670f0a4a03265b8e5789902
new file mode 100644
index 0000000..0a5c0a1
--- /dev/null
+++ b/fuzzer/corpus/8b2e0dda68c540ab2670f0a4a03265b8e5789902
Binary files differ
diff --git a/fuzzer/corpus/8b46dc3a74c1f00ec2d797d4725bf77bb26b8618 b/fuzzer/corpus/8b46dc3a74c1f00ec2d797d4725bf77bb26b8618
new file mode 100644
index 0000000..c6609f4
--- /dev/null
+++ b/fuzzer/corpus/8b46dc3a74c1f00ec2d797d4725bf77bb26b8618
Binary files differ
diff --git a/fuzzer/corpus/8b9dc8086e6803264f339153d8d501cf0b304fd9 b/fuzzer/corpus/8b9dc8086e6803264f339153d8d501cf0b304fd9
new file mode 100644
index 0000000..b51092f
--- /dev/null
+++ b/fuzzer/corpus/8b9dc8086e6803264f339153d8d501cf0b304fd9
Binary files differ
diff --git a/fuzzer/corpus/8ba0b96015902ac14f3a2066f517302fe28c6edf b/fuzzer/corpus/8ba0b96015902ac14f3a2066f517302fe28c6edf
new file mode 100644
index 0000000..faf4833
--- /dev/null
+++ b/fuzzer/corpus/8ba0b96015902ac14f3a2066f517302fe28c6edf
Binary files differ
diff --git a/fuzzer/corpus/8bb5913391d907b3829e475a0d982e98217230fe b/fuzzer/corpus/8bb5913391d907b3829e475a0d982e98217230fe
new file mode 100644
index 0000000..f842b50
--- /dev/null
+++ b/fuzzer/corpus/8bb5913391d907b3829e475a0d982e98217230fe
Binary files differ
diff --git a/fuzzer/corpus/8bda61d0d497216bde6d2865b7f8c26df0702954 b/fuzzer/corpus/8bda61d0d497216bde6d2865b7f8c26df0702954
new file mode 100644
index 0000000..4bcf3d2
--- /dev/null
+++ b/fuzzer/corpus/8bda61d0d497216bde6d2865b7f8c26df0702954
Binary files differ
diff --git a/fuzzer/corpus/8bed6f305898ddcfaf14ac4c4d3febb1b69e56dc b/fuzzer/corpus/8bed6f305898ddcfaf14ac4c4d3febb1b69e56dc
new file mode 100644
index 0000000..f8ee90b
--- /dev/null
+++ b/fuzzer/corpus/8bed6f305898ddcfaf14ac4c4d3febb1b69e56dc
Binary files differ
diff --git a/fuzzer/corpus/8c4753a130f6268258ac1cc39108b843a4210df4 b/fuzzer/corpus/8c4753a130f6268258ac1cc39108b843a4210df4
new file mode 100644
index 0000000..5cbf399
--- /dev/null
+++ b/fuzzer/corpus/8c4753a130f6268258ac1cc39108b843a4210df4
Binary files differ
diff --git a/fuzzer/corpus/8c84bd43c113b9f1fa988796307fe5ed77b923c8 b/fuzzer/corpus/8c84bd43c113b9f1fa988796307fe5ed77b923c8
new file mode 100644
index 0000000..635a796
--- /dev/null
+++ b/fuzzer/corpus/8c84bd43c113b9f1fa988796307fe5ed77b923c8
Binary files differ
diff --git a/fuzzer/corpus/8c89e29dd1d57d7e5616a3b68d39678267df60d2 b/fuzzer/corpus/8c89e29dd1d57d7e5616a3b68d39678267df60d2
new file mode 100644
index 0000000..441c144
--- /dev/null
+++ b/fuzzer/corpus/8c89e29dd1d57d7e5616a3b68d39678267df60d2
Binary files differ
diff --git a/fuzzer/corpus/8cb003b20ad361f711a61634a1e280dcf7ca4910 b/fuzzer/corpus/8cb003b20ad361f711a61634a1e280dcf7ca4910
new file mode 100644
index 0000000..737b53b
--- /dev/null
+++ b/fuzzer/corpus/8cb003b20ad361f711a61634a1e280dcf7ca4910
Binary files differ
diff --git a/fuzzer/corpus/8cbe50e5868507dbfa64360ab8935689ac005f42 b/fuzzer/corpus/8cbe50e5868507dbfa64360ab8935689ac005f42
new file mode 100644
index 0000000..ce77ade
--- /dev/null
+++ b/fuzzer/corpus/8cbe50e5868507dbfa64360ab8935689ac005f42
Binary files differ
diff --git a/fuzzer/corpus/8ced8f7fc42421ce6d4920c62688b621fabbbf60 b/fuzzer/corpus/8ced8f7fc42421ce6d4920c62688b621fabbbf60
new file mode 100644
index 0000000..ab2dd97
--- /dev/null
+++ b/fuzzer/corpus/8ced8f7fc42421ce6d4920c62688b621fabbbf60
Binary files differ
diff --git a/fuzzer/corpus/8d09b8839f60d7289c31fc73a47767def27110ab b/fuzzer/corpus/8d09b8839f60d7289c31fc73a47767def27110ab
new file mode 100644
index 0000000..c88d487
--- /dev/null
+++ b/fuzzer/corpus/8d09b8839f60d7289c31fc73a47767def27110ab
Binary files differ
diff --git a/fuzzer/corpus/8d2a81f2b79778b61e84b96ce111083b918d12b1 b/fuzzer/corpus/8d2a81f2b79778b61e84b96ce111083b918d12b1
new file mode 100644
index 0000000..6644e7e
--- /dev/null
+++ b/fuzzer/corpus/8d2a81f2b79778b61e84b96ce111083b918d12b1
Binary files differ
diff --git a/fuzzer/corpus/8d37cfc4bc1b0d607e967a774712de0cfdc1d0d6 b/fuzzer/corpus/8d37cfc4bc1b0d607e967a774712de0cfdc1d0d6
new file mode 100644
index 0000000..c7985a3
--- /dev/null
+++ b/fuzzer/corpus/8d37cfc4bc1b0d607e967a774712de0cfdc1d0d6
Binary files differ
diff --git a/fuzzer/corpus/8d45ad1dc43b87bd5e87ac210a13222135ee8e2f b/fuzzer/corpus/8d45ad1dc43b87bd5e87ac210a13222135ee8e2f
new file mode 100644
index 0000000..341b9c0
--- /dev/null
+++ b/fuzzer/corpus/8d45ad1dc43b87bd5e87ac210a13222135ee8e2f
Binary files differ
diff --git a/fuzzer/corpus/8d585e33080801d329007cdd945a1cf95e9dd1ea b/fuzzer/corpus/8d585e33080801d329007cdd945a1cf95e9dd1ea
new file mode 100644
index 0000000..357ae12
--- /dev/null
+++ b/fuzzer/corpus/8d585e33080801d329007cdd945a1cf95e9dd1ea
Binary files differ
diff --git a/fuzzer/corpus/8d9ac5f667371272cd3044f321c02c28a42c25dc b/fuzzer/corpus/8d9ac5f667371272cd3044f321c02c28a42c25dc
new file mode 100644
index 0000000..b69c04e
--- /dev/null
+++ b/fuzzer/corpus/8d9ac5f667371272cd3044f321c02c28a42c25dc
Binary files differ
diff --git a/fuzzer/corpus/8dca3fa748a2eceaad67d32e4ec211fdb68550fc b/fuzzer/corpus/8dca3fa748a2eceaad67d32e4ec211fdb68550fc
new file mode 100644
index 0000000..0169632
--- /dev/null
+++ b/fuzzer/corpus/8dca3fa748a2eceaad67d32e4ec211fdb68550fc
Binary files differ
diff --git a/fuzzer/corpus/8e2d519f3841c8d5220778e40913b1a462c97b12 b/fuzzer/corpus/8e2d519f3841c8d5220778e40913b1a462c97b12
new file mode 100644
index 0000000..cd0e429
--- /dev/null
+++ b/fuzzer/corpus/8e2d519f3841c8d5220778e40913b1a462c97b12
Binary files differ
diff --git a/fuzzer/corpus/8e5362552348074c79a58a7705bc8734ad7fe373 b/fuzzer/corpus/8e5362552348074c79a58a7705bc8734ad7fe373
new file mode 100644
index 0000000..cc91f54
--- /dev/null
+++ b/fuzzer/corpus/8e5362552348074c79a58a7705bc8734ad7fe373
Binary files differ
diff --git a/fuzzer/corpus/8e640d948e1dff48c4f488d42917d957835c7795 b/fuzzer/corpus/8e640d948e1dff48c4f488d42917d957835c7795
new file mode 100644
index 0000000..8d642d0
--- /dev/null
+++ b/fuzzer/corpus/8e640d948e1dff48c4f488d42917d957835c7795
Binary files differ
diff --git a/fuzzer/corpus/8e698937b5ebe1bf7aad256d8340b7ad013f2adb b/fuzzer/corpus/8e698937b5ebe1bf7aad256d8340b7ad013f2adb
new file mode 100644
index 0000000..6c46472
--- /dev/null
+++ b/fuzzer/corpus/8e698937b5ebe1bf7aad256d8340b7ad013f2adb
@@ -0,0 +1 @@
+se0e
\ No newline at end of file
diff --git a/fuzzer/corpus/8e73653222f4bc524d3b5fa96221daad0ac941e9 b/fuzzer/corpus/8e73653222f4bc524d3b5fa96221daad0ac941e9
new file mode 100644
index 0000000..61e7cc4
--- /dev/null
+++ b/fuzzer/corpus/8e73653222f4bc524d3b5fa96221daad0ac941e9
Binary files differ
diff --git a/fuzzer/corpus/8ed44f9d26529e79c5f1ec78381d33f732e8ef17 b/fuzzer/corpus/8ed44f9d26529e79c5f1ec78381d33f732e8ef17
new file mode 100644
index 0000000..dbb0f7c
--- /dev/null
+++ b/fuzzer/corpus/8ed44f9d26529e79c5f1ec78381d33f732e8ef17
Binary files differ
diff --git a/fuzzer/corpus/8edf800c03a8aad4523c3d8de48bf4599a42e6fd b/fuzzer/corpus/8edf800c03a8aad4523c3d8de48bf4599a42e6fd
new file mode 100644
index 0000000..59e1c50
--- /dev/null
+++ b/fuzzer/corpus/8edf800c03a8aad4523c3d8de48bf4599a42e6fd
Binary files differ
diff --git a/fuzzer/corpus/8efa9187d6a0e27a24408e91b68606fa6b459f0e b/fuzzer/corpus/8efa9187d6a0e27a24408e91b68606fa6b459f0e
new file mode 100644
index 0000000..1ca993a
--- /dev/null
+++ b/fuzzer/corpus/8efa9187d6a0e27a24408e91b68606fa6b459f0e
Binary files differ
diff --git a/fuzzer/corpus/8f01b61dcb5c337b995dcf0e5764f34e5de119aa b/fuzzer/corpus/8f01b61dcb5c337b995dcf0e5764f34e5de119aa
new file mode 100644
index 0000000..71a8740
--- /dev/null
+++ b/fuzzer/corpus/8f01b61dcb5c337b995dcf0e5764f34e5de119aa
Binary files differ
diff --git a/fuzzer/corpus/8f1a55d99de3071ae0f6e59100450ec5b692a447 b/fuzzer/corpus/8f1a55d99de3071ae0f6e59100450ec5b692a447
new file mode 100644
index 0000000..069bed5
--- /dev/null
+++ b/fuzzer/corpus/8f1a55d99de3071ae0f6e59100450ec5b692a447
Binary files differ
diff --git a/fuzzer/corpus/8f331152d08cc196dec4a1d056788d4de085eaee b/fuzzer/corpus/8f331152d08cc196dec4a1d056788d4de085eaee
new file mode 100644
index 0000000..93b13f8
--- /dev/null
+++ b/fuzzer/corpus/8f331152d08cc196dec4a1d056788d4de085eaee
Binary files differ
diff --git a/fuzzer/corpus/8f36ff88bf4b338ab4947e4c0239f9eb3575fcf9 b/fuzzer/corpus/8f36ff88bf4b338ab4947e4c0239f9eb3575fcf9
new file mode 100644
index 0000000..61b26eb
--- /dev/null
+++ b/fuzzer/corpus/8f36ff88bf4b338ab4947e4c0239f9eb3575fcf9
Binary files differ
diff --git a/fuzzer/corpus/8f39339cc14bd9193514c410014081bfa344c808 b/fuzzer/corpus/8f39339cc14bd9193514c410014081bfa344c808
new file mode 100644
index 0000000..d011750
--- /dev/null
+++ b/fuzzer/corpus/8f39339cc14bd9193514c410014081bfa344c808
Binary files differ
diff --git a/fuzzer/corpus/8f40d833d26571fd8c25a30163093c71b8ec14e1 b/fuzzer/corpus/8f40d833d26571fd8c25a30163093c71b8ec14e1
new file mode 100644
index 0000000..5969a15
--- /dev/null
+++ b/fuzzer/corpus/8f40d833d26571fd8c25a30163093c71b8ec14e1
Binary files differ
diff --git a/fuzzer/corpus/8f4a7f193fdcb4e8d9304a74317a9fa6921c3ffb b/fuzzer/corpus/8f4a7f193fdcb4e8d9304a74317a9fa6921c3ffb
new file mode 100644
index 0000000..74e1c4d
--- /dev/null
+++ b/fuzzer/corpus/8f4a7f193fdcb4e8d9304a74317a9fa6921c3ffb
Binary files differ
diff --git a/fuzzer/corpus/8f52a3721d402c54d4f3604bc1df28a1796d3f32 b/fuzzer/corpus/8f52a3721d402c54d4f3604bc1df28a1796d3f32
new file mode 100644
index 0000000..fd2401a
--- /dev/null
+++ b/fuzzer/corpus/8f52a3721d402c54d4f3604bc1df28a1796d3f32
Binary files differ
diff --git a/fuzzer/corpus/8f57c6744d49926eb8d6c0a36b80991c50996344 b/fuzzer/corpus/8f57c6744d49926eb8d6c0a36b80991c50996344
new file mode 100644
index 0000000..3e6488d
--- /dev/null
+++ b/fuzzer/corpus/8f57c6744d49926eb8d6c0a36b80991c50996344
Binary files differ
diff --git a/fuzzer/corpus/8f8748ad3794c703d767666b91847b9747eb38c4 b/fuzzer/corpus/8f8748ad3794c703d767666b91847b9747eb38c4
new file mode 100644
index 0000000..727636f
--- /dev/null
+++ b/fuzzer/corpus/8f8748ad3794c703d767666b91847b9747eb38c4
Binary files differ
diff --git a/fuzzer/corpus/8fbc8b089aa011ffef0a708cdc7b1d9b968e7ac4 b/fuzzer/corpus/8fbc8b089aa011ffef0a708cdc7b1d9b968e7ac4
new file mode 100644
index 0000000..39f31f3
--- /dev/null
+++ b/fuzzer/corpus/8fbc8b089aa011ffef0a708cdc7b1d9b968e7ac4
Binary files differ
diff --git a/fuzzer/corpus/8fc1fc6eb61142f1f8db3972b8355b8d2351af17 b/fuzzer/corpus/8fc1fc6eb61142f1f8db3972b8355b8d2351af17
new file mode 100644
index 0000000..9de8061
--- /dev/null
+++ b/fuzzer/corpus/8fc1fc6eb61142f1f8db3972b8355b8d2351af17
Binary files differ
diff --git a/fuzzer/corpus/902e9545496f4bd52675923b09256bdb3d285e40 b/fuzzer/corpus/902e9545496f4bd52675923b09256bdb3d285e40
new file mode 100644
index 0000000..50e15e1
--- /dev/null
+++ b/fuzzer/corpus/902e9545496f4bd52675923b09256bdb3d285e40
Binary files differ
diff --git a/fuzzer/corpus/904219e4f56c8e679d64389a9f16a87f876cb9cc b/fuzzer/corpus/904219e4f56c8e679d64389a9f16a87f876cb9cc
new file mode 100644
index 0000000..1ed711d
--- /dev/null
+++ b/fuzzer/corpus/904219e4f56c8e679d64389a9f16a87f876cb9cc
Binary files differ
diff --git a/fuzzer/corpus/907c814ebe5a217c57b1532198428d001cff0bf8 b/fuzzer/corpus/907c814ebe5a217c57b1532198428d001cff0bf8
new file mode 100644
index 0000000..28ad1c5
--- /dev/null
+++ b/fuzzer/corpus/907c814ebe5a217c57b1532198428d001cff0bf8
Binary files differ
diff --git a/fuzzer/corpus/90839e2f2bc032d0e688d04d06e00da1e5b6769b b/fuzzer/corpus/90839e2f2bc032d0e688d04d06e00da1e5b6769b
new file mode 100644
index 0000000..0a8f4d6
--- /dev/null
+++ b/fuzzer/corpus/90839e2f2bc032d0e688d04d06e00da1e5b6769b
Binary files differ
diff --git a/fuzzer/corpus/909df934174cd3496294e668eca5b1ba6dd22e60 b/fuzzer/corpus/909df934174cd3496294e668eca5b1ba6dd22e60
new file mode 100644
index 0000000..d55dc3b
--- /dev/null
+++ b/fuzzer/corpus/909df934174cd3496294e668eca5b1ba6dd22e60
Binary files differ
diff --git a/fuzzer/corpus/90bb6fc426b1324848a639c7bb414e5d14356550 b/fuzzer/corpus/90bb6fc426b1324848a639c7bb414e5d14356550
new file mode 100644
index 0000000..e59cd24
--- /dev/null
+++ b/fuzzer/corpus/90bb6fc426b1324848a639c7bb414e5d14356550
Binary files differ
diff --git a/fuzzer/corpus/90c7cb30b59b02b23cff45739cbc964fdff4b3f9 b/fuzzer/corpus/90c7cb30b59b02b23cff45739cbc964fdff4b3f9
new file mode 100644
index 0000000..4a79c35
--- /dev/null
+++ b/fuzzer/corpus/90c7cb30b59b02b23cff45739cbc964fdff4b3f9
Binary files differ
diff --git a/fuzzer/corpus/90d4c2d95d25aa1e67ab78f1553148de43f42ceb b/fuzzer/corpus/90d4c2d95d25aa1e67ab78f1553148de43f42ceb
new file mode 100644
index 0000000..e43e4ef
--- /dev/null
+++ b/fuzzer/corpus/90d4c2d95d25aa1e67ab78f1553148de43f42ceb
Binary files differ
diff --git a/fuzzer/corpus/90dfac881acb62787fd9479f8c2c90aca0979866 b/fuzzer/corpus/90dfac881acb62787fd9479f8c2c90aca0979866
new file mode 100644
index 0000000..d1321e8
--- /dev/null
+++ b/fuzzer/corpus/90dfac881acb62787fd9479f8c2c90aca0979866
Binary files differ
diff --git a/fuzzer/corpus/90f2d8c6a973a3044bb3d9f7b2b505fe8b735467 b/fuzzer/corpus/90f2d8c6a973a3044bb3d9f7b2b505fe8b735467
new file mode 100644
index 0000000..7aad456
--- /dev/null
+++ b/fuzzer/corpus/90f2d8c6a973a3044bb3d9f7b2b505fe8b735467
Binary files differ
diff --git a/fuzzer/corpus/90fd5c59f63f6404bdeec3571a7c22dd471f2a76 b/fuzzer/corpus/90fd5c59f63f6404bdeec3571a7c22dd471f2a76
new file mode 100644
index 0000000..0432ef6
--- /dev/null
+++ b/fuzzer/corpus/90fd5c59f63f6404bdeec3571a7c22dd471f2a76
Binary files differ
diff --git a/fuzzer/corpus/90ffd04a9547fd44b574e2346764605436b494dd b/fuzzer/corpus/90ffd04a9547fd44b574e2346764605436b494dd
new file mode 100644
index 0000000..ae5b3d2
--- /dev/null
+++ b/fuzzer/corpus/90ffd04a9547fd44b574e2346764605436b494dd
Binary files differ
diff --git a/fuzzer/corpus/910bb3ca72a76508a0a036830f0b0678d1ce8cf6 b/fuzzer/corpus/910bb3ca72a76508a0a036830f0b0678d1ce8cf6
new file mode 100644
index 0000000..e9b7412
--- /dev/null
+++ b/fuzzer/corpus/910bb3ca72a76508a0a036830f0b0678d1ce8cf6
Binary files differ
diff --git a/fuzzer/corpus/9113dc61fd586fcacaae9ed3cf37ea084ece8990 b/fuzzer/corpus/9113dc61fd586fcacaae9ed3cf37ea084ece8990
new file mode 100644
index 0000000..6fe6e28
--- /dev/null
+++ b/fuzzer/corpus/9113dc61fd586fcacaae9ed3cf37ea084ece8990
Binary files differ
diff --git a/fuzzer/corpus/9114620e87fa084243157b4f03684e2abb72ea0b b/fuzzer/corpus/9114620e87fa084243157b4f03684e2abb72ea0b
new file mode 100644
index 0000000..ddaaca8
--- /dev/null
+++ b/fuzzer/corpus/9114620e87fa084243157b4f03684e2abb72ea0b
Binary files differ
diff --git a/fuzzer/corpus/91267d27e463ef628be63cad43b38a6243eebe90 b/fuzzer/corpus/91267d27e463ef628be63cad43b38a6243eebe90
new file mode 100644
index 0000000..e06895a
--- /dev/null
+++ b/fuzzer/corpus/91267d27e463ef628be63cad43b38a6243eebe90
Binary files differ
diff --git a/fuzzer/corpus/913d43ae64592c8b4c55bccbfcaf1e34d9b6c78c b/fuzzer/corpus/913d43ae64592c8b4c55bccbfcaf1e34d9b6c78c
new file mode 100644
index 0000000..a08da3b
--- /dev/null
+++ b/fuzzer/corpus/913d43ae64592c8b4c55bccbfcaf1e34d9b6c78c
Binary files differ
diff --git a/fuzzer/corpus/9148b45122d0ecadf51458de33998ff27ce96e55 b/fuzzer/corpus/9148b45122d0ecadf51458de33998ff27ce96e55
new file mode 100644
index 0000000..19b5817
--- /dev/null
+++ b/fuzzer/corpus/9148b45122d0ecadf51458de33998ff27ce96e55
Binary files differ
diff --git a/fuzzer/corpus/914ff5d72f2c35c5dd5246f56ceb26f135043ca7 b/fuzzer/corpus/914ff5d72f2c35c5dd5246f56ceb26f135043ca7
new file mode 100644
index 0000000..e122ce4
--- /dev/null
+++ b/fuzzer/corpus/914ff5d72f2c35c5dd5246f56ceb26f135043ca7
Binary files differ
diff --git a/fuzzer/corpus/9166dd5c71910bc2a5c88c6b610c822518f47b49 b/fuzzer/corpus/9166dd5c71910bc2a5c88c6b610c822518f47b49
new file mode 100644
index 0000000..b204f66
--- /dev/null
+++ b/fuzzer/corpus/9166dd5c71910bc2a5c88c6b610c822518f47b49
Binary files differ
diff --git a/fuzzer/corpus/91923f189c6813b46baa52a30f72bea9dab4cec3 b/fuzzer/corpus/91923f189c6813b46baa52a30f72bea9dab4cec3
new file mode 100644
index 0000000..e287d7a
--- /dev/null
+++ b/fuzzer/corpus/91923f189c6813b46baa52a30f72bea9dab4cec3
Binary files differ
diff --git a/fuzzer/corpus/91a8e37b3a1f44bda6ac409980e6a2d4a9156a11 b/fuzzer/corpus/91a8e37b3a1f44bda6ac409980e6a2d4a9156a11
new file mode 100644
index 0000000..c439356
--- /dev/null
+++ b/fuzzer/corpus/91a8e37b3a1f44bda6ac409980e6a2d4a9156a11
Binary files differ
diff --git a/fuzzer/corpus/91f7985c3e6d3d8a17580a9d293d643e52d5c534 b/fuzzer/corpus/91f7985c3e6d3d8a17580a9d293d643e52d5c534
new file mode 100644
index 0000000..0900669
--- /dev/null
+++ b/fuzzer/corpus/91f7985c3e6d3d8a17580a9d293d643e52d5c534
Binary files differ
diff --git a/fuzzer/corpus/92148259f949540128b36486bcb9e6d3ab8ec124 b/fuzzer/corpus/92148259f949540128b36486bcb9e6d3ab8ec124
new file mode 100644
index 0000000..3d553a4
--- /dev/null
+++ b/fuzzer/corpus/92148259f949540128b36486bcb9e6d3ab8ec124
Binary files differ
diff --git a/fuzzer/corpus/923ceaee40c82c9fa5491ba85b4972b8582a2c69 b/fuzzer/corpus/923ceaee40c82c9fa5491ba85b4972b8582a2c69
new file mode 100644
index 0000000..45fffa2
--- /dev/null
+++ b/fuzzer/corpus/923ceaee40c82c9fa5491ba85b4972b8582a2c69
Binary files differ
diff --git a/fuzzer/corpus/927caaad37be4c7c3ff69eaf3fccea4a0a2c3c6e b/fuzzer/corpus/927caaad37be4c7c3ff69eaf3fccea4a0a2c3c6e
new file mode 100644
index 0000000..131411f
--- /dev/null
+++ b/fuzzer/corpus/927caaad37be4c7c3ff69eaf3fccea4a0a2c3c6e
Binary files differ
diff --git a/fuzzer/corpus/928aed4be9c6335cfdec4e04a3644d36b162e59f b/fuzzer/corpus/928aed4be9c6335cfdec4e04a3644d36b162e59f
new file mode 100644
index 0000000..b45e9a6
--- /dev/null
+++ b/fuzzer/corpus/928aed4be9c6335cfdec4e04a3644d36b162e59f
Binary files differ
diff --git a/fuzzer/corpus/928e5ea8a82bd17015cb1b2b828dccbae05ed81c b/fuzzer/corpus/928e5ea8a82bd17015cb1b2b828dccbae05ed81c
new file mode 100644
index 0000000..47a71a8
--- /dev/null
+++ b/fuzzer/corpus/928e5ea8a82bd17015cb1b2b828dccbae05ed81c
Binary files differ
diff --git a/fuzzer/corpus/92d49fa60a0535d9a2993d81e71bcd893b96744d b/fuzzer/corpus/92d49fa60a0535d9a2993d81e71bcd893b96744d
new file mode 100644
index 0000000..899c730
--- /dev/null
+++ b/fuzzer/corpus/92d49fa60a0535d9a2993d81e71bcd893b96744d
Binary files differ
diff --git a/fuzzer/corpus/92e4b808ccd7718fa4494efe2803822b377596ea b/fuzzer/corpus/92e4b808ccd7718fa4494efe2803822b377596ea
new file mode 100644
index 0000000..1a19ca0
--- /dev/null
+++ b/fuzzer/corpus/92e4b808ccd7718fa4494efe2803822b377596ea
Binary files differ
diff --git a/fuzzer/corpus/92e6fca9bb5223fecf157bc2fda2a3b02181b3e7 b/fuzzer/corpus/92e6fca9bb5223fecf157bc2fda2a3b02181b3e7
new file mode 100644
index 0000000..f6fe2b3
--- /dev/null
+++ b/fuzzer/corpus/92e6fca9bb5223fecf157bc2fda2a3b02181b3e7
Binary files differ
diff --git a/fuzzer/corpus/932359778a7ddaf719fc878a4e23093e142948c6 b/fuzzer/corpus/932359778a7ddaf719fc878a4e23093e142948c6
new file mode 100644
index 0000000..1399b2c
--- /dev/null
+++ b/fuzzer/corpus/932359778a7ddaf719fc878a4e23093e142948c6
Binary files differ
diff --git a/fuzzer/corpus/933b97f21c81d68e32857ca64df28cd97a04077a b/fuzzer/corpus/933b97f21c81d68e32857ca64df28cd97a04077a
new file mode 100644
index 0000000..0501ff6
--- /dev/null
+++ b/fuzzer/corpus/933b97f21c81d68e32857ca64df28cd97a04077a
Binary files differ
diff --git a/fuzzer/corpus/93608c9cd306ea0818dedb1e1fd86a39952123ac b/fuzzer/corpus/93608c9cd306ea0818dedb1e1fd86a39952123ac
new file mode 100644
index 0000000..0d161e4
--- /dev/null
+++ b/fuzzer/corpus/93608c9cd306ea0818dedb1e1fd86a39952123ac
Binary files differ
diff --git a/fuzzer/corpus/938900bbaf4a1a1eec75d16ec3e4bc45256de6cf b/fuzzer/corpus/938900bbaf4a1a1eec75d16ec3e4bc45256de6cf
new file mode 100644
index 0000000..433ebc6
--- /dev/null
+++ b/fuzzer/corpus/938900bbaf4a1a1eec75d16ec3e4bc45256de6cf
Binary files differ
diff --git a/fuzzer/corpus/93d56d539af6ac5a69e695ad565ea6d02da157cd b/fuzzer/corpus/93d56d539af6ac5a69e695ad565ea6d02da157cd
new file mode 100644
index 0000000..9d42c3a
--- /dev/null
+++ b/fuzzer/corpus/93d56d539af6ac5a69e695ad565ea6d02da157cd
Binary files differ
diff --git a/fuzzer/corpus/93fa04a15a203225ace622afffd955ef2c50d46c b/fuzzer/corpus/93fa04a15a203225ace622afffd955ef2c50d46c
new file mode 100644
index 0000000..7d2e7fb
--- /dev/null
+++ b/fuzzer/corpus/93fa04a15a203225ace622afffd955ef2c50d46c
Binary files differ
diff --git a/fuzzer/corpus/94296913d11ce753fe6ed95171410cf5f8d01c36 b/fuzzer/corpus/94296913d11ce753fe6ed95171410cf5f8d01c36
new file mode 100644
index 0000000..4e83114
--- /dev/null
+++ b/fuzzer/corpus/94296913d11ce753fe6ed95171410cf5f8d01c36
Binary files differ
diff --git a/fuzzer/corpus/94368c9131dd1ed8dd79e8ff7ca98aa40b30d7db b/fuzzer/corpus/94368c9131dd1ed8dd79e8ff7ca98aa40b30d7db
new file mode 100644
index 0000000..4e3a917
--- /dev/null
+++ b/fuzzer/corpus/94368c9131dd1ed8dd79e8ff7ca98aa40b30d7db
Binary files differ
diff --git a/fuzzer/corpus/943e790a9ef18ecae5661080ded421c3da4e967a b/fuzzer/corpus/943e790a9ef18ecae5661080ded421c3da4e967a
new file mode 100644
index 0000000..ccd814c
--- /dev/null
+++ b/fuzzer/corpus/943e790a9ef18ecae5661080ded421c3da4e967a
Binary files differ
diff --git a/fuzzer/corpus/945b9a12a1b293ecd3af0b4bc4ad11a81183d2e7 b/fuzzer/corpus/945b9a12a1b293ecd3af0b4bc4ad11a81183d2e7
new file mode 100644
index 0000000..3c7635b
--- /dev/null
+++ b/fuzzer/corpus/945b9a12a1b293ecd3af0b4bc4ad11a81183d2e7
Binary files differ
diff --git a/fuzzer/corpus/9468850301ce9170aa86986ba4f10461b711349e b/fuzzer/corpus/9468850301ce9170aa86986ba4f10461b711349e
new file mode 100644
index 0000000..a008da9
--- /dev/null
+++ b/fuzzer/corpus/9468850301ce9170aa86986ba4f10461b711349e
Binary files differ
diff --git a/fuzzer/corpus/94b34427be5d7c62ee764559406a0c561184b660 b/fuzzer/corpus/94b34427be5d7c62ee764559406a0c561184b660
new file mode 100644
index 0000000..639be1e
--- /dev/null
+++ b/fuzzer/corpus/94b34427be5d7c62ee764559406a0c561184b660
Binary files differ
diff --git a/fuzzer/corpus/94c526d076b812e768ba933ef1e373c4ec0912d7 b/fuzzer/corpus/94c526d076b812e768ba933ef1e373c4ec0912d7
new file mode 100644
index 0000000..eecc597
--- /dev/null
+++ b/fuzzer/corpus/94c526d076b812e768ba933ef1e373c4ec0912d7
Binary files differ
diff --git a/fuzzer/corpus/94d124dbb6c5c418fd5edd09927de3fd3952c448 b/fuzzer/corpus/94d124dbb6c5c418fd5edd09927de3fd3952c448
new file mode 100644
index 0000000..7906581
--- /dev/null
+++ b/fuzzer/corpus/94d124dbb6c5c418fd5edd09927de3fd3952c448
Binary files differ
diff --git a/fuzzer/corpus/94e3f46d03542cb08030511441a7b0e1502c9336 b/fuzzer/corpus/94e3f46d03542cb08030511441a7b0e1502c9336
new file mode 100644
index 0000000..021e4a2
--- /dev/null
+++ b/fuzzer/corpus/94e3f46d03542cb08030511441a7b0e1502c9336
Binary files differ
diff --git a/fuzzer/corpus/94ff9bd5bb4dfb4d074c115e0201367247e6f40f b/fuzzer/corpus/94ff9bd5bb4dfb4d074c115e0201367247e6f40f
new file mode 100644
index 0000000..07a4be9
--- /dev/null
+++ b/fuzzer/corpus/94ff9bd5bb4dfb4d074c115e0201367247e6f40f
Binary files differ
diff --git a/fuzzer/corpus/952418b86b69c6c5955480dbf4932965c0edaf21 b/fuzzer/corpus/952418b86b69c6c5955480dbf4932965c0edaf21
new file mode 100644
index 0000000..53d6c81
--- /dev/null
+++ b/fuzzer/corpus/952418b86b69c6c5955480dbf4932965c0edaf21
Binary files differ
diff --git a/fuzzer/corpus/954da74a4362ac8b00ea38a1cbb5d0c84e92e64a b/fuzzer/corpus/954da74a4362ac8b00ea38a1cbb5d0c84e92e64a
new file mode 100644
index 0000000..77f4a17
--- /dev/null
+++ b/fuzzer/corpus/954da74a4362ac8b00ea38a1cbb5d0c84e92e64a
Binary files differ
diff --git a/fuzzer/corpus/958931c0af4fde12af91b2b4b2cf33dd3ea37061 b/fuzzer/corpus/958931c0af4fde12af91b2b4b2cf33dd3ea37061
new file mode 100644
index 0000000..8916362
--- /dev/null
+++ b/fuzzer/corpus/958931c0af4fde12af91b2b4b2cf33dd3ea37061
Binary files differ
diff --git a/fuzzer/corpus/95a1f4c7cc112c88aac967b6feba84d9d8ce8013 b/fuzzer/corpus/95a1f4c7cc112c88aac967b6feba84d9d8ce8013
new file mode 100644
index 0000000..87b70b4
--- /dev/null
+++ b/fuzzer/corpus/95a1f4c7cc112c88aac967b6feba84d9d8ce8013
Binary files differ
diff --git a/fuzzer/corpus/95cba40a6ad0d1f046081552fb1ba7561580de24 b/fuzzer/corpus/95cba40a6ad0d1f046081552fb1ba7561580de24
new file mode 100644
index 0000000..83857f5
--- /dev/null
+++ b/fuzzer/corpus/95cba40a6ad0d1f046081552fb1ba7561580de24
Binary files differ
diff --git a/fuzzer/corpus/95eca34f27a6a51ef5ddbd45e2181c4646033e35 b/fuzzer/corpus/95eca34f27a6a51ef5ddbd45e2181c4646033e35
new file mode 100644
index 0000000..5919c8f
--- /dev/null
+++ b/fuzzer/corpus/95eca34f27a6a51ef5ddbd45e2181c4646033e35
Binary files differ
diff --git a/fuzzer/corpus/9650a9885e2b5ff63e106e33d261979961ddbdce b/fuzzer/corpus/9650a9885e2b5ff63e106e33d261979961ddbdce
new file mode 100644
index 0000000..94ca91f
--- /dev/null
+++ b/fuzzer/corpus/9650a9885e2b5ff63e106e33d261979961ddbdce
Binary files differ
diff --git a/fuzzer/corpus/9650fd22b68938e9c792ce6db89ec95724183c1f b/fuzzer/corpus/9650fd22b68938e9c792ce6db89ec95724183c1f
new file mode 100644
index 0000000..fc8823f
--- /dev/null
+++ b/fuzzer/corpus/9650fd22b68938e9c792ce6db89ec95724183c1f
Binary files differ
diff --git a/fuzzer/corpus/96530dca593097b70c65d339e3eec7de1579307c b/fuzzer/corpus/96530dca593097b70c65d339e3eec7de1579307c
new file mode 100644
index 0000000..756cc91
--- /dev/null
+++ b/fuzzer/corpus/96530dca593097b70c65d339e3eec7de1579307c
Binary files differ
diff --git a/fuzzer/corpus/9660c0988d5dd571f139b60462e2c3b6b8a99201 b/fuzzer/corpus/9660c0988d5dd571f139b60462e2c3b6b8a99201
new file mode 100644
index 0000000..8d001c3
--- /dev/null
+++ b/fuzzer/corpus/9660c0988d5dd571f139b60462e2c3b6b8a99201
Binary files differ
diff --git a/fuzzer/corpus/967e23f677b127242edf6e398318c7b0be5d2e1c b/fuzzer/corpus/967e23f677b127242edf6e398318c7b0be5d2e1c
new file mode 100644
index 0000000..73b28e1
--- /dev/null
+++ b/fuzzer/corpus/967e23f677b127242edf6e398318c7b0be5d2e1c
Binary files differ
diff --git a/fuzzer/corpus/96918754c1d8476b006388739968dce90720c2c7 b/fuzzer/corpus/96918754c1d8476b006388739968dce90720c2c7
new file mode 100644
index 0000000..1c62051
--- /dev/null
+++ b/fuzzer/corpus/96918754c1d8476b006388739968dce90720c2c7
Binary files differ
diff --git a/fuzzer/corpus/96b406c9132c08286fba4002d7d26142171f44cb b/fuzzer/corpus/96b406c9132c08286fba4002d7d26142171f44cb
new file mode 100644
index 0000000..ed6dc21
--- /dev/null
+++ b/fuzzer/corpus/96b406c9132c08286fba4002d7d26142171f44cb
Binary files differ
diff --git a/fuzzer/corpus/96d5767c72ec78d6fa16c097d95559b0b449e135 b/fuzzer/corpus/96d5767c72ec78d6fa16c097d95559b0b449e135
new file mode 100644
index 0000000..c13a115
--- /dev/null
+++ b/fuzzer/corpus/96d5767c72ec78d6fa16c097d95559b0b449e135
Binary files differ
diff --git a/fuzzer/corpus/96dac3f664df069f373a5f02afeed805f8d00918 b/fuzzer/corpus/96dac3f664df069f373a5f02afeed805f8d00918
new file mode 100644
index 0000000..c012050
--- /dev/null
+++ b/fuzzer/corpus/96dac3f664df069f373a5f02afeed805f8d00918
Binary files differ
diff --git a/fuzzer/corpus/96e16ca69c68c6812c34b3f7d87381b4f5589361 b/fuzzer/corpus/96e16ca69c68c6812c34b3f7d87381b4f5589361
new file mode 100644
index 0000000..e7862af
--- /dev/null
+++ b/fuzzer/corpus/96e16ca69c68c6812c34b3f7d87381b4f5589361
Binary files differ
diff --git a/fuzzer/corpus/9701eac27e38b4d198e26228113ffdc76fdea589 b/fuzzer/corpus/9701eac27e38b4d198e26228113ffdc76fdea589
new file mode 100644
index 0000000..33f8c2b
--- /dev/null
+++ b/fuzzer/corpus/9701eac27e38b4d198e26228113ffdc76fdea589
Binary files differ
diff --git a/fuzzer/corpus/971b1560ab92e7840aff0034b89833ce4e62d8ca b/fuzzer/corpus/971b1560ab92e7840aff0034b89833ce4e62d8ca
new file mode 100644
index 0000000..1c2ac06
--- /dev/null
+++ b/fuzzer/corpus/971b1560ab92e7840aff0034b89833ce4e62d8ca
Binary files differ
diff --git a/fuzzer/corpus/971ec195d5011a172ec57c10863ecec6d036628f b/fuzzer/corpus/971ec195d5011a172ec57c10863ecec6d036628f
new file mode 100644
index 0000000..543715c
--- /dev/null
+++ b/fuzzer/corpus/971ec195d5011a172ec57c10863ecec6d036628f
@@ -0,0 +1 @@
+s_{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{0i
\ No newline at end of file
diff --git a/fuzzer/corpus/97218a0b259b20d3e0777ec5193146c0f20c150e b/fuzzer/corpus/97218a0b259b20d3e0777ec5193146c0f20c150e
new file mode 100644
index 0000000..ccbdcf9
--- /dev/null
+++ b/fuzzer/corpus/97218a0b259b20d3e0777ec5193146c0f20c150e
Binary files differ
diff --git a/fuzzer/corpus/972bfb71e17aab591a53713624b9d38513800f2e b/fuzzer/corpus/972bfb71e17aab591a53713624b9d38513800f2e
new file mode 100644
index 0000000..99ac2c3
--- /dev/null
+++ b/fuzzer/corpus/972bfb71e17aab591a53713624b9d38513800f2e
Binary files differ
diff --git a/fuzzer/corpus/97641203c7593c4baffb35a61f7054a9b0049a4f b/fuzzer/corpus/97641203c7593c4baffb35a61f7054a9b0049a4f
new file mode 100644
index 0000000..fb7087e
--- /dev/null
+++ b/fuzzer/corpus/97641203c7593c4baffb35a61f7054a9b0049a4f
Binary files differ
diff --git a/fuzzer/corpus/977ee7319f66d5d4da2d9a37845a9d366fd752be b/fuzzer/corpus/977ee7319f66d5d4da2d9a37845a9d366fd752be
new file mode 100644
index 0000000..079a1d2
--- /dev/null
+++ b/fuzzer/corpus/977ee7319f66d5d4da2d9a37845a9d366fd752be
Binary files differ
diff --git a/fuzzer/corpus/977fd46f27620198fe8eeb07ae07d6fb805e3129 b/fuzzer/corpus/977fd46f27620198fe8eeb07ae07d6fb805e3129
new file mode 100644
index 0000000..33ced0a
--- /dev/null
+++ b/fuzzer/corpus/977fd46f27620198fe8eeb07ae07d6fb805e3129
Binary files differ
diff --git a/fuzzer/corpus/977ff6e02707adeff86521e71edb8ff32a76e30d b/fuzzer/corpus/977ff6e02707adeff86521e71edb8ff32a76e30d
new file mode 100644
index 0000000..0838030
--- /dev/null
+++ b/fuzzer/corpus/977ff6e02707adeff86521e71edb8ff32a76e30d
Binary files differ
diff --git a/fuzzer/corpus/97fb5b3c5b5867374bf6f4200aaf675b1f053e54 b/fuzzer/corpus/97fb5b3c5b5867374bf6f4200aaf675b1f053e54
new file mode 100644
index 0000000..96b8d6b
--- /dev/null
+++ b/fuzzer/corpus/97fb5b3c5b5867374bf6f4200aaf675b1f053e54
Binary files differ
diff --git a/fuzzer/corpus/980b39be6d42e294ab54a02cd96b8325ffc4f982 b/fuzzer/corpus/980b39be6d42e294ab54a02cd96b8325ffc4f982
new file mode 100644
index 0000000..5d79b23
--- /dev/null
+++ b/fuzzer/corpus/980b39be6d42e294ab54a02cd96b8325ffc4f982
Binary files differ
diff --git a/fuzzer/corpus/981057bbd4eeb0d24e7562feaf61e625c6dc88bd b/fuzzer/corpus/981057bbd4eeb0d24e7562feaf61e625c6dc88bd
new file mode 100644
index 0000000..06dde98
--- /dev/null
+++ b/fuzzer/corpus/981057bbd4eeb0d24e7562feaf61e625c6dc88bd
Binary files differ
diff --git a/fuzzer/corpus/981a6a5600069bdf40665c67bdec186b2df55a83 b/fuzzer/corpus/981a6a5600069bdf40665c67bdec186b2df55a83
new file mode 100644
index 0000000..95d1e28
--- /dev/null
+++ b/fuzzer/corpus/981a6a5600069bdf40665c67bdec186b2df55a83
Binary files differ
diff --git a/fuzzer/corpus/982f865b15e081a25649c841cb03e95a1e49b09b b/fuzzer/corpus/982f865b15e081a25649c841cb03e95a1e49b09b
new file mode 100644
index 0000000..9dd0a4e
--- /dev/null
+++ b/fuzzer/corpus/982f865b15e081a25649c841cb03e95a1e49b09b
Binary files differ
diff --git a/fuzzer/corpus/985593bc6f792360ce8b8a4b5a16346ec29c6a38 b/fuzzer/corpus/985593bc6f792360ce8b8a4b5a16346ec29c6a38
new file mode 100644
index 0000000..9e00d18
--- /dev/null
+++ b/fuzzer/corpus/985593bc6f792360ce8b8a4b5a16346ec29c6a38
Binary files differ
diff --git a/fuzzer/corpus/985cfb783ed2c8a6a3e385d2669d7bab4201e2b4 b/fuzzer/corpus/985cfb783ed2c8a6a3e385d2669d7bab4201e2b4
new file mode 100644
index 0000000..3d941c0
--- /dev/null
+++ b/fuzzer/corpus/985cfb783ed2c8a6a3e385d2669d7bab4201e2b4
Binary files differ
diff --git a/fuzzer/corpus/98693d04569d34ebca27f95425a38bbe1088eca7 b/fuzzer/corpus/98693d04569d34ebca27f95425a38bbe1088eca7
new file mode 100644
index 0000000..5f5272e
--- /dev/null
+++ b/fuzzer/corpus/98693d04569d34ebca27f95425a38bbe1088eca7
Binary files differ
diff --git a/fuzzer/corpus/986fc5a28a4867a4dcb6bd2911228e087f53b391 b/fuzzer/corpus/986fc5a28a4867a4dcb6bd2911228e087f53b391
new file mode 100644
index 0000000..c23c2c0
--- /dev/null
+++ b/fuzzer/corpus/986fc5a28a4867a4dcb6bd2911228e087f53b391
Binary files differ
diff --git a/fuzzer/corpus/9872c895dbfff515d9dcc12a6815f0b7a57f9bd9 b/fuzzer/corpus/9872c895dbfff515d9dcc12a6815f0b7a57f9bd9
new file mode 100644
index 0000000..15b77d6
--- /dev/null
+++ b/fuzzer/corpus/9872c895dbfff515d9dcc12a6815f0b7a57f9bd9
Binary files differ
diff --git a/fuzzer/corpus/98b5ce00c98db04f0c25ba401ce1c3473665c3d1 b/fuzzer/corpus/98b5ce00c98db04f0c25ba401ce1c3473665c3d1
new file mode 100644
index 0000000..ec0da0a
--- /dev/null
+++ b/fuzzer/corpus/98b5ce00c98db04f0c25ba401ce1c3473665c3d1
Binary files differ
diff --git a/fuzzer/corpus/98f8bf5a578768c9687ac66ced2222ce989c575a b/fuzzer/corpus/98f8bf5a578768c9687ac66ced2222ce989c575a
new file mode 100644
index 0000000..5ebb392
--- /dev/null
+++ b/fuzzer/corpus/98f8bf5a578768c9687ac66ced2222ce989c575a
Binary files differ
diff --git a/fuzzer/corpus/9913741d1fc0599e9bc040e743b49d0910962b0e b/fuzzer/corpus/9913741d1fc0599e9bc040e743b49d0910962b0e
new file mode 100644
index 0000000..a8c9b64
--- /dev/null
+++ b/fuzzer/corpus/9913741d1fc0599e9bc040e743b49d0910962b0e
Binary files differ
diff --git a/fuzzer/corpus/99528249973de765e4650895580d15355443e67f b/fuzzer/corpus/99528249973de765e4650895580d15355443e67f
new file mode 100644
index 0000000..07b02ae
--- /dev/null
+++ b/fuzzer/corpus/99528249973de765e4650895580d15355443e67f
Binary files differ
diff --git a/fuzzer/corpus/996f90eef9fbe51b578675b3907b3793d0ca64f6 b/fuzzer/corpus/996f90eef9fbe51b578675b3907b3793d0ca64f6
new file mode 100644
index 0000000..91078ae
--- /dev/null
+++ b/fuzzer/corpus/996f90eef9fbe51b578675b3907b3793d0ca64f6
Binary files differ
diff --git a/fuzzer/corpus/998b724972d21f411214771394c08a09a8e7bb79 b/fuzzer/corpus/998b724972d21f411214771394c08a09a8e7bb79
new file mode 100644
index 0000000..772ebd1
--- /dev/null
+++ b/fuzzer/corpus/998b724972d21f411214771394c08a09a8e7bb79
Binary files differ
diff --git a/fuzzer/corpus/99ad7dcb5a371cf8285e48d7cdf6749027fea3d4 b/fuzzer/corpus/99ad7dcb5a371cf8285e48d7cdf6749027fea3d4
new file mode 100644
index 0000000..42ded28
--- /dev/null
+++ b/fuzzer/corpus/99ad7dcb5a371cf8285e48d7cdf6749027fea3d4
Binary files differ
diff --git a/fuzzer/corpus/99c020478bb68808a6c4d3757bfdddbefafd20ae b/fuzzer/corpus/99c020478bb68808a6c4d3757bfdddbefafd20ae
new file mode 100644
index 0000000..94cfbb4
--- /dev/null
+++ b/fuzzer/corpus/99c020478bb68808a6c4d3757bfdddbefafd20ae
Binary files differ
diff --git a/fuzzer/corpus/99f3870ed7b619a95946157e6ff86c3d466e3935 b/fuzzer/corpus/99f3870ed7b619a95946157e6ff86c3d466e3935
new file mode 100644
index 0000000..b7a3d2d
--- /dev/null
+++ b/fuzzer/corpus/99f3870ed7b619a95946157e6ff86c3d466e3935
Binary files differ
diff --git a/fuzzer/corpus/99f6ef0fa50cfb4f1642f758c52820a68c964496 b/fuzzer/corpus/99f6ef0fa50cfb4f1642f758c52820a68c964496
new file mode 100644
index 0000000..6b27c40
--- /dev/null
+++ b/fuzzer/corpus/99f6ef0fa50cfb4f1642f758c52820a68c964496
Binary files differ
diff --git a/fuzzer/corpus/9a6ed1be0606889e3124faf77f9f26821a308056 b/fuzzer/corpus/9a6ed1be0606889e3124faf77f9f26821a308056
new file mode 100644
index 0000000..1a57b7b
--- /dev/null
+++ b/fuzzer/corpus/9a6ed1be0606889e3124faf77f9f26821a308056
Binary files differ
diff --git a/fuzzer/corpus/9a93158cd5cdaf8d19cbf54ef8fb451a53967339 b/fuzzer/corpus/9a93158cd5cdaf8d19cbf54ef8fb451a53967339
new file mode 100644
index 0000000..0fa4625
--- /dev/null
+++ b/fuzzer/corpus/9a93158cd5cdaf8d19cbf54ef8fb451a53967339
Binary files differ
diff --git a/fuzzer/corpus/9aaacdd034a4b6720322545ce68672a4ca32061c b/fuzzer/corpus/9aaacdd034a4b6720322545ce68672a4ca32061c
new file mode 100644
index 0000000..77eb951
--- /dev/null
+++ b/fuzzer/corpus/9aaacdd034a4b6720322545ce68672a4ca32061c
Binary files differ
diff --git a/fuzzer/corpus/9aad5607940370f7224c7aac753a22495984a9d6 b/fuzzer/corpus/9aad5607940370f7224c7aac753a22495984a9d6
new file mode 100644
index 0000000..bcab60e
--- /dev/null
+++ b/fuzzer/corpus/9aad5607940370f7224c7aac753a22495984a9d6
Binary files differ
diff --git a/fuzzer/corpus/9abbd6f61f12dac2f0daaca291a329b8a2991d82 b/fuzzer/corpus/9abbd6f61f12dac2f0daaca291a329b8a2991d82
new file mode 100644
index 0000000..356c9fb
--- /dev/null
+++ b/fuzzer/corpus/9abbd6f61f12dac2f0daaca291a329b8a2991d82
Binary files differ
diff --git a/fuzzer/corpus/9aeac0b89be9a5d0175b3b7abc6bd80d3c4f1412 b/fuzzer/corpus/9aeac0b89be9a5d0175b3b7abc6bd80d3c4f1412
new file mode 100644
index 0000000..549ddd1
--- /dev/null
+++ b/fuzzer/corpus/9aeac0b89be9a5d0175b3b7abc6bd80d3c4f1412
Binary files differ
diff --git a/fuzzer/corpus/9b0be960b1129fcf72d2ce3e1da0fe7796e0dbd3 b/fuzzer/corpus/9b0be960b1129fcf72d2ce3e1da0fe7796e0dbd3
new file mode 100644
index 0000000..3fe83a6
--- /dev/null
+++ b/fuzzer/corpus/9b0be960b1129fcf72d2ce3e1da0fe7796e0dbd3
Binary files differ
diff --git a/fuzzer/corpus/9b17ba5112ead18f32c69d680cf1b4c686003586 b/fuzzer/corpus/9b17ba5112ead18f32c69d680cf1b4c686003586
new file mode 100644
index 0000000..8b978e9
--- /dev/null
+++ b/fuzzer/corpus/9b17ba5112ead18f32c69d680cf1b4c686003586
Binary files differ
diff --git a/fuzzer/corpus/9b28b7ceef627b9310f0cc35f61d78e461415797 b/fuzzer/corpus/9b28b7ceef627b9310f0cc35f61d78e461415797
new file mode 100644
index 0000000..8533254
--- /dev/null
+++ b/fuzzer/corpus/9b28b7ceef627b9310f0cc35f61d78e461415797
Binary files differ
diff --git a/fuzzer/corpus/9b30d4296c272fdd48876e4d517d8cd48e7e23c8 b/fuzzer/corpus/9b30d4296c272fdd48876e4d517d8cd48e7e23c8
new file mode 100644
index 0000000..3da5a8b
--- /dev/null
+++ b/fuzzer/corpus/9b30d4296c272fdd48876e4d517d8cd48e7e23c8
Binary files differ
diff --git a/fuzzer/corpus/9b4be303509d04ccded139062d1c86949f13a749 b/fuzzer/corpus/9b4be303509d04ccded139062d1c86949f13a749
new file mode 100644
index 0000000..4672175
--- /dev/null
+++ b/fuzzer/corpus/9b4be303509d04ccded139062d1c86949f13a749
Binary files differ
diff --git a/fuzzer/corpus/9b54cf3a3e5abac1f1798e62cf557eb53785cd71 b/fuzzer/corpus/9b54cf3a3e5abac1f1798e62cf557eb53785cd71
new file mode 100644
index 0000000..60dd322
--- /dev/null
+++ b/fuzzer/corpus/9b54cf3a3e5abac1f1798e62cf557eb53785cd71
Binary files differ
diff --git a/fuzzer/corpus/9b7c95b2ee72ab6347484a6679548b7671fec40d b/fuzzer/corpus/9b7c95b2ee72ab6347484a6679548b7671fec40d
new file mode 100644
index 0000000..3dc05f1
--- /dev/null
+++ b/fuzzer/corpus/9b7c95b2ee72ab6347484a6679548b7671fec40d
Binary files differ
diff --git a/fuzzer/corpus/9ba8be5f01e6c59523360e246bf321707195c64e b/fuzzer/corpus/9ba8be5f01e6c59523360e246bf321707195c64e
new file mode 100644
index 0000000..b05c789
--- /dev/null
+++ b/fuzzer/corpus/9ba8be5f01e6c59523360e246bf321707195c64e
Binary files differ
diff --git a/fuzzer/corpus/9c1e071cd40ef456c80db14ab6279191908804e6 b/fuzzer/corpus/9c1e071cd40ef456c80db14ab6279191908804e6
new file mode 100644
index 0000000..27f9515
--- /dev/null
+++ b/fuzzer/corpus/9c1e071cd40ef456c80db14ab6279191908804e6
Binary files differ
diff --git a/fuzzer/corpus/9c241260e18673e5a907fb110c8ab7578bbe82e7 b/fuzzer/corpus/9c241260e18673e5a907fb110c8ab7578bbe82e7
new file mode 100644
index 0000000..eeb0614
--- /dev/null
+++ b/fuzzer/corpus/9c241260e18673e5a907fb110c8ab7578bbe82e7
Binary files differ
diff --git a/fuzzer/corpus/9c47e0548e795d9932d138becfeab778c0180a1d b/fuzzer/corpus/9c47e0548e795d9932d138becfeab778c0180a1d
new file mode 100644
index 0000000..e51128d
--- /dev/null
+++ b/fuzzer/corpus/9c47e0548e795d9932d138becfeab778c0180a1d
Binary files differ
diff --git a/fuzzer/corpus/9c60d94673a78e97b868eabdb3d20beafad86b7d b/fuzzer/corpus/9c60d94673a78e97b868eabdb3d20beafad86b7d
new file mode 100644
index 0000000..c02af52
--- /dev/null
+++ b/fuzzer/corpus/9c60d94673a78e97b868eabdb3d20beafad86b7d
Binary files differ
diff --git a/fuzzer/corpus/9c78b9075fba3c55fe322becd2c14de15357ab5e b/fuzzer/corpus/9c78b9075fba3c55fe322becd2c14de15357ab5e
new file mode 100644
index 0000000..3733dd8
--- /dev/null
+++ b/fuzzer/corpus/9c78b9075fba3c55fe322becd2c14de15357ab5e
Binary files differ
diff --git a/fuzzer/corpus/9cd6dbd06c4d168f9f91f3ea3aada68e3bdcd3ee b/fuzzer/corpus/9cd6dbd06c4d168f9f91f3ea3aada68e3bdcd3ee
new file mode 100644
index 0000000..0e9a686
--- /dev/null
+++ b/fuzzer/corpus/9cd6dbd06c4d168f9f91f3ea3aada68e3bdcd3ee
Binary files differ
diff --git a/fuzzer/corpus/9cec130b4190e0064c6654fdfc72e4c846f06ab3 b/fuzzer/corpus/9cec130b4190e0064c6654fdfc72e4c846f06ab3
new file mode 100644
index 0000000..f6765e0
--- /dev/null
+++ b/fuzzer/corpus/9cec130b4190e0064c6654fdfc72e4c846f06ab3
Binary files differ
diff --git a/fuzzer/corpus/9cfe6596628788f5442c7b6d32dddd46b2e9322f b/fuzzer/corpus/9cfe6596628788f5442c7b6d32dddd46b2e9322f
new file mode 100644
index 0000000..3adc8c0
--- /dev/null
+++ b/fuzzer/corpus/9cfe6596628788f5442c7b6d32dddd46b2e9322f
Binary files differ
diff --git a/fuzzer/corpus/9d3f8c4341dc52765ae5568821439d79b2ff4486 b/fuzzer/corpus/9d3f8c4341dc52765ae5568821439d79b2ff4486
new file mode 100644
index 0000000..37517f5
--- /dev/null
+++ b/fuzzer/corpus/9d3f8c4341dc52765ae5568821439d79b2ff4486
Binary files differ
diff --git a/fuzzer/corpus/9d7bab66e6a5c032289b5bf8f41318432689f691 b/fuzzer/corpus/9d7bab66e6a5c032289b5bf8f41318432689f691
new file mode 100644
index 0000000..883b66f
--- /dev/null
+++ b/fuzzer/corpus/9d7bab66e6a5c032289b5bf8f41318432689f691
Binary files differ
diff --git a/fuzzer/corpus/9d94d57d2a876d3c974280a054f6b861e8b8ee8f b/fuzzer/corpus/9d94d57d2a876d3c974280a054f6b861e8b8ee8f
new file mode 100644
index 0000000..007c513
--- /dev/null
+++ b/fuzzer/corpus/9d94d57d2a876d3c974280a054f6b861e8b8ee8f
Binary files differ
diff --git a/fuzzer/corpus/9da016e1836bf58d9e01bd78b407234e8a63d5b6 b/fuzzer/corpus/9da016e1836bf58d9e01bd78b407234e8a63d5b6
new file mode 100644
index 0000000..90af751
--- /dev/null
+++ b/fuzzer/corpus/9da016e1836bf58d9e01bd78b407234e8a63d5b6
Binary files differ
diff --git a/fuzzer/corpus/9de256302dde57124d6e1a589384b22cbb6744d4 b/fuzzer/corpus/9de256302dde57124d6e1a589384b22cbb6744d4
new file mode 100644
index 0000000..08297e4
--- /dev/null
+++ b/fuzzer/corpus/9de256302dde57124d6e1a589384b22cbb6744d4
Binary files differ
diff --git a/fuzzer/corpus/9dedc2eb341a398320cfc085a594038b9059ea06 b/fuzzer/corpus/9dedc2eb341a398320cfc085a594038b9059ea06
new file mode 100644
index 0000000..6c94e21
--- /dev/null
+++ b/fuzzer/corpus/9dedc2eb341a398320cfc085a594038b9059ea06
Binary files differ
diff --git a/fuzzer/corpus/9e2ae70380ac19788fc7895b341bdbab163a87e8 b/fuzzer/corpus/9e2ae70380ac19788fc7895b341bdbab163a87e8
new file mode 100644
index 0000000..4e675de
--- /dev/null
+++ b/fuzzer/corpus/9e2ae70380ac19788fc7895b341bdbab163a87e8
Binary files differ
diff --git a/fuzzer/corpus/9e30979bb21ddfdaa17bed28f606f472dff0f19e b/fuzzer/corpus/9e30979bb21ddfdaa17bed28f606f472dff0f19e
new file mode 100644
index 0000000..6a45d0d
--- /dev/null
+++ b/fuzzer/corpus/9e30979bb21ddfdaa17bed28f606f472dff0f19e
Binary files differ
diff --git a/fuzzer/corpus/9e3ca060f2f65039dcd9e16d1ad3985ab44382b2 b/fuzzer/corpus/9e3ca060f2f65039dcd9e16d1ad3985ab44382b2
new file mode 100644
index 0000000..b0dc2c7
--- /dev/null
+++ b/fuzzer/corpus/9e3ca060f2f65039dcd9e16d1ad3985ab44382b2
Binary files differ
diff --git a/fuzzer/corpus/9e449baa1048738d81380e1c891c07dd43e1a9b2 b/fuzzer/corpus/9e449baa1048738d81380e1c891c07dd43e1a9b2
new file mode 100644
index 0000000..17d3a65
--- /dev/null
+++ b/fuzzer/corpus/9e449baa1048738d81380e1c891c07dd43e1a9b2
Binary files differ
diff --git a/fuzzer/corpus/9e5b8aa4c45e3619d85a1473229e1d66f4ad48e7 b/fuzzer/corpus/9e5b8aa4c45e3619d85a1473229e1d66f4ad48e7
new file mode 100644
index 0000000..65e4941
--- /dev/null
+++ b/fuzzer/corpus/9e5b8aa4c45e3619d85a1473229e1d66f4ad48e7
Binary files differ
diff --git a/fuzzer/corpus/9e803f57defd8e912dc797b9dbfd3aac27b9ace9 b/fuzzer/corpus/9e803f57defd8e912dc797b9dbfd3aac27b9ace9
new file mode 100644
index 0000000..e5522de
--- /dev/null
+++ b/fuzzer/corpus/9e803f57defd8e912dc797b9dbfd3aac27b9ace9
Binary files differ
diff --git a/fuzzer/corpus/9ec2ede23b6c73d00cb2f6018b64f493dbcd8efa b/fuzzer/corpus/9ec2ede23b6c73d00cb2f6018b64f493dbcd8efa
new file mode 100644
index 0000000..cbe116c
--- /dev/null
+++ b/fuzzer/corpus/9ec2ede23b6c73d00cb2f6018b64f493dbcd8efa
Binary files differ
diff --git a/fuzzer/corpus/9ecf66a3ebd3a67fd436993d4bdb3f847daa3697 b/fuzzer/corpus/9ecf66a3ebd3a67fd436993d4bdb3f847daa3697
new file mode 100644
index 0000000..f142ffc
--- /dev/null
+++ b/fuzzer/corpus/9ecf66a3ebd3a67fd436993d4bdb3f847daa3697
Binary files differ
diff --git a/fuzzer/corpus/9eee3d01b6f15e1dd4f63931031019468b3555a0 b/fuzzer/corpus/9eee3d01b6f15e1dd4f63931031019468b3555a0
new file mode 100644
index 0000000..389c4a7
--- /dev/null
+++ b/fuzzer/corpus/9eee3d01b6f15e1dd4f63931031019468b3555a0
Binary files differ
diff --git a/fuzzer/corpus/9ef41e08dee8a1199d0a13a0386c67b71667ad6b b/fuzzer/corpus/9ef41e08dee8a1199d0a13a0386c67b71667ad6b
new file mode 100644
index 0000000..28a6f7c
--- /dev/null
+++ b/fuzzer/corpus/9ef41e08dee8a1199d0a13a0386c67b71667ad6b
Binary files differ
diff --git a/fuzzer/corpus/9f330d1c0863135fee70bd56c9f716d3a9bbefba b/fuzzer/corpus/9f330d1c0863135fee70bd56c9f716d3a9bbefba
new file mode 100644
index 0000000..1c555c9
--- /dev/null
+++ b/fuzzer/corpus/9f330d1c0863135fee70bd56c9f716d3a9bbefba
Binary files differ
diff --git a/fuzzer/corpus/9f4f5cc25f7e9f4ae4c55a52c1b1f01c70350d94 b/fuzzer/corpus/9f4f5cc25f7e9f4ae4c55a52c1b1f01c70350d94
new file mode 100644
index 0000000..acf4cdc
--- /dev/null
+++ b/fuzzer/corpus/9f4f5cc25f7e9f4ae4c55a52c1b1f01c70350d94
Binary files differ
diff --git a/fuzzer/corpus/9f52f113cf6b07f8fa43582f7a651e3b1a24082e b/fuzzer/corpus/9f52f113cf6b07f8fa43582f7a651e3b1a24082e
new file mode 100644
index 0000000..e1f9855
--- /dev/null
+++ b/fuzzer/corpus/9f52f113cf6b07f8fa43582f7a651e3b1a24082e
Binary files differ
diff --git a/fuzzer/corpus/9f59ae1a679d0db7b98247533bbdbac5025eb28a b/fuzzer/corpus/9f59ae1a679d0db7b98247533bbdbac5025eb28a
new file mode 100644
index 0000000..4ac4b1b
--- /dev/null
+++ b/fuzzer/corpus/9f59ae1a679d0db7b98247533bbdbac5025eb28a
Binary files differ
diff --git a/fuzzer/corpus/9f6ecea8ab081020ee29b0f69970cfcb1b470b23 b/fuzzer/corpus/9f6ecea8ab081020ee29b0f69970cfcb1b470b23
new file mode 100644
index 0000000..43b9c44
--- /dev/null
+++ b/fuzzer/corpus/9f6ecea8ab081020ee29b0f69970cfcb1b470b23
Binary files differ
diff --git a/fuzzer/corpus/9f85bca93890d4ab652e0f78921590b71ad39922 b/fuzzer/corpus/9f85bca93890d4ab652e0f78921590b71ad39922
new file mode 100644
index 0000000..37688e9
--- /dev/null
+++ b/fuzzer/corpus/9f85bca93890d4ab652e0f78921590b71ad39922
Binary files differ
diff --git a/fuzzer/corpus/9fa9198d7ec1a0e0f29bf8e3843b4e331b2be8f9 b/fuzzer/corpus/9fa9198d7ec1a0e0f29bf8e3843b4e331b2be8f9
new file mode 100644
index 0000000..1ad3071
--- /dev/null
+++ b/fuzzer/corpus/9fa9198d7ec1a0e0f29bf8e3843b4e331b2be8f9
Binary files differ
diff --git a/fuzzer/corpus/9fb7a6049b631b7a9b00dc8156ba10c76dc234a1 b/fuzzer/corpus/9fb7a6049b631b7a9b00dc8156ba10c76dc234a1
new file mode 100644
index 0000000..245f910
--- /dev/null
+++ b/fuzzer/corpus/9fb7a6049b631b7a9b00dc8156ba10c76dc234a1
Binary files differ
diff --git a/fuzzer/corpus/a00ce6721f4e3b6c8bbde0357aa9b6ed3dcd2653 b/fuzzer/corpus/a00ce6721f4e3b6c8bbde0357aa9b6ed3dcd2653
new file mode 100644
index 0000000..1bf2c51
--- /dev/null
+++ b/fuzzer/corpus/a00ce6721f4e3b6c8bbde0357aa9b6ed3dcd2653
Binary files differ
diff --git a/fuzzer/corpus/a0402e7a7b9602d44e1da267a785de5b57a09668 b/fuzzer/corpus/a0402e7a7b9602d44e1da267a785de5b57a09668
new file mode 100644
index 0000000..ec00c5b
--- /dev/null
+++ b/fuzzer/corpus/a0402e7a7b9602d44e1da267a785de5b57a09668
Binary files differ
diff --git a/fuzzer/corpus/a04ec9682a046248e400ac66a09c69c968da8009 b/fuzzer/corpus/a04ec9682a046248e400ac66a09c69c968da8009
new file mode 100644
index 0000000..1461e2a
--- /dev/null
+++ b/fuzzer/corpus/a04ec9682a046248e400ac66a09c69c968da8009
Binary files differ
diff --git a/fuzzer/corpus/a05f44b7ae3fe252ae56e532595ff032f2ece62e b/fuzzer/corpus/a05f44b7ae3fe252ae56e532595ff032f2ece62e
new file mode 100644
index 0000000..bc8c39b
--- /dev/null
+++ b/fuzzer/corpus/a05f44b7ae3fe252ae56e532595ff032f2ece62e
Binary files differ
diff --git a/fuzzer/corpus/a06e5d87f23c6dabba262a6b301a425636b434ef b/fuzzer/corpus/a06e5d87f23c6dabba262a6b301a425636b434ef
new file mode 100644
index 0000000..0d12e07
--- /dev/null
+++ b/fuzzer/corpus/a06e5d87f23c6dabba262a6b301a425636b434ef
Binary files differ
diff --git a/fuzzer/corpus/a0724ef9d2a467d743f996937ba3ef72225860e2 b/fuzzer/corpus/a0724ef9d2a467d743f996937ba3ef72225860e2
new file mode 100644
index 0000000..e0c7d5f
--- /dev/null
+++ b/fuzzer/corpus/a0724ef9d2a467d743f996937ba3ef72225860e2
Binary files differ
diff --git a/fuzzer/corpus/a07bec09199f97fbe68679d9ef1b3f8180084336 b/fuzzer/corpus/a07bec09199f97fbe68679d9ef1b3f8180084336
new file mode 100644
index 0000000..c856f3f
--- /dev/null
+++ b/fuzzer/corpus/a07bec09199f97fbe68679d9ef1b3f8180084336
Binary files differ
diff --git a/fuzzer/corpus/a07de385038f371937bbdc041d1698a3eeeb0e3a b/fuzzer/corpus/a07de385038f371937bbdc041d1698a3eeeb0e3a
new file mode 100644
index 0000000..95ee188
--- /dev/null
+++ b/fuzzer/corpus/a07de385038f371937bbdc041d1698a3eeeb0e3a
Binary files differ
diff --git a/fuzzer/corpus/a0a5e60ad7c50a8adce5d9a706d1990194816322 b/fuzzer/corpus/a0a5e60ad7c50a8adce5d9a706d1990194816322
new file mode 100644
index 0000000..a2e0e38
--- /dev/null
+++ b/fuzzer/corpus/a0a5e60ad7c50a8adce5d9a706d1990194816322
Binary files differ
diff --git a/fuzzer/corpus/a0b74f15cc136779c3036836d74c7f833ae9655f b/fuzzer/corpus/a0b74f15cc136779c3036836d74c7f833ae9655f
new file mode 100644
index 0000000..d4c075c
--- /dev/null
+++ b/fuzzer/corpus/a0b74f15cc136779c3036836d74c7f833ae9655f
Binary files differ
diff --git a/fuzzer/corpus/a124a6aea6603776b3a71cd813903d4191ec82c0 b/fuzzer/corpus/a124a6aea6603776b3a71cd813903d4191ec82c0
new file mode 100644
index 0000000..ed2581d
--- /dev/null
+++ b/fuzzer/corpus/a124a6aea6603776b3a71cd813903d4191ec82c0
Binary files differ
diff --git a/fuzzer/corpus/a131ab9d440a60d6eb3f77ac366d91a4589744b6 b/fuzzer/corpus/a131ab9d440a60d6eb3f77ac366d91a4589744b6
new file mode 100644
index 0000000..6d6d9f7
--- /dev/null
+++ b/fuzzer/corpus/a131ab9d440a60d6eb3f77ac366d91a4589744b6
Binary files differ
diff --git a/fuzzer/corpus/a140f3a860b94995c124e3ebe261598a20b2a390 b/fuzzer/corpus/a140f3a860b94995c124e3ebe261598a20b2a390
new file mode 100644
index 0000000..e02c41f
--- /dev/null
+++ b/fuzzer/corpus/a140f3a860b94995c124e3ebe261598a20b2a390
Binary files differ
diff --git a/fuzzer/corpus/a17c51b2fa9f23ff210d0e89917b26fb14daf8a1 b/fuzzer/corpus/a17c51b2fa9f23ff210d0e89917b26fb14daf8a1
new file mode 100644
index 0000000..c2dbcec
--- /dev/null
+++ b/fuzzer/corpus/a17c51b2fa9f23ff210d0e89917b26fb14daf8a1
Binary files differ
diff --git a/fuzzer/corpus/a197d714b9b79700a96df7028af09116f360ba72 b/fuzzer/corpus/a197d714b9b79700a96df7028af09116f360ba72
new file mode 100644
index 0000000..f958b11
--- /dev/null
+++ b/fuzzer/corpus/a197d714b9b79700a96df7028af09116f360ba72
Binary files differ
diff --git a/fuzzer/corpus/a19e0848b6ae37a8334f174eb35725df1882dc62 b/fuzzer/corpus/a19e0848b6ae37a8334f174eb35725df1882dc62
new file mode 100644
index 0000000..e0c4fd3
--- /dev/null
+++ b/fuzzer/corpus/a19e0848b6ae37a8334f174eb35725df1882dc62
Binary files differ
diff --git a/fuzzer/corpus/a1c6ff56ff1f880f79350ecbc7612e7f69023a6c b/fuzzer/corpus/a1c6ff56ff1f880f79350ecbc7612e7f69023a6c
new file mode 100644
index 0000000..6360e7b
--- /dev/null
+++ b/fuzzer/corpus/a1c6ff56ff1f880f79350ecbc7612e7f69023a6c
Binary files differ
diff --git a/fuzzer/corpus/a23b0f4d2553440e151ce9cf8a24fffc6efad9c0 b/fuzzer/corpus/a23b0f4d2553440e151ce9cf8a24fffc6efad9c0
new file mode 100644
index 0000000..efe1c72
--- /dev/null
+++ b/fuzzer/corpus/a23b0f4d2553440e151ce9cf8a24fffc6efad9c0
Binary files differ
diff --git a/fuzzer/corpus/a252e70476c0635ccafb278f4a35fb48e8818c30 b/fuzzer/corpus/a252e70476c0635ccafb278f4a35fb48e8818c30
new file mode 100644
index 0000000..0ba6339
--- /dev/null
+++ b/fuzzer/corpus/a252e70476c0635ccafb278f4a35fb48e8818c30
Binary files differ
diff --git a/fuzzer/corpus/a25e19710fcd419d19f54f0a572449a0056f9d20 b/fuzzer/corpus/a25e19710fcd419d19f54f0a572449a0056f9d20
new file mode 100644
index 0000000..94439d3
--- /dev/null
+++ b/fuzzer/corpus/a25e19710fcd419d19f54f0a572449a0056f9d20
Binary files differ
diff --git a/fuzzer/corpus/a2778495452f89e265644e0fc66964af0f7d9e60 b/fuzzer/corpus/a2778495452f89e265644e0fc66964af0f7d9e60
new file mode 100644
index 0000000..4c7d723
--- /dev/null
+++ b/fuzzer/corpus/a2778495452f89e265644e0fc66964af0f7d9e60
Binary files differ
diff --git a/fuzzer/corpus/a2a6b6cbc125c6b928182cc5ea8aae7a20425e0d b/fuzzer/corpus/a2a6b6cbc125c6b928182cc5ea8aae7a20425e0d
new file mode 100644
index 0000000..27b7fbb
--- /dev/null
+++ b/fuzzer/corpus/a2a6b6cbc125c6b928182cc5ea8aae7a20425e0d
Binary files differ
diff --git a/fuzzer/corpus/a2bdbdd72978f996e9d09afe3268c68b53b78783 b/fuzzer/corpus/a2bdbdd72978f996e9d09afe3268c68b53b78783
new file mode 100644
index 0000000..3d7e355
--- /dev/null
+++ b/fuzzer/corpus/a2bdbdd72978f996e9d09afe3268c68b53b78783
Binary files differ
diff --git a/fuzzer/corpus/a2ec72c9750f0709b192400745be046d3da77685 b/fuzzer/corpus/a2ec72c9750f0709b192400745be046d3da77685
new file mode 100644
index 0000000..3e48711
--- /dev/null
+++ b/fuzzer/corpus/a2ec72c9750f0709b192400745be046d3da77685
Binary files differ
diff --git a/fuzzer/corpus/a30075c591196ff0ac86376af28a7be74de77ad1 b/fuzzer/corpus/a30075c591196ff0ac86376af28a7be74de77ad1
new file mode 100644
index 0000000..4b2b438
--- /dev/null
+++ b/fuzzer/corpus/a30075c591196ff0ac86376af28a7be74de77ad1
Binary files differ
diff --git a/fuzzer/corpus/a31e589e6dea656fd22d7d01e46d98e5ef8b28d8 b/fuzzer/corpus/a31e589e6dea656fd22d7d01e46d98e5ef8b28d8
new file mode 100644
index 0000000..b31c110
--- /dev/null
+++ b/fuzzer/corpus/a31e589e6dea656fd22d7d01e46d98e5ef8b28d8
Binary files differ
diff --git a/fuzzer/corpus/a34e28b15e51ee0fbc40f0386395d98fa2ad339c b/fuzzer/corpus/a34e28b15e51ee0fbc40f0386395d98fa2ad339c
new file mode 100644
index 0000000..442c53c
--- /dev/null
+++ b/fuzzer/corpus/a34e28b15e51ee0fbc40f0386395d98fa2ad339c
Binary files differ
diff --git a/fuzzer/corpus/a3936fbf2a00ca8477e83d2a0cbb6c4e162f629e b/fuzzer/corpus/a3936fbf2a00ca8477e83d2a0cbb6c4e162f629e
new file mode 100644
index 0000000..786dbc1
--- /dev/null
+++ b/fuzzer/corpus/a3936fbf2a00ca8477e83d2a0cbb6c4e162f629e
Binary files differ
diff --git a/fuzzer/corpus/a39828749775b26453a2d58c5a786922403dafc4 b/fuzzer/corpus/a39828749775b26453a2d58c5a786922403dafc4
new file mode 100644
index 0000000..05e43eb
--- /dev/null
+++ b/fuzzer/corpus/a39828749775b26453a2d58c5a786922403dafc4
Binary files differ
diff --git a/fuzzer/corpus/a3ca6f82d249c0ab8f79ab4b58edc0b9d055d142 b/fuzzer/corpus/a3ca6f82d249c0ab8f79ab4b58edc0b9d055d142
new file mode 100644
index 0000000..823fc1d
--- /dev/null
+++ b/fuzzer/corpus/a3ca6f82d249c0ab8f79ab4b58edc0b9d055d142
Binary files differ
diff --git a/fuzzer/corpus/a40db43a6195cce6df5ff0077c7fca1fbe016fb3 b/fuzzer/corpus/a40db43a6195cce6df5ff0077c7fca1fbe016fb3
new file mode 100644
index 0000000..64ceaa6
--- /dev/null
+++ b/fuzzer/corpus/a40db43a6195cce6df5ff0077c7fca1fbe016fb3
Binary files differ
diff --git a/fuzzer/corpus/a41c29b344f7a32203f4c6fbb3341d66a76e0f8d b/fuzzer/corpus/a41c29b344f7a32203f4c6fbb3341d66a76e0f8d
new file mode 100644
index 0000000..fbe2a73
--- /dev/null
+++ b/fuzzer/corpus/a41c29b344f7a32203f4c6fbb3341d66a76e0f8d
Binary files differ
diff --git a/fuzzer/corpus/a4431c62fb8ef0665686a78cd818282946ba9aaa b/fuzzer/corpus/a4431c62fb8ef0665686a78cd818282946ba9aaa
new file mode 100644
index 0000000..a85cf56
--- /dev/null
+++ b/fuzzer/corpus/a4431c62fb8ef0665686a78cd818282946ba9aaa
Binary files differ
diff --git a/fuzzer/corpus/a448a9d7e6765afd6d1028dec3cfca58e17b581b b/fuzzer/corpus/a448a9d7e6765afd6d1028dec3cfca58e17b581b
new file mode 100644
index 0000000..fdf755f
--- /dev/null
+++ b/fuzzer/corpus/a448a9d7e6765afd6d1028dec3cfca58e17b581b
Binary files differ
diff --git a/fuzzer/corpus/a46ffe0e19429417ab070f2c3ce34a6fac2c582c b/fuzzer/corpus/a46ffe0e19429417ab070f2c3ce34a6fac2c582c
new file mode 100644
index 0000000..a1fe7d2
--- /dev/null
+++ b/fuzzer/corpus/a46ffe0e19429417ab070f2c3ce34a6fac2c582c
Binary files differ
diff --git a/fuzzer/corpus/a472e7c34f650bfa9b6642c14d493a32c10d5492 b/fuzzer/corpus/a472e7c34f650bfa9b6642c14d493a32c10d5492
new file mode 100644
index 0000000..7004f51
--- /dev/null
+++ b/fuzzer/corpus/a472e7c34f650bfa9b6642c14d493a32c10d5492
Binary files differ
diff --git a/fuzzer/corpus/a4b78ac6b2d9cbb4aac5db15a808236c47c81648 b/fuzzer/corpus/a4b78ac6b2d9cbb4aac5db15a808236c47c81648
new file mode 100644
index 0000000..3d4602c
--- /dev/null
+++ b/fuzzer/corpus/a4b78ac6b2d9cbb4aac5db15a808236c47c81648
Binary files differ
diff --git a/fuzzer/corpus/a4de7cbc3d38d08ba145a1ea7cab672a5e7839c0 b/fuzzer/corpus/a4de7cbc3d38d08ba145a1ea7cab672a5e7839c0
new file mode 100644
index 0000000..0deeaf2
--- /dev/null
+++ b/fuzzer/corpus/a4de7cbc3d38d08ba145a1ea7cab672a5e7839c0
Binary files differ
diff --git a/fuzzer/corpus/a4eb99045b43365c0c07d08573ce80293e662f5b b/fuzzer/corpus/a4eb99045b43365c0c07d08573ce80293e662f5b
new file mode 100644
index 0000000..d4d6ff7
--- /dev/null
+++ b/fuzzer/corpus/a4eb99045b43365c0c07d08573ce80293e662f5b
Binary files differ
diff --git a/fuzzer/corpus/a4f64bc10c0d08f3be022aabad141a68414ff5e3 b/fuzzer/corpus/a4f64bc10c0d08f3be022aabad141a68414ff5e3
new file mode 100644
index 0000000..fa35469
--- /dev/null
+++ b/fuzzer/corpus/a4f64bc10c0d08f3be022aabad141a68414ff5e3
Binary files differ
diff --git a/fuzzer/corpus/a555234f5da3adddce2137190718450dba377e56 b/fuzzer/corpus/a555234f5da3adddce2137190718450dba377e56
new file mode 100644
index 0000000..729113e
--- /dev/null
+++ b/fuzzer/corpus/a555234f5da3adddce2137190718450dba377e56
Binary files differ
diff --git a/fuzzer/corpus/a568ae849db9ba3c316c7c3ddb48c5f88b6b1c25 b/fuzzer/corpus/a568ae849db9ba3c316c7c3ddb48c5f88b6b1c25
new file mode 100644
index 0000000..d3bbe33
--- /dev/null
+++ b/fuzzer/corpus/a568ae849db9ba3c316c7c3ddb48c5f88b6b1c25
Binary files differ
diff --git a/fuzzer/corpus/a57bdbc6ea4669a17704ca5de70aa2b1d1b09bd4 b/fuzzer/corpus/a57bdbc6ea4669a17704ca5de70aa2b1d1b09bd4
new file mode 100644
index 0000000..6aadee8
--- /dev/null
+++ b/fuzzer/corpus/a57bdbc6ea4669a17704ca5de70aa2b1d1b09bd4
Binary files differ
diff --git a/fuzzer/corpus/a58164328a9db030f36a8fc7f11dccddfa1ca050 b/fuzzer/corpus/a58164328a9db030f36a8fc7f11dccddfa1ca050
new file mode 100644
index 0000000..2358768
--- /dev/null
+++ b/fuzzer/corpus/a58164328a9db030f36a8fc7f11dccddfa1ca050
Binary files differ
diff --git a/fuzzer/corpus/a5a1a9ec9db8510374b7d62883154c95e13afdc1 b/fuzzer/corpus/a5a1a9ec9db8510374b7d62883154c95e13afdc1
new file mode 100644
index 0000000..0437e06
--- /dev/null
+++ b/fuzzer/corpus/a5a1a9ec9db8510374b7d62883154c95e13afdc1
Binary files differ
diff --git a/fuzzer/corpus/a5b715881b7e41246bb34205acf8a99cf6ad5b15 b/fuzzer/corpus/a5b715881b7e41246bb34205acf8a99cf6ad5b15
new file mode 100644
index 0000000..75e8554
--- /dev/null
+++ b/fuzzer/corpus/a5b715881b7e41246bb34205acf8a99cf6ad5b15
Binary files differ
diff --git a/fuzzer/corpus/a5db49eeea0edb757b08e378ded563004d33fb71 b/fuzzer/corpus/a5db49eeea0edb757b08e378ded563004d33fb71
new file mode 100644
index 0000000..d3c4db5
--- /dev/null
+++ b/fuzzer/corpus/a5db49eeea0edb757b08e378ded563004d33fb71
Binary files differ
diff --git a/fuzzer/corpus/a5e72b3b078d1d8f9b12007aaaeb57bffcff2684 b/fuzzer/corpus/a5e72b3b078d1d8f9b12007aaaeb57bffcff2684
new file mode 100644
index 0000000..1824f43
--- /dev/null
+++ b/fuzzer/corpus/a5e72b3b078d1d8f9b12007aaaeb57bffcff2684
Binary files differ
diff --git a/fuzzer/corpus/a60b2c853a9e3b3be9f31a3b19d94e6dcb957e83 b/fuzzer/corpus/a60b2c853a9e3b3be9f31a3b19d94e6dcb957e83
new file mode 100644
index 0000000..b46ea32
--- /dev/null
+++ b/fuzzer/corpus/a60b2c853a9e3b3be9f31a3b19d94e6dcb957e83
Binary files differ
diff --git a/fuzzer/corpus/a62085e1420f6bc8587fa150147d892568930aeb b/fuzzer/corpus/a62085e1420f6bc8587fa150147d892568930aeb
new file mode 100644
index 0000000..fcf98fb
--- /dev/null
+++ b/fuzzer/corpus/a62085e1420f6bc8587fa150147d892568930aeb
Binary files differ
diff --git a/fuzzer/corpus/a63b134d68fcd412a837d7a684da1da24d3faebe b/fuzzer/corpus/a63b134d68fcd412a837d7a684da1da24d3faebe
new file mode 100644
index 0000000..08c3b52
--- /dev/null
+++ b/fuzzer/corpus/a63b134d68fcd412a837d7a684da1da24d3faebe
Binary files differ
diff --git a/fuzzer/corpus/a648ffd089006c76755202162341974dfa085f0b b/fuzzer/corpus/a648ffd089006c76755202162341974dfa085f0b
new file mode 100644
index 0000000..3631151
--- /dev/null
+++ b/fuzzer/corpus/a648ffd089006c76755202162341974dfa085f0b
Binary files differ
diff --git a/fuzzer/corpus/a64f2befea21affc7215b7710c8f698eff46f6f1 b/fuzzer/corpus/a64f2befea21affc7215b7710c8f698eff46f6f1
new file mode 100644
index 0000000..6c8db22
--- /dev/null
+++ b/fuzzer/corpus/a64f2befea21affc7215b7710c8f698eff46f6f1
Binary files differ
diff --git a/fuzzer/corpus/a66e6843fa98cffdc1a61d3827b0a5e7d467e399 b/fuzzer/corpus/a66e6843fa98cffdc1a61d3827b0a5e7d467e399
new file mode 100644
index 0000000..75efeb3
--- /dev/null
+++ b/fuzzer/corpus/a66e6843fa98cffdc1a61d3827b0a5e7d467e399
Binary files differ
diff --git a/fuzzer/corpus/a671a8bce0d19da27a479f63d662d109321d7c1c b/fuzzer/corpus/a671a8bce0d19da27a479f63d662d109321d7c1c
new file mode 100644
index 0000000..47a3c5a
--- /dev/null
+++ b/fuzzer/corpus/a671a8bce0d19da27a479f63d662d109321d7c1c
Binary files differ
diff --git a/fuzzer/corpus/a68cfa9b49941181d0536cbe57c0ff875682be5f b/fuzzer/corpus/a68cfa9b49941181d0536cbe57c0ff875682be5f
new file mode 100644
index 0000000..8c7bf10
--- /dev/null
+++ b/fuzzer/corpus/a68cfa9b49941181d0536cbe57c0ff875682be5f
Binary files differ
diff --git a/fuzzer/corpus/a68f939e75f3107545f434142bea3f77de5af2aa b/fuzzer/corpus/a68f939e75f3107545f434142bea3f77de5af2aa
new file mode 100644
index 0000000..f69b20c
--- /dev/null
+++ b/fuzzer/corpus/a68f939e75f3107545f434142bea3f77de5af2aa
Binary files differ
diff --git a/fuzzer/corpus/a6af47c9d1aa96128faf909754769812a92ea2cd b/fuzzer/corpus/a6af47c9d1aa96128faf909754769812a92ea2cd
new file mode 100644
index 0000000..3fee5af
--- /dev/null
+++ b/fuzzer/corpus/a6af47c9d1aa96128faf909754769812a92ea2cd
Binary files differ
diff --git a/fuzzer/corpus/a6b3e6680654fdbc7f8aa50dc1e200bbdacd1b86 b/fuzzer/corpus/a6b3e6680654fdbc7f8aa50dc1e200bbdacd1b86
new file mode 100644
index 0000000..a69cd7a
--- /dev/null
+++ b/fuzzer/corpus/a6b3e6680654fdbc7f8aa50dc1e200bbdacd1b86
Binary files differ
diff --git a/fuzzer/corpus/a6b7dcfe93de48aa50ab692f9dde48659cf8bb51 b/fuzzer/corpus/a6b7dcfe93de48aa50ab692f9dde48659cf8bb51
new file mode 100644
index 0000000..9573021
--- /dev/null
+++ b/fuzzer/corpus/a6b7dcfe93de48aa50ab692f9dde48659cf8bb51
Binary files differ
diff --git a/fuzzer/corpus/a6bb1a9b10959fe53936a1fac7eb0bde4be444aa b/fuzzer/corpus/a6bb1a9b10959fe53936a1fac7eb0bde4be444aa
new file mode 100644
index 0000000..a60a6db
--- /dev/null
+++ b/fuzzer/corpus/a6bb1a9b10959fe53936a1fac7eb0bde4be444aa
Binary files differ
diff --git a/fuzzer/corpus/a6e1ce7cc857d744fd47a08b8a659a0ac0a4d466 b/fuzzer/corpus/a6e1ce7cc857d744fd47a08b8a659a0ac0a4d466
new file mode 100644
index 0000000..1b346c7
--- /dev/null
+++ b/fuzzer/corpus/a6e1ce7cc857d744fd47a08b8a659a0ac0a4d466
Binary files differ
diff --git a/fuzzer/corpus/a6e33f3db52b71566c50f6eae9ccabea13071b05 b/fuzzer/corpus/a6e33f3db52b71566c50f6eae9ccabea13071b05
new file mode 100644
index 0000000..b5d9de7
--- /dev/null
+++ b/fuzzer/corpus/a6e33f3db52b71566c50f6eae9ccabea13071b05
Binary files differ
diff --git a/fuzzer/corpus/a6fca0cc59ddb4e67de9a60338c3c045f1bfaafe b/fuzzer/corpus/a6fca0cc59ddb4e67de9a60338c3c045f1bfaafe
new file mode 100644
index 0000000..fd99bc0
--- /dev/null
+++ b/fuzzer/corpus/a6fca0cc59ddb4e67de9a60338c3c045f1bfaafe
Binary files differ
diff --git a/fuzzer/corpus/a72ca9cb40b29c1264df92aeae418e3172042018 b/fuzzer/corpus/a72ca9cb40b29c1264df92aeae418e3172042018
new file mode 100644
index 0000000..853c9eb
--- /dev/null
+++ b/fuzzer/corpus/a72ca9cb40b29c1264df92aeae418e3172042018
Binary files differ
diff --git a/fuzzer/corpus/a755472a71ea22d4f9f3b0645c4da32283838008 b/fuzzer/corpus/a755472a71ea22d4f9f3b0645c4da32283838008
new file mode 100644
index 0000000..67d0a66
--- /dev/null
+++ b/fuzzer/corpus/a755472a71ea22d4f9f3b0645c4da32283838008
Binary files differ
diff --git a/fuzzer/corpus/a7757cd87759689bd919a5da5cbafc6d7ae55753 b/fuzzer/corpus/a7757cd87759689bd919a5da5cbafc6d7ae55753
new file mode 100644
index 0000000..228618d
--- /dev/null
+++ b/fuzzer/corpus/a7757cd87759689bd919a5da5cbafc6d7ae55753
Binary files differ
diff --git a/fuzzer/corpus/a7b8b53d1b04ddd9c057aca5207626def04f20f3 b/fuzzer/corpus/a7b8b53d1b04ddd9c057aca5207626def04f20f3
new file mode 100644
index 0000000..dcf200a
--- /dev/null
+++ b/fuzzer/corpus/a7b8b53d1b04ddd9c057aca5207626def04f20f3
Binary files differ
diff --git a/fuzzer/corpus/a7bfd49bdef2d481abe0b672994dbfb5091e5043 b/fuzzer/corpus/a7bfd49bdef2d481abe0b672994dbfb5091e5043
new file mode 100644
index 0000000..8bf61bd
--- /dev/null
+++ b/fuzzer/corpus/a7bfd49bdef2d481abe0b672994dbfb5091e5043
Binary files differ
diff --git a/fuzzer/corpus/a7c18a6bfc5b1d6d5c2912e0925f2a604335d558 b/fuzzer/corpus/a7c18a6bfc5b1d6d5c2912e0925f2a604335d558
new file mode 100644
index 0000000..d24ca7f
--- /dev/null
+++ b/fuzzer/corpus/a7c18a6bfc5b1d6d5c2912e0925f2a604335d558
Binary files differ
diff --git a/fuzzer/corpus/a7cf4e1481bbc25d69cde1223d0ca1f564f804a1 b/fuzzer/corpus/a7cf4e1481bbc25d69cde1223d0ca1f564f804a1
new file mode 100644
index 0000000..b15a529
--- /dev/null
+++ b/fuzzer/corpus/a7cf4e1481bbc25d69cde1223d0ca1f564f804a1
Binary files differ
diff --git a/fuzzer/corpus/a7e583fff5800704446327afa38bd746689bfbe9 b/fuzzer/corpus/a7e583fff5800704446327afa38bd746689bfbe9
new file mode 100644
index 0000000..9c5f971
--- /dev/null
+++ b/fuzzer/corpus/a7e583fff5800704446327afa38bd746689bfbe9
Binary files differ
diff --git a/fuzzer/corpus/a80466a2b191afca2d8a60dcbb61fd7b8b390b37 b/fuzzer/corpus/a80466a2b191afca2d8a60dcbb61fd7b8b390b37
new file mode 100644
index 0000000..9ba02b1
--- /dev/null
+++ b/fuzzer/corpus/a80466a2b191afca2d8a60dcbb61fd7b8b390b37
Binary files differ
diff --git a/fuzzer/corpus/a807bf50577e8c5083ded8e5c4d225dc05f47f6b b/fuzzer/corpus/a807bf50577e8c5083ded8e5c4d225dc05f47f6b
new file mode 100644
index 0000000..2dd9347
--- /dev/null
+++ b/fuzzer/corpus/a807bf50577e8c5083ded8e5c4d225dc05f47f6b
Binary files differ
diff --git a/fuzzer/corpus/a80b911f1542d09573307e9c8577860fa9816285 b/fuzzer/corpus/a80b911f1542d09573307e9c8577860fa9816285
new file mode 100644
index 0000000..d018455
--- /dev/null
+++ b/fuzzer/corpus/a80b911f1542d09573307e9c8577860fa9816285
Binary files differ
diff --git a/fuzzer/corpus/a82e293ea52cf8fc548427fa24dd7a55c81aed0c b/fuzzer/corpus/a82e293ea52cf8fc548427fa24dd7a55c81aed0c
new file mode 100644
index 0000000..d3456be
--- /dev/null
+++ b/fuzzer/corpus/a82e293ea52cf8fc548427fa24dd7a55c81aed0c
Binary files differ
diff --git a/fuzzer/corpus/a8610f7c50e75bfc1ca37b56db39c3b2f9025004 b/fuzzer/corpus/a8610f7c50e75bfc1ca37b56db39c3b2f9025004
new file mode 100644
index 0000000..2fc0c98
--- /dev/null
+++ b/fuzzer/corpus/a8610f7c50e75bfc1ca37b56db39c3b2f9025004
Binary files differ
diff --git a/fuzzer/corpus/a8621e272ae40c121e7fa695ed6668f237cd7892 b/fuzzer/corpus/a8621e272ae40c121e7fa695ed6668f237cd7892
new file mode 100644
index 0000000..b4218ec
--- /dev/null
+++ b/fuzzer/corpus/a8621e272ae40c121e7fa695ed6668f237cd7892
Binary files differ
diff --git a/fuzzer/corpus/a8762aad35c5b45be111309e719165ff48773a2a b/fuzzer/corpus/a8762aad35c5b45be111309e719165ff48773a2a
new file mode 100644
index 0000000..816c939
--- /dev/null
+++ b/fuzzer/corpus/a8762aad35c5b45be111309e719165ff48773a2a
Binary files differ
diff --git a/fuzzer/corpus/a8790d98d8a107d592eebb5f99dee7b017fdff3b b/fuzzer/corpus/a8790d98d8a107d592eebb5f99dee7b017fdff3b
new file mode 100644
index 0000000..506c5b9
--- /dev/null
+++ b/fuzzer/corpus/a8790d98d8a107d592eebb5f99dee7b017fdff3b
Binary files differ
diff --git a/fuzzer/corpus/a8aed5fafaef98a6b997478b7ed68bbbf666fba4 b/fuzzer/corpus/a8aed5fafaef98a6b997478b7ed68bbbf666fba4
new file mode 100644
index 0000000..bc8c667
--- /dev/null
+++ b/fuzzer/corpus/a8aed5fafaef98a6b997478b7ed68bbbf666fba4
Binary files differ
diff --git a/fuzzer/corpus/a8c1c193e7efd801f9e0a1d910da70ee9d584437 b/fuzzer/corpus/a8c1c193e7efd801f9e0a1d910da70ee9d584437
new file mode 100644
index 0000000..456abd8
--- /dev/null
+++ b/fuzzer/corpus/a8c1c193e7efd801f9e0a1d910da70ee9d584437
Binary files differ
diff --git a/fuzzer/corpus/a8f6bfc3f182aa200bc53909b9e4764efad16802 b/fuzzer/corpus/a8f6bfc3f182aa200bc53909b9e4764efad16802
new file mode 100644
index 0000000..8e69a20
--- /dev/null
+++ b/fuzzer/corpus/a8f6bfc3f182aa200bc53909b9e4764efad16802
Binary files differ
diff --git a/fuzzer/corpus/a9085a24fb1d7300da30a5300f954e3671a52d01 b/fuzzer/corpus/a9085a24fb1d7300da30a5300f954e3671a52d01
new file mode 100644
index 0000000..b22fc15
--- /dev/null
+++ b/fuzzer/corpus/a9085a24fb1d7300da30a5300f954e3671a52d01
Binary files differ
diff --git a/fuzzer/corpus/a926de9ddb04cdfb33ff1683b88f623ec67b584d b/fuzzer/corpus/a926de9ddb04cdfb33ff1683b88f623ec67b584d
new file mode 100644
index 0000000..2fcb53b
--- /dev/null
+++ b/fuzzer/corpus/a926de9ddb04cdfb33ff1683b88f623ec67b584d
Binary files differ
diff --git a/fuzzer/corpus/a9273ea543537deaf8dfd24f6b6f6201206b9abd b/fuzzer/corpus/a9273ea543537deaf8dfd24f6b6f6201206b9abd
new file mode 100644
index 0000000..53e4ddb
--- /dev/null
+++ b/fuzzer/corpus/a9273ea543537deaf8dfd24f6b6f6201206b9abd
Binary files differ
diff --git a/fuzzer/corpus/a964dd60aca3045d39dbdc0c98a037593c67d8c1 b/fuzzer/corpus/a964dd60aca3045d39dbdc0c98a037593c67d8c1
new file mode 100644
index 0000000..fad3752
--- /dev/null
+++ b/fuzzer/corpus/a964dd60aca3045d39dbdc0c98a037593c67d8c1
Binary files differ
diff --git a/fuzzer/corpus/a9980999939802d49268136d3f0a6629686b723a b/fuzzer/corpus/a9980999939802d49268136d3f0a6629686b723a
new file mode 100644
index 0000000..a8dd97f
--- /dev/null
+++ b/fuzzer/corpus/a9980999939802d49268136d3f0a6629686b723a
Binary files differ
diff --git a/fuzzer/corpus/a99d22b39d4c8d341f3ed3ddcb6cfa6d82ff6e8c b/fuzzer/corpus/a99d22b39d4c8d341f3ed3ddcb6cfa6d82ff6e8c
new file mode 100644
index 0000000..455c113
--- /dev/null
+++ b/fuzzer/corpus/a99d22b39d4c8d341f3ed3ddcb6cfa6d82ff6e8c
Binary files differ
diff --git a/fuzzer/corpus/a99e5cc0ab33e44eaeab04bf5de5bfb533a4e23b b/fuzzer/corpus/a99e5cc0ab33e44eaeab04bf5de5bfb533a4e23b
new file mode 100644
index 0000000..e0845bd
--- /dev/null
+++ b/fuzzer/corpus/a99e5cc0ab33e44eaeab04bf5de5bfb533a4e23b
Binary files differ
diff --git a/fuzzer/corpus/a9d704cf90f8a7ca642deb9d6a433341e0ca88cf b/fuzzer/corpus/a9d704cf90f8a7ca642deb9d6a433341e0ca88cf
new file mode 100644
index 0000000..1e67f59
--- /dev/null
+++ b/fuzzer/corpus/a9d704cf90f8a7ca642deb9d6a433341e0ca88cf
Binary files differ
diff --git a/fuzzer/corpus/a9da33b40b2fa6670ba0e4dff941846eaf3663c0 b/fuzzer/corpus/a9da33b40b2fa6670ba0e4dff941846eaf3663c0
new file mode 100644
index 0000000..9675f46
--- /dev/null
+++ b/fuzzer/corpus/a9da33b40b2fa6670ba0e4dff941846eaf3663c0
Binary files differ
diff --git a/fuzzer/corpus/a9e37ec3b9565533fcf017f8b16736fd59b61d99 b/fuzzer/corpus/a9e37ec3b9565533fcf017f8b16736fd59b61d99
new file mode 100644
index 0000000..985fc1c
--- /dev/null
+++ b/fuzzer/corpus/a9e37ec3b9565533fcf017f8b16736fd59b61d99
Binary files differ
diff --git a/fuzzer/corpus/a9f8447603bfc124119e9cdea2d8c879114e2171 b/fuzzer/corpus/a9f8447603bfc124119e9cdea2d8c879114e2171
new file mode 100644
index 0000000..5c4d10e
--- /dev/null
+++ b/fuzzer/corpus/a9f8447603bfc124119e9cdea2d8c879114e2171
Binary files differ
diff --git a/fuzzer/corpus/aa26685e89708e893feb311f566d4b40d18dad64 b/fuzzer/corpus/aa26685e89708e893feb311f566d4b40d18dad64
new file mode 100644
index 0000000..3eb1aec
--- /dev/null
+++ b/fuzzer/corpus/aa26685e89708e893feb311f566d4b40d18dad64
Binary files differ
diff --git a/fuzzer/corpus/aa3b95aac3c7d1ed8530c6683279b1831ae8a146 b/fuzzer/corpus/aa3b95aac3c7d1ed8530c6683279b1831ae8a146
new file mode 100644
index 0000000..1a81e2d
--- /dev/null
+++ b/fuzzer/corpus/aa3b95aac3c7d1ed8530c6683279b1831ae8a146
Binary files differ
diff --git a/fuzzer/corpus/aa3e480fea9bac83b7a634bbf7248d33c771cedc b/fuzzer/corpus/aa3e480fea9bac83b7a634bbf7248d33c771cedc
new file mode 100644
index 0000000..c288080
--- /dev/null
+++ b/fuzzer/corpus/aa3e480fea9bac83b7a634bbf7248d33c771cedc
Binary files differ
diff --git a/fuzzer/corpus/aa5c4d5a591e8b9252992ce55ae8d4a41405fa28 b/fuzzer/corpus/aa5c4d5a591e8b9252992ce55ae8d4a41405fa28
new file mode 100644
index 0000000..e4f4ebf
--- /dev/null
+++ b/fuzzer/corpus/aa5c4d5a591e8b9252992ce55ae8d4a41405fa28
Binary files differ
diff --git a/fuzzer/corpus/aa7a28bb2d469bf02cdfabe01275a62b44c499f1 b/fuzzer/corpus/aa7a28bb2d469bf02cdfabe01275a62b44c499f1
new file mode 100644
index 0000000..16b5cab
--- /dev/null
+++ b/fuzzer/corpus/aa7a28bb2d469bf02cdfabe01275a62b44c499f1
Binary files differ
diff --git a/fuzzer/corpus/aaa1f07d9414ea9fe7be47cd6503e8e11b30bc10 b/fuzzer/corpus/aaa1f07d9414ea9fe7be47cd6503e8e11b30bc10
new file mode 100644
index 0000000..c6fb093
--- /dev/null
+++ b/fuzzer/corpus/aaa1f07d9414ea9fe7be47cd6503e8e11b30bc10
Binary files differ
diff --git a/fuzzer/corpus/ab0f35f174d1d5ee36f7c8503ff01b29e90b62c6 b/fuzzer/corpus/ab0f35f174d1d5ee36f7c8503ff01b29e90b62c6
new file mode 100644
index 0000000..705f146
--- /dev/null
+++ b/fuzzer/corpus/ab0f35f174d1d5ee36f7c8503ff01b29e90b62c6
Binary files differ
diff --git a/fuzzer/corpus/ab179e4cea023bd1811d3abfebeb0e15df9734a9 b/fuzzer/corpus/ab179e4cea023bd1811d3abfebeb0e15df9734a9
new file mode 100644
index 0000000..ff02482
--- /dev/null
+++ b/fuzzer/corpus/ab179e4cea023bd1811d3abfebeb0e15df9734a9
Binary files differ
diff --git a/fuzzer/corpus/ab44a7c3df0a5f904290ed70aa12dcb06d7f6cbc b/fuzzer/corpus/ab44a7c3df0a5f904290ed70aa12dcb06d7f6cbc
new file mode 100644
index 0000000..7ee7172
--- /dev/null
+++ b/fuzzer/corpus/ab44a7c3df0a5f904290ed70aa12dcb06d7f6cbc
Binary files differ
diff --git a/fuzzer/corpus/ab77f104aa790021b9820064a863915a2b428ff8 b/fuzzer/corpus/ab77f104aa790021b9820064a863915a2b428ff8
new file mode 100644
index 0000000..10df6d1
--- /dev/null
+++ b/fuzzer/corpus/ab77f104aa790021b9820064a863915a2b428ff8
Binary files differ
diff --git a/fuzzer/corpus/ab95629542ccb25866fa532ec2cc211c5755acb3 b/fuzzer/corpus/ab95629542ccb25866fa532ec2cc211c5755acb3
new file mode 100644
index 0000000..9810c8a
--- /dev/null
+++ b/fuzzer/corpus/ab95629542ccb25866fa532ec2cc211c5755acb3
Binary files differ
diff --git a/fuzzer/corpus/ab95f7b5ac2973fd98c5f05485649704e3b3238b b/fuzzer/corpus/ab95f7b5ac2973fd98c5f05485649704e3b3238b
new file mode 100644
index 0000000..1903cfd
--- /dev/null
+++ b/fuzzer/corpus/ab95f7b5ac2973fd98c5f05485649704e3b3238b
Binary files differ
diff --git a/fuzzer/corpus/ab99877141b7d2af9892f88dd2aee0e20cd107e9 b/fuzzer/corpus/ab99877141b7d2af9892f88dd2aee0e20cd107e9
new file mode 100644
index 0000000..4964587
--- /dev/null
+++ b/fuzzer/corpus/ab99877141b7d2af9892f88dd2aee0e20cd107e9
Binary files differ
diff --git a/fuzzer/corpus/abafd0bf8000a84106e3aaf1d5dbcc99584a939e b/fuzzer/corpus/abafd0bf8000a84106e3aaf1d5dbcc99584a939e
new file mode 100644
index 0000000..74bf563
--- /dev/null
+++ b/fuzzer/corpus/abafd0bf8000a84106e3aaf1d5dbcc99584a939e
Binary files differ
diff --git a/fuzzer/corpus/abc9a933d36067f16a6e15a7cec665f7e3a4afa8 b/fuzzer/corpus/abc9a933d36067f16a6e15a7cec665f7e3a4afa8
new file mode 100644
index 0000000..f1331a9
--- /dev/null
+++ b/fuzzer/corpus/abc9a933d36067f16a6e15a7cec665f7e3a4afa8
Binary files differ
diff --git a/fuzzer/corpus/abcd351e2c4acca2d217d822faf119d76df34cd5 b/fuzzer/corpus/abcd351e2c4acca2d217d822faf119d76df34cd5
new file mode 100644
index 0000000..f0c0987
--- /dev/null
+++ b/fuzzer/corpus/abcd351e2c4acca2d217d822faf119d76df34cd5
Binary files differ
diff --git a/fuzzer/corpus/ac1b044cdad246e47a4bea9734b7cc8a5e8b1411 b/fuzzer/corpus/ac1b044cdad246e47a4bea9734b7cc8a5e8b1411
new file mode 100644
index 0000000..6f0af37
--- /dev/null
+++ b/fuzzer/corpus/ac1b044cdad246e47a4bea9734b7cc8a5e8b1411
Binary files differ
diff --git a/fuzzer/corpus/ac52ae7784ff5e407122bd10c1382ea3dc72adb3 b/fuzzer/corpus/ac52ae7784ff5e407122bd10c1382ea3dc72adb3
new file mode 100644
index 0000000..9d7587f
--- /dev/null
+++ b/fuzzer/corpus/ac52ae7784ff5e407122bd10c1382ea3dc72adb3
Binary files differ
diff --git a/fuzzer/corpus/ac573f59d8cbc7628dc70fbe607273f7b4a90e14 b/fuzzer/corpus/ac573f59d8cbc7628dc70fbe607273f7b4a90e14
new file mode 100644
index 0000000..7776013
--- /dev/null
+++ b/fuzzer/corpus/ac573f59d8cbc7628dc70fbe607273f7b4a90e14
Binary files differ
diff --git a/fuzzer/corpus/ac66b21b0d6e8f86ef3e4e0acb57f277ba596b02 b/fuzzer/corpus/ac66b21b0d6e8f86ef3e4e0acb57f277ba596b02
new file mode 100644
index 0000000..ee34296
--- /dev/null
+++ b/fuzzer/corpus/ac66b21b0d6e8f86ef3e4e0acb57f277ba596b02
Binary files differ
diff --git a/fuzzer/corpus/acb32e7192b794c926b90d06963f95e1c0b66e72 b/fuzzer/corpus/acb32e7192b794c926b90d06963f95e1c0b66e72
new file mode 100644
index 0000000..64f825b
--- /dev/null
+++ b/fuzzer/corpus/acb32e7192b794c926b90d06963f95e1c0b66e72
Binary files differ
diff --git a/fuzzer/corpus/acb606851bdac198612ac62801f7a1c73b82be27 b/fuzzer/corpus/acb606851bdac198612ac62801f7a1c73b82be27
new file mode 100644
index 0000000..19df6ad
--- /dev/null
+++ b/fuzzer/corpus/acb606851bdac198612ac62801f7a1c73b82be27
Binary files differ
diff --git a/fuzzer/corpus/acc711730e20e150881af343a1ab56b416056398 b/fuzzer/corpus/acc711730e20e150881af343a1ab56b416056398
new file mode 100644
index 0000000..06be284
--- /dev/null
+++ b/fuzzer/corpus/acc711730e20e150881af343a1ab56b416056398
Binary files differ
diff --git a/fuzzer/corpus/acf53b89ce2f08f052602c438ee2aa52b461f3a0 b/fuzzer/corpus/acf53b89ce2f08f052602c438ee2aa52b461f3a0
new file mode 100644
index 0000000..7f2c7b9
--- /dev/null
+++ b/fuzzer/corpus/acf53b89ce2f08f052602c438ee2aa52b461f3a0
Binary files differ
diff --git a/fuzzer/corpus/ad0dbd1e1da9a5830c00cddc9b803e98b423538e b/fuzzer/corpus/ad0dbd1e1da9a5830c00cddc9b803e98b423538e
new file mode 100644
index 0000000..fd38514
--- /dev/null
+++ b/fuzzer/corpus/ad0dbd1e1da9a5830c00cddc9b803e98b423538e
Binary files differ
diff --git a/fuzzer/corpus/ad37b6ad4541ba1e70e8ed071dcf87bcdddfe80a b/fuzzer/corpus/ad37b6ad4541ba1e70e8ed071dcf87bcdddfe80a
new file mode 100644
index 0000000..a66496e
--- /dev/null
+++ b/fuzzer/corpus/ad37b6ad4541ba1e70e8ed071dcf87bcdddfe80a
Binary files differ
diff --git a/fuzzer/corpus/ad4b1a1e5b1d101d805ebb7701aedde8a77b2e95 b/fuzzer/corpus/ad4b1a1e5b1d101d805ebb7701aedde8a77b2e95
new file mode 100644
index 0000000..f14986a
--- /dev/null
+++ b/fuzzer/corpus/ad4b1a1e5b1d101d805ebb7701aedde8a77b2e95
Binary files differ
diff --git a/fuzzer/corpus/ad576ac9cf0b654830eb06800ad44c23877ccb20 b/fuzzer/corpus/ad576ac9cf0b654830eb06800ad44c23877ccb20
new file mode 100644
index 0000000..ebaff1a
--- /dev/null
+++ b/fuzzer/corpus/ad576ac9cf0b654830eb06800ad44c23877ccb20
Binary files differ
diff --git a/fuzzer/corpus/ad83a49bd0873471b1ca7be8b42c6304c5a17c48 b/fuzzer/corpus/ad83a49bd0873471b1ca7be8b42c6304c5a17c48
new file mode 100644
index 0000000..4db9dee
--- /dev/null
+++ b/fuzzer/corpus/ad83a49bd0873471b1ca7be8b42c6304c5a17c48
Binary files differ
diff --git a/fuzzer/corpus/ae004a2b950aa5f3a7c35c1fabbfb27f3ebacaa2 b/fuzzer/corpus/ae004a2b950aa5f3a7c35c1fabbfb27f3ebacaa2
new file mode 100644
index 0000000..5c51dec
--- /dev/null
+++ b/fuzzer/corpus/ae004a2b950aa5f3a7c35c1fabbfb27f3ebacaa2
Binary files differ
diff --git a/fuzzer/corpus/ae122e655e7f051e8bf61282ed984c9d9c9ab615 b/fuzzer/corpus/ae122e655e7f051e8bf61282ed984c9d9c9ab615
new file mode 100644
index 0000000..764985a
--- /dev/null
+++ b/fuzzer/corpus/ae122e655e7f051e8bf61282ed984c9d9c9ab615
Binary files differ
diff --git a/fuzzer/corpus/ae9865a8b03a07140310e5b3b4ae839ec194f35f b/fuzzer/corpus/ae9865a8b03a07140310e5b3b4ae839ec194f35f
new file mode 100644
index 0000000..51b643c
--- /dev/null
+++ b/fuzzer/corpus/ae9865a8b03a07140310e5b3b4ae839ec194f35f
Binary files differ
diff --git a/fuzzer/corpus/aea36ae4121c712f1492013c8abc8c2a14ba2488 b/fuzzer/corpus/aea36ae4121c712f1492013c8abc8c2a14ba2488
new file mode 100644
index 0000000..4255ff0
--- /dev/null
+++ b/fuzzer/corpus/aea36ae4121c712f1492013c8abc8c2a14ba2488
Binary files differ
diff --git a/fuzzer/corpus/aeb959af83d479c18a5df10be115f641d739a14d b/fuzzer/corpus/aeb959af83d479c18a5df10be115f641d739a14d
new file mode 100644
index 0000000..ef41a0b
--- /dev/null
+++ b/fuzzer/corpus/aeb959af83d479c18a5df10be115f641d739a14d
Binary files differ
diff --git a/fuzzer/corpus/aed457ce90a7906073f591e1a90899c47e40c877 b/fuzzer/corpus/aed457ce90a7906073f591e1a90899c47e40c877
new file mode 100644
index 0000000..e015f5f
--- /dev/null
+++ b/fuzzer/corpus/aed457ce90a7906073f591e1a90899c47e40c877
Binary files differ
diff --git a/fuzzer/corpus/aefabca803961bd5f8c8da0fe93629450c474fab b/fuzzer/corpus/aefabca803961bd5f8c8da0fe93629450c474fab
new file mode 100644
index 0000000..ca3da64
--- /dev/null
+++ b/fuzzer/corpus/aefabca803961bd5f8c8da0fe93629450c474fab
Binary files differ
diff --git a/fuzzer/corpus/af04023d6c0b94605931eb6c898a5decd4095d41 b/fuzzer/corpus/af04023d6c0b94605931eb6c898a5decd4095d41
new file mode 100644
index 0000000..1f99f73
--- /dev/null
+++ b/fuzzer/corpus/af04023d6c0b94605931eb6c898a5decd4095d41
Binary files differ
diff --git a/fuzzer/corpus/af13d6384d400e9ea79d5180be68bdab81b28006 b/fuzzer/corpus/af13d6384d400e9ea79d5180be68bdab81b28006
new file mode 100644
index 0000000..aaafc57
--- /dev/null
+++ b/fuzzer/corpus/af13d6384d400e9ea79d5180be68bdab81b28006
Binary files differ
diff --git a/fuzzer/corpus/af14df49d0daf61bfb099627cc0e03c0198afb97 b/fuzzer/corpus/af14df49d0daf61bfb099627cc0e03c0198afb97
new file mode 100644
index 0000000..0a7a3da
--- /dev/null
+++ b/fuzzer/corpus/af14df49d0daf61bfb099627cc0e03c0198afb97
Binary files differ
diff --git a/fuzzer/corpus/af160ab09726a432f0cd0b26bbd35d7668a5d2be b/fuzzer/corpus/af160ab09726a432f0cd0b26bbd35d7668a5d2be
new file mode 100644
index 0000000..4969200
--- /dev/null
+++ b/fuzzer/corpus/af160ab09726a432f0cd0b26bbd35d7668a5d2be
Binary files differ
diff --git a/fuzzer/corpus/af5cedd5aee77a244f0bfd53e11e16de96916525 b/fuzzer/corpus/af5cedd5aee77a244f0bfd53e11e16de96916525
new file mode 100644
index 0000000..bce9c50
--- /dev/null
+++ b/fuzzer/corpus/af5cedd5aee77a244f0bfd53e11e16de96916525
Binary files differ
diff --git a/fuzzer/corpus/af620437941a7d0844db040b95e9d96ef23236cd b/fuzzer/corpus/af620437941a7d0844db040b95e9d96ef23236cd
new file mode 100644
index 0000000..0f4d45a
--- /dev/null
+++ b/fuzzer/corpus/af620437941a7d0844db040b95e9d96ef23236cd
Binary files differ
diff --git a/fuzzer/corpus/af8d61c41eb03f751c7a4cdf854472dae2f1d144 b/fuzzer/corpus/af8d61c41eb03f751c7a4cdf854472dae2f1d144
new file mode 100644
index 0000000..6745776
--- /dev/null
+++ b/fuzzer/corpus/af8d61c41eb03f751c7a4cdf854472dae2f1d144
Binary files differ
diff --git a/fuzzer/corpus/affac4eaed8393429b7f04d63842aa37490e87fe b/fuzzer/corpus/affac4eaed8393429b7f04d63842aa37490e87fe
new file mode 100644
index 0000000..66a2891
--- /dev/null
+++ b/fuzzer/corpus/affac4eaed8393429b7f04d63842aa37490e87fe
Binary files differ
diff --git a/fuzzer/corpus/affe9b29aa183c3225409684ae7af7593fba56c5 b/fuzzer/corpus/affe9b29aa183c3225409684ae7af7593fba56c5
new file mode 100644
index 0000000..0b144eb
--- /dev/null
+++ b/fuzzer/corpus/affe9b29aa183c3225409684ae7af7593fba56c5
Binary files differ
diff --git a/fuzzer/corpus/b022290019b3aed4b21d1788d75eb3ed38d8642e b/fuzzer/corpus/b022290019b3aed4b21d1788d75eb3ed38d8642e
new file mode 100644
index 0000000..3aa47ac
--- /dev/null
+++ b/fuzzer/corpus/b022290019b3aed4b21d1788d75eb3ed38d8642e
Binary files differ
diff --git a/fuzzer/corpus/b028acef0ec9253f6642ade799b41cd55e1a39bc b/fuzzer/corpus/b028acef0ec9253f6642ade799b41cd55e1a39bc
new file mode 100644
index 0000000..901c66f
--- /dev/null
+++ b/fuzzer/corpus/b028acef0ec9253f6642ade799b41cd55e1a39bc
Binary files differ
diff --git a/fuzzer/corpus/b02e208540bcf9a8d2c32ae51640c9adf645e284 b/fuzzer/corpus/b02e208540bcf9a8d2c32ae51640c9adf645e284
new file mode 100644
index 0000000..f8d4066
--- /dev/null
+++ b/fuzzer/corpus/b02e208540bcf9a8d2c32ae51640c9adf645e284
Binary files differ
diff --git a/fuzzer/corpus/b038fbb7453c449f1c944d66f7d4ec4481c9b645 b/fuzzer/corpus/b038fbb7453c449f1c944d66f7d4ec4481c9b645
new file mode 100644
index 0000000..2959403
--- /dev/null
+++ b/fuzzer/corpus/b038fbb7453c449f1c944d66f7d4ec4481c9b645
Binary files differ
diff --git a/fuzzer/corpus/b0542cd481de90f8dccab5ee9ac3bb38b8c237e7 b/fuzzer/corpus/b0542cd481de90f8dccab5ee9ac3bb38b8c237e7
new file mode 100644
index 0000000..3e7ac3c
--- /dev/null
+++ b/fuzzer/corpus/b0542cd481de90f8dccab5ee9ac3bb38b8c237e7
Binary files differ
diff --git a/fuzzer/corpus/b0a3c32657f342f9d89ab03aac57517202b71a0f b/fuzzer/corpus/b0a3c32657f342f9d89ab03aac57517202b71a0f
new file mode 100644
index 0000000..f6dcfef
--- /dev/null
+++ b/fuzzer/corpus/b0a3c32657f342f9d89ab03aac57517202b71a0f
Binary files differ
diff --git a/fuzzer/corpus/b0a70264a9c59cbca4f87ce3938def92b0434763 b/fuzzer/corpus/b0a70264a9c59cbca4f87ce3938def92b0434763
new file mode 100644
index 0000000..a26f308
--- /dev/null
+++ b/fuzzer/corpus/b0a70264a9c59cbca4f87ce3938def92b0434763
Binary files differ
diff --git a/fuzzer/corpus/b0fa5d53ba8dd1aaf3b86c52c46eb4e8690aa5df b/fuzzer/corpus/b0fa5d53ba8dd1aaf3b86c52c46eb4e8690aa5df
new file mode 100644
index 0000000..4cc9f32
--- /dev/null
+++ b/fuzzer/corpus/b0fa5d53ba8dd1aaf3b86c52c46eb4e8690aa5df
Binary files differ
diff --git a/fuzzer/corpus/b10f95e1644851b913a60078c8cb34a3b0b8e27f b/fuzzer/corpus/b10f95e1644851b913a60078c8cb34a3b0b8e27f
new file mode 100644
index 0000000..af761e9
--- /dev/null
+++ b/fuzzer/corpus/b10f95e1644851b913a60078c8cb34a3b0b8e27f
Binary files differ
diff --git a/fuzzer/corpus/b1125b0a2c6face1f55a14a2cb75d2e8f188ba4f b/fuzzer/corpus/b1125b0a2c6face1f55a14a2cb75d2e8f188ba4f
new file mode 100644
index 0000000..590121a
--- /dev/null
+++ b/fuzzer/corpus/b1125b0a2c6face1f55a14a2cb75d2e8f188ba4f
Binary files differ
diff --git a/fuzzer/corpus/b12e52a882f814bfe59003345091e01753cf5ee2 b/fuzzer/corpus/b12e52a882f814bfe59003345091e01753cf5ee2
new file mode 100644
index 0000000..6a17501
--- /dev/null
+++ b/fuzzer/corpus/b12e52a882f814bfe59003345091e01753cf5ee2
Binary files differ
diff --git a/fuzzer/corpus/b1652b614cf0beaa3e36f67925b430c8dd15b49c b/fuzzer/corpus/b1652b614cf0beaa3e36f67925b430c8dd15b49c
new file mode 100644
index 0000000..13507ac
--- /dev/null
+++ b/fuzzer/corpus/b1652b614cf0beaa3e36f67925b430c8dd15b49c
@@ -0,0 +1 @@
+;&
\ No newline at end of file
diff --git a/fuzzer/corpus/b1b72da7f573b84560265a560b936d2064774bb9 b/fuzzer/corpus/b1b72da7f573b84560265a560b936d2064774bb9
new file mode 100644
index 0000000..f392f77
--- /dev/null
+++ b/fuzzer/corpus/b1b72da7f573b84560265a560b936d2064774bb9
Binary files differ
diff --git a/fuzzer/corpus/b1c2915aec9478032a8bc6563a575ede43894f61 b/fuzzer/corpus/b1c2915aec9478032a8bc6563a575ede43894f61
new file mode 100644
index 0000000..02170a7
--- /dev/null
+++ b/fuzzer/corpus/b1c2915aec9478032a8bc6563a575ede43894f61
Binary files differ
diff --git a/fuzzer/corpus/b1f12b4bd20fab90bae94bebb056697ca05a5b6c b/fuzzer/corpus/b1f12b4bd20fab90bae94bebb056697ca05a5b6c
new file mode 100644
index 0000000..433f934
--- /dev/null
+++ b/fuzzer/corpus/b1f12b4bd20fab90bae94bebb056697ca05a5b6c
Binary files differ
diff --git a/fuzzer/corpus/b1f1b196ad277248bd22e963655405cfeffd5952 b/fuzzer/corpus/b1f1b196ad277248bd22e963655405cfeffd5952
new file mode 100644
index 0000000..8c9cbe8
--- /dev/null
+++ b/fuzzer/corpus/b1f1b196ad277248bd22e963655405cfeffd5952
Binary files differ
diff --git a/fuzzer/corpus/b1f58f240f4a90d9c1f2c6da77e4368358fa226a b/fuzzer/corpus/b1f58f240f4a90d9c1f2c6da77e4368358fa226a
new file mode 100644
index 0000000..1ef2fa5
--- /dev/null
+++ b/fuzzer/corpus/b1f58f240f4a90d9c1f2c6da77e4368358fa226a
Binary files differ
diff --git a/fuzzer/corpus/b23e509660302582884606a0bc8be9a4768f804e b/fuzzer/corpus/b23e509660302582884606a0bc8be9a4768f804e
new file mode 100644
index 0000000..f037f6d
--- /dev/null
+++ b/fuzzer/corpus/b23e509660302582884606a0bc8be9a4768f804e
Binary files differ
diff --git a/fuzzer/corpus/b291c888b73545b92980e02a535be54e949e389d b/fuzzer/corpus/b291c888b73545b92980e02a535be54e949e389d
new file mode 100644
index 0000000..a08da33
--- /dev/null
+++ b/fuzzer/corpus/b291c888b73545b92980e02a535be54e949e389d
Binary files differ
diff --git a/fuzzer/corpus/b327968a2a9ee61ecfe4e1db00c2ae77e9bfd6c7 b/fuzzer/corpus/b327968a2a9ee61ecfe4e1db00c2ae77e9bfd6c7
new file mode 100644
index 0000000..406f925
--- /dev/null
+++ b/fuzzer/corpus/b327968a2a9ee61ecfe4e1db00c2ae77e9bfd6c7
Binary files differ
diff --git a/fuzzer/corpus/b33fd53eaa2d1a2352f898f378fe364f621b5baf b/fuzzer/corpus/b33fd53eaa2d1a2352f898f378fe364f621b5baf
new file mode 100644
index 0000000..964dbe7
--- /dev/null
+++ b/fuzzer/corpus/b33fd53eaa2d1a2352f898f378fe364f621b5baf
Binary files differ
diff --git a/fuzzer/corpus/b3625fa9028a46535dd1a49acd1b70e752b0780e b/fuzzer/corpus/b3625fa9028a46535dd1a49acd1b70e752b0780e
new file mode 100644
index 0000000..878205a
--- /dev/null
+++ b/fuzzer/corpus/b3625fa9028a46535dd1a49acd1b70e752b0780e
Binary files differ
diff --git a/fuzzer/corpus/b36336d1d29dd3ff1cef4b6784e3631a5f555b8d b/fuzzer/corpus/b36336d1d29dd3ff1cef4b6784e3631a5f555b8d
new file mode 100644
index 0000000..e54142f
--- /dev/null
+++ b/fuzzer/corpus/b36336d1d29dd3ff1cef4b6784e3631a5f555b8d
Binary files differ
diff --git a/fuzzer/corpus/b36abefba8e582309e15b81222eec2444aa5f969 b/fuzzer/corpus/b36abefba8e582309e15b81222eec2444aa5f969
new file mode 100644
index 0000000..352dbb4
--- /dev/null
+++ b/fuzzer/corpus/b36abefba8e582309e15b81222eec2444aa5f969
Binary files differ
diff --git a/fuzzer/corpus/b3c38cdc5412279d62511330e04a00ad95dc1a93 b/fuzzer/corpus/b3c38cdc5412279d62511330e04a00ad95dc1a93
new file mode 100644
index 0000000..a0b4f38
--- /dev/null
+++ b/fuzzer/corpus/b3c38cdc5412279d62511330e04a00ad95dc1a93
Binary files differ
diff --git a/fuzzer/corpus/b3cba0ac0c13bf7ee873e11343bb0c9920d9615b b/fuzzer/corpus/b3cba0ac0c13bf7ee873e11343bb0c9920d9615b
new file mode 100644
index 0000000..b78ad28
--- /dev/null
+++ b/fuzzer/corpus/b3cba0ac0c13bf7ee873e11343bb0c9920d9615b
Binary files differ
diff --git a/fuzzer/corpus/b3e1785e7dca08bf2757feebb9a2648f29a3a1da b/fuzzer/corpus/b3e1785e7dca08bf2757feebb9a2648f29a3a1da
new file mode 100644
index 0000000..ee7b1ea
--- /dev/null
+++ b/fuzzer/corpus/b3e1785e7dca08bf2757feebb9a2648f29a3a1da
Binary files differ
diff --git a/fuzzer/corpus/b40035ce3c4a82585110a0e4773a275495c560d0 b/fuzzer/corpus/b40035ce3c4a82585110a0e4773a275495c560d0
new file mode 100644
index 0000000..eeed890
--- /dev/null
+++ b/fuzzer/corpus/b40035ce3c4a82585110a0e4773a275495c560d0
Binary files differ
diff --git a/fuzzer/corpus/b41513e38a40c11ae772fb7a1dc46849306fa929 b/fuzzer/corpus/b41513e38a40c11ae772fb7a1dc46849306fa929
new file mode 100644
index 0000000..8237e15
--- /dev/null
+++ b/fuzzer/corpus/b41513e38a40c11ae772fb7a1dc46849306fa929
Binary files differ
diff --git a/fuzzer/corpus/b440c4a8e9536d283137d567fc89cdb3920dc209 b/fuzzer/corpus/b440c4a8e9536d283137d567fc89cdb3920dc209
new file mode 100644
index 0000000..f7d2590
--- /dev/null
+++ b/fuzzer/corpus/b440c4a8e9536d283137d567fc89cdb3920dc209
Binary files differ
diff --git a/fuzzer/corpus/b447fd8e1f131f7cd3f82e8703a5ad3dddccf205 b/fuzzer/corpus/b447fd8e1f131f7cd3f82e8703a5ad3dddccf205
new file mode 100644
index 0000000..0af81ac
--- /dev/null
+++ b/fuzzer/corpus/b447fd8e1f131f7cd3f82e8703a5ad3dddccf205
Binary files differ
diff --git a/fuzzer/corpus/b475e35ef68932ef1a70e67488b576714fc073ac b/fuzzer/corpus/b475e35ef68932ef1a70e67488b576714fc073ac
new file mode 100644
index 0000000..ac05e33
--- /dev/null
+++ b/fuzzer/corpus/b475e35ef68932ef1a70e67488b576714fc073ac
Binary files differ
diff --git a/fuzzer/corpus/b47b8724900dd415fa9201a7b3b2720147a0ba5b b/fuzzer/corpus/b47b8724900dd415fa9201a7b3b2720147a0ba5b
new file mode 100644
index 0000000..aafd0b3
--- /dev/null
+++ b/fuzzer/corpus/b47b8724900dd415fa9201a7b3b2720147a0ba5b
Binary files differ
diff --git a/fuzzer/corpus/b48701709424c09e9c262b0367a66718df647b80 b/fuzzer/corpus/b48701709424c09e9c262b0367a66718df647b80
new file mode 100644
index 0000000..0d7d6b3
--- /dev/null
+++ b/fuzzer/corpus/b48701709424c09e9c262b0367a66718df647b80
Binary files differ
diff --git a/fuzzer/corpus/b498d0f6ce383ab6aa52d7b786419dd839747bd9 b/fuzzer/corpus/b498d0f6ce383ab6aa52d7b786419dd839747bd9
new file mode 100644
index 0000000..2eeccf4
--- /dev/null
+++ b/fuzzer/corpus/b498d0f6ce383ab6aa52d7b786419dd839747bd9
Binary files differ
diff --git a/fuzzer/corpus/b4bbf596493692f306c888391e41aaeb59d3e417 b/fuzzer/corpus/b4bbf596493692f306c888391e41aaeb59d3e417
new file mode 100644
index 0000000..a452212
--- /dev/null
+++ b/fuzzer/corpus/b4bbf596493692f306c888391e41aaeb59d3e417
Binary files differ
diff --git a/fuzzer/corpus/b4d490f1f29780eee91544d7451a5c977e0acb90 b/fuzzer/corpus/b4d490f1f29780eee91544d7451a5c977e0acb90
new file mode 100644
index 0000000..a109f4f
--- /dev/null
+++ b/fuzzer/corpus/b4d490f1f29780eee91544d7451a5c977e0acb90
Binary files differ
diff --git a/fuzzer/corpus/b4eb663685b5a179cffe6a121849b1f06d102f3e b/fuzzer/corpus/b4eb663685b5a179cffe6a121849b1f06d102f3e
new file mode 100644
index 0000000..d3086da
--- /dev/null
+++ b/fuzzer/corpus/b4eb663685b5a179cffe6a121849b1f06d102f3e
Binary files differ
diff --git a/fuzzer/corpus/b4ed8fb5213913d7dcf0e5a72a3c1e2ab0f635f0 b/fuzzer/corpus/b4ed8fb5213913d7dcf0e5a72a3c1e2ab0f635f0
new file mode 100644
index 0000000..3bfbf21
--- /dev/null
+++ b/fuzzer/corpus/b4ed8fb5213913d7dcf0e5a72a3c1e2ab0f635f0
Binary files differ
diff --git a/fuzzer/corpus/b58033dc578bbf699bbf4c0dfc07678b08c76783 b/fuzzer/corpus/b58033dc578bbf699bbf4c0dfc07678b08c76783
new file mode 100644
index 0000000..9c2c35d
--- /dev/null
+++ b/fuzzer/corpus/b58033dc578bbf699bbf4c0dfc07678b08c76783
Binary files differ
diff --git a/fuzzer/corpus/b581d89809a1ebaedc42ab614a61d3cbd40c5aaa b/fuzzer/corpus/b581d89809a1ebaedc42ab614a61d3cbd40c5aaa
new file mode 100644
index 0000000..6deb058
--- /dev/null
+++ b/fuzzer/corpus/b581d89809a1ebaedc42ab614a61d3cbd40c5aaa
Binary files differ
diff --git a/fuzzer/corpus/b583162b28fa627f80ed2d06cfd4eb1acef39541 b/fuzzer/corpus/b583162b28fa627f80ed2d06cfd4eb1acef39541
new file mode 100644
index 0000000..e9bdc7a
--- /dev/null
+++ b/fuzzer/corpus/b583162b28fa627f80ed2d06cfd4eb1acef39541
Binary files differ
diff --git a/fuzzer/corpus/b598725c815f06686e3c8690697f0ff201d0b57c b/fuzzer/corpus/b598725c815f06686e3c8690697f0ff201d0b57c
new file mode 100644
index 0000000..a973431
--- /dev/null
+++ b/fuzzer/corpus/b598725c815f06686e3c8690697f0ff201d0b57c
Binary files differ
diff --git a/fuzzer/corpus/b6039be1a02771294eb95a5982883ae855433a2a b/fuzzer/corpus/b6039be1a02771294eb95a5982883ae855433a2a
new file mode 100644
index 0000000..ec9ccaf
--- /dev/null
+++ b/fuzzer/corpus/b6039be1a02771294eb95a5982883ae855433a2a
Binary files differ
diff --git a/fuzzer/corpus/b641d3fcf623bdd676f97a8833e82992a4743778 b/fuzzer/corpus/b641d3fcf623bdd676f97a8833e82992a4743778
new file mode 100644
index 0000000..8b49cdd
--- /dev/null
+++ b/fuzzer/corpus/b641d3fcf623bdd676f97a8833e82992a4743778
Binary files differ
diff --git a/fuzzer/corpus/b66b945d4a1b8d6dc719ed083e4f95754d83c31a b/fuzzer/corpus/b66b945d4a1b8d6dc719ed083e4f95754d83c31a
new file mode 100644
index 0000000..b31ffeb
--- /dev/null
+++ b/fuzzer/corpus/b66b945d4a1b8d6dc719ed083e4f95754d83c31a
Binary files differ
diff --git a/fuzzer/corpus/b6b6ebbb24ef7c3ecd1cd4f706c1cafbe710c9b3 b/fuzzer/corpus/b6b6ebbb24ef7c3ecd1cd4f706c1cafbe710c9b3
new file mode 100644
index 0000000..3b1fde1
--- /dev/null
+++ b/fuzzer/corpus/b6b6ebbb24ef7c3ecd1cd4f706c1cafbe710c9b3
Binary files differ
diff --git a/fuzzer/corpus/b6cb886ee698fcd534ab3da6654ef579547b8c11 b/fuzzer/corpus/b6cb886ee698fcd534ab3da6654ef579547b8c11
new file mode 100644
index 0000000..826810d
--- /dev/null
+++ b/fuzzer/corpus/b6cb886ee698fcd534ab3da6654ef579547b8c11
Binary files differ
diff --git a/fuzzer/corpus/b6d8a56fc5e82c823b9d53b45f08787134d67dc7 b/fuzzer/corpus/b6d8a56fc5e82c823b9d53b45f08787134d67dc7
new file mode 100644
index 0000000..8e429e7
--- /dev/null
+++ b/fuzzer/corpus/b6d8a56fc5e82c823b9d53b45f08787134d67dc7
Binary files differ
diff --git a/fuzzer/corpus/b6e96fb3fcc73bf1a984f147a3fd7082ee62d5de b/fuzzer/corpus/b6e96fb3fcc73bf1a984f147a3fd7082ee62d5de
new file mode 100644
index 0000000..098e01b
--- /dev/null
+++ b/fuzzer/corpus/b6e96fb3fcc73bf1a984f147a3fd7082ee62d5de
Binary files differ
diff --git a/fuzzer/corpus/b7001265e0587a7acc0278f748a87b5912021a63 b/fuzzer/corpus/b7001265e0587a7acc0278f748a87b5912021a63
new file mode 100644
index 0000000..b0cca98
--- /dev/null
+++ b/fuzzer/corpus/b7001265e0587a7acc0278f748a87b5912021a63
Binary files differ
diff --git a/fuzzer/corpus/b72fbdd680d25a8f3a19798abc0348698d0cd3c7 b/fuzzer/corpus/b72fbdd680d25a8f3a19798abc0348698d0cd3c7
new file mode 100644
index 0000000..d8e33d3
--- /dev/null
+++ b/fuzzer/corpus/b72fbdd680d25a8f3a19798abc0348698d0cd3c7
Binary files differ
diff --git a/fuzzer/corpus/b745983a72ce95060aa62d8e5209a4681f3e127c b/fuzzer/corpus/b745983a72ce95060aa62d8e5209a4681f3e127c
new file mode 100644
index 0000000..8482cb9
--- /dev/null
+++ b/fuzzer/corpus/b745983a72ce95060aa62d8e5209a4681f3e127c
Binary files differ
diff --git a/fuzzer/corpus/b74cbd5188f5dba946b826ce65c36119fae3f266 b/fuzzer/corpus/b74cbd5188f5dba946b826ce65c36119fae3f266
new file mode 100644
index 0000000..a082e3c
--- /dev/null
+++ b/fuzzer/corpus/b74cbd5188f5dba946b826ce65c36119fae3f266
Binary files differ
diff --git a/fuzzer/corpus/b74f3d88c2ba867d41dd6f3f36529933eb2dc0b9 b/fuzzer/corpus/b74f3d88c2ba867d41dd6f3f36529933eb2dc0b9
new file mode 100644
index 0000000..b4764e7
--- /dev/null
+++ b/fuzzer/corpus/b74f3d88c2ba867d41dd6f3f36529933eb2dc0b9
Binary files differ
diff --git a/fuzzer/corpus/b75b3aa437555a7e6f6ece21981361287fc666bb b/fuzzer/corpus/b75b3aa437555a7e6f6ece21981361287fc666bb
new file mode 100644
index 0000000..866a75f
--- /dev/null
+++ b/fuzzer/corpus/b75b3aa437555a7e6f6ece21981361287fc666bb
Binary files differ
diff --git a/fuzzer/corpus/b75bcc4549e2de797d41bcb716295e20f2dc4caf b/fuzzer/corpus/b75bcc4549e2de797d41bcb716295e20f2dc4caf
new file mode 100644
index 0000000..cd89c81
--- /dev/null
+++ b/fuzzer/corpus/b75bcc4549e2de797d41bcb716295e20f2dc4caf
Binary files differ
diff --git a/fuzzer/corpus/b771cc23ceac245c40b5e7dc3c63f7dc1b350739 b/fuzzer/corpus/b771cc23ceac245c40b5e7dc3c63f7dc1b350739
new file mode 100644
index 0000000..239e67c
--- /dev/null
+++ b/fuzzer/corpus/b771cc23ceac245c40b5e7dc3c63f7dc1b350739
Binary files differ
diff --git a/fuzzer/corpus/b7866740d2712c92b722e0f3cfa74300c48c5b5e b/fuzzer/corpus/b7866740d2712c92b722e0f3cfa74300c48c5b5e
new file mode 100644
index 0000000..033d19e
--- /dev/null
+++ b/fuzzer/corpus/b7866740d2712c92b722e0f3cfa74300c48c5b5e
Binary files differ
diff --git a/fuzzer/corpus/b7960b8fe4c1db84b2e0c86cb95c93c1e414b6c4 b/fuzzer/corpus/b7960b8fe4c1db84b2e0c86cb95c93c1e414b6c4
new file mode 100644
index 0000000..60c47d1
--- /dev/null
+++ b/fuzzer/corpus/b7960b8fe4c1db84b2e0c86cb95c93c1e414b6c4
Binary files differ
diff --git a/fuzzer/corpus/b7b591c4c581bacff52f9fd9bf7304eac4d1f748 b/fuzzer/corpus/b7b591c4c581bacff52f9fd9bf7304eac4d1f748
new file mode 100644
index 0000000..9c47c28
--- /dev/null
+++ b/fuzzer/corpus/b7b591c4c581bacff52f9fd9bf7304eac4d1f748
Binary files differ
diff --git a/fuzzer/corpus/b7b7c408a7166f903e9cc756f4920f79b426381e b/fuzzer/corpus/b7b7c408a7166f903e9cc756f4920f79b426381e
new file mode 100644
index 0000000..99ed937
--- /dev/null
+++ b/fuzzer/corpus/b7b7c408a7166f903e9cc756f4920f79b426381e
Binary files differ
diff --git a/fuzzer/corpus/b7bc2764cebdf51b913de3bc221f9c08373f5966 b/fuzzer/corpus/b7bc2764cebdf51b913de3bc221f9c08373f5966
new file mode 100644
index 0000000..981d3e5
--- /dev/null
+++ b/fuzzer/corpus/b7bc2764cebdf51b913de3bc221f9c08373f5966
Binary files differ
diff --git a/fuzzer/corpus/b7f9e12ba48198f6312c7789e493c41c0be299c9 b/fuzzer/corpus/b7f9e12ba48198f6312c7789e493c41c0be299c9
new file mode 100644
index 0000000..0bbd7c5
--- /dev/null
+++ b/fuzzer/corpus/b7f9e12ba48198f6312c7789e493c41c0be299c9
Binary files differ
diff --git a/fuzzer/corpus/b850ba1387ac36eb58c4a42135157b46d1529d9d b/fuzzer/corpus/b850ba1387ac36eb58c4a42135157b46d1529d9d
new file mode 100644
index 0000000..2348e26
--- /dev/null
+++ b/fuzzer/corpus/b850ba1387ac36eb58c4a42135157b46d1529d9d
Binary files differ
diff --git a/fuzzer/corpus/b88f6fb5473a09c4d7fa4657b606131e8dd21715 b/fuzzer/corpus/b88f6fb5473a09c4d7fa4657b606131e8dd21715
new file mode 100644
index 0000000..f883986
--- /dev/null
+++ b/fuzzer/corpus/b88f6fb5473a09c4d7fa4657b606131e8dd21715
Binary files differ
diff --git a/fuzzer/corpus/b8942cdf264fcfbb26c059e194bad0ee81ba32da b/fuzzer/corpus/b8942cdf264fcfbb26c059e194bad0ee81ba32da
new file mode 100644
index 0000000..e1d0449
--- /dev/null
+++ b/fuzzer/corpus/b8942cdf264fcfbb26c059e194bad0ee81ba32da
Binary files differ
diff --git a/fuzzer/corpus/b8eeb4cce737fd22fd8a6fadd6d0b085d3a6b941 b/fuzzer/corpus/b8eeb4cce737fd22fd8a6fadd6d0b085d3a6b941
new file mode 100644
index 0000000..a626bdf
--- /dev/null
+++ b/fuzzer/corpus/b8eeb4cce737fd22fd8a6fadd6d0b085d3a6b941
Binary files differ
diff --git a/fuzzer/corpus/b9050443cf8610e1ed7f893bdfd81a22eed05e6a b/fuzzer/corpus/b9050443cf8610e1ed7f893bdfd81a22eed05e6a
new file mode 100644
index 0000000..b856a6c
--- /dev/null
+++ b/fuzzer/corpus/b9050443cf8610e1ed7f893bdfd81a22eed05e6a
Binary files differ
diff --git a/fuzzer/corpus/b932bb2aa2598878de6786c90bd1f9199290a148 b/fuzzer/corpus/b932bb2aa2598878de6786c90bd1f9199290a148
new file mode 100644
index 0000000..3b652aa
--- /dev/null
+++ b/fuzzer/corpus/b932bb2aa2598878de6786c90bd1f9199290a148
Binary files differ
diff --git a/fuzzer/corpus/b93694a168b6db389856a8569a80629242d56b95 b/fuzzer/corpus/b93694a168b6db389856a8569a80629242d56b95
new file mode 100644
index 0000000..56ce18c
--- /dev/null
+++ b/fuzzer/corpus/b93694a168b6db389856a8569a80629242d56b95
Binary files differ
diff --git a/fuzzer/corpus/b941c8a8a0296a082a8c2c33c3c93735d486fdb4 b/fuzzer/corpus/b941c8a8a0296a082a8c2c33c3c93735d486fdb4
new file mode 100644
index 0000000..fd06ce7
--- /dev/null
+++ b/fuzzer/corpus/b941c8a8a0296a082a8c2c33c3c93735d486fdb4
Binary files differ
diff --git a/fuzzer/corpus/b950473dc074b0a1d5e041ef84298cead70f06f3 b/fuzzer/corpus/b950473dc074b0a1d5e041ef84298cead70f06f3
new file mode 100644
index 0000000..daf49d7
--- /dev/null
+++ b/fuzzer/corpus/b950473dc074b0a1d5e041ef84298cead70f06f3
Binary files differ
diff --git a/fuzzer/corpus/b95ae04faa88926bbce91e0a0d6475125e7f884e b/fuzzer/corpus/b95ae04faa88926bbce91e0a0d6475125e7f884e
new file mode 100644
index 0000000..7536b20
--- /dev/null
+++ b/fuzzer/corpus/b95ae04faa88926bbce91e0a0d6475125e7f884e
Binary files differ
diff --git a/fuzzer/corpus/b98b9e3109fd96e1a933fc185b47555b162f6b44 b/fuzzer/corpus/b98b9e3109fd96e1a933fc185b47555b162f6b44
new file mode 100644
index 0000000..59e0d6d
--- /dev/null
+++ b/fuzzer/corpus/b98b9e3109fd96e1a933fc185b47555b162f6b44
Binary files differ
diff --git a/fuzzer/corpus/b995acb3754bfd20497513ef1b190331ea73e224 b/fuzzer/corpus/b995acb3754bfd20497513ef1b190331ea73e224
new file mode 100644
index 0000000..4ce7928
--- /dev/null
+++ b/fuzzer/corpus/b995acb3754bfd20497513ef1b190331ea73e224
Binary files differ
diff --git a/fuzzer/corpus/b99f45d03362f3fd9a8f54f6bbdbd0d5730dfc1c b/fuzzer/corpus/b99f45d03362f3fd9a8f54f6bbdbd0d5730dfc1c
new file mode 100644
index 0000000..8a964e1
--- /dev/null
+++ b/fuzzer/corpus/b99f45d03362f3fd9a8f54f6bbdbd0d5730dfc1c
Binary files differ
diff --git a/fuzzer/corpus/b99fbcf533ec1a09f6e3134adb59c101e8351c93 b/fuzzer/corpus/b99fbcf533ec1a09f6e3134adb59c101e8351c93
new file mode 100644
index 0000000..86532a5
--- /dev/null
+++ b/fuzzer/corpus/b99fbcf533ec1a09f6e3134adb59c101e8351c93
Binary files differ
diff --git a/fuzzer/corpus/b9aee39de19dc1039a82aeebb5ba0813a01f4c9e b/fuzzer/corpus/b9aee39de19dc1039a82aeebb5ba0813a01f4c9e
new file mode 100644
index 0000000..1beee77
--- /dev/null
+++ b/fuzzer/corpus/b9aee39de19dc1039a82aeebb5ba0813a01f4c9e
Binary files differ
diff --git a/fuzzer/corpus/b9caaa394e159a3b3bb10e17a1dd43430d01b97e b/fuzzer/corpus/b9caaa394e159a3b3bb10e17a1dd43430d01b97e
new file mode 100644
index 0000000..5461bae
--- /dev/null
+++ b/fuzzer/corpus/b9caaa394e159a3b3bb10e17a1dd43430d01b97e
Binary files differ
diff --git a/fuzzer/corpus/b9db8acd5cb7aab7e5abe50fc881cc8aaacf37ec b/fuzzer/corpus/b9db8acd5cb7aab7e5abe50fc881cc8aaacf37ec
new file mode 100644
index 0000000..b2413dc
--- /dev/null
+++ b/fuzzer/corpus/b9db8acd5cb7aab7e5abe50fc881cc8aaacf37ec
Binary files differ
diff --git a/fuzzer/corpus/b9e69922a79d61b300e659da5d2e2e1a14f4cedd b/fuzzer/corpus/b9e69922a79d61b300e659da5d2e2e1a14f4cedd
new file mode 100644
index 0000000..5c25313
--- /dev/null
+++ b/fuzzer/corpus/b9e69922a79d61b300e659da5d2e2e1a14f4cedd
Binary files differ
diff --git a/fuzzer/corpus/b9ee4302c1793f9e890da1206f9a3be32a961588 b/fuzzer/corpus/b9ee4302c1793f9e890da1206f9a3be32a961588
new file mode 100644
index 0000000..51cf193
--- /dev/null
+++ b/fuzzer/corpus/b9ee4302c1793f9e890da1206f9a3be32a961588
Binary files differ
diff --git a/fuzzer/corpus/ba2d203e7be4e0c06ded8538ebe05a2733d53a46 b/fuzzer/corpus/ba2d203e7be4e0c06ded8538ebe05a2733d53a46
new file mode 100644
index 0000000..c3bbdda
--- /dev/null
+++ b/fuzzer/corpus/ba2d203e7be4e0c06ded8538ebe05a2733d53a46
Binary files differ
diff --git a/fuzzer/corpus/ba3a8325a6ba14ad6fae61f78f368e627cdcaafe b/fuzzer/corpus/ba3a8325a6ba14ad6fae61f78f368e627cdcaafe
new file mode 100644
index 0000000..a716052
--- /dev/null
+++ b/fuzzer/corpus/ba3a8325a6ba14ad6fae61f78f368e627cdcaafe
Binary files differ
diff --git a/fuzzer/corpus/ba5715e84f3f2f69474df91f82a182e964797a06 b/fuzzer/corpus/ba5715e84f3f2f69474df91f82a182e964797a06
new file mode 100644
index 0000000..c86a90f
--- /dev/null
+++ b/fuzzer/corpus/ba5715e84f3f2f69474df91f82a182e964797a06
Binary files differ
diff --git a/fuzzer/corpus/ba81531b7f4f7e40b5da85eaa0e5562d3e8022c5 b/fuzzer/corpus/ba81531b7f4f7e40b5da85eaa0e5562d3e8022c5
new file mode 100644
index 0000000..95b321b
--- /dev/null
+++ b/fuzzer/corpus/ba81531b7f4f7e40b5da85eaa0e5562d3e8022c5
Binary files differ
diff --git a/fuzzer/corpus/ba9a7f3948610b9eb91b70b69ac393854580dfa5 b/fuzzer/corpus/ba9a7f3948610b9eb91b70b69ac393854580dfa5
new file mode 100644
index 0000000..ed16bee
--- /dev/null
+++ b/fuzzer/corpus/ba9a7f3948610b9eb91b70b69ac393854580dfa5
Binary files differ
diff --git a/fuzzer/corpus/baa3c3de1e52d0af2e5d0a48875732b189c63698 b/fuzzer/corpus/baa3c3de1e52d0af2e5d0a48875732b189c63698
new file mode 100644
index 0000000..5e0472d
--- /dev/null
+++ b/fuzzer/corpus/baa3c3de1e52d0af2e5d0a48875732b189c63698
Binary files differ
diff --git a/fuzzer/corpus/bacce5ae9090baa05828db5575c8e133fe7fb8b5 b/fuzzer/corpus/bacce5ae9090baa05828db5575c8e133fe7fb8b5
new file mode 100644
index 0000000..bdb1b7b
--- /dev/null
+++ b/fuzzer/corpus/bacce5ae9090baa05828db5575c8e133fe7fb8b5
Binary files differ
diff --git a/fuzzer/corpus/badf603f73835f42dfcebf1746493e20f5873b90 b/fuzzer/corpus/badf603f73835f42dfcebf1746493e20f5873b90
new file mode 100644
index 0000000..fb19520
--- /dev/null
+++ b/fuzzer/corpus/badf603f73835f42dfcebf1746493e20f5873b90
Binary files differ
diff --git a/fuzzer/corpus/bae520b513fd18dd19647b877cc04cc5ca3cbbe6 b/fuzzer/corpus/bae520b513fd18dd19647b877cc04cc5ca3cbbe6
new file mode 100644
index 0000000..0c7f190
--- /dev/null
+++ b/fuzzer/corpus/bae520b513fd18dd19647b877cc04cc5ca3cbbe6
Binary files differ
diff --git a/fuzzer/corpus/baf43a9588c00adc1f4ff20422836f123a82aad5 b/fuzzer/corpus/baf43a9588c00adc1f4ff20422836f123a82aad5
new file mode 100644
index 0000000..1d4bffa
--- /dev/null
+++ b/fuzzer/corpus/baf43a9588c00adc1f4ff20422836f123a82aad5
Binary files differ
diff --git a/fuzzer/corpus/bb12542fbbcba0a6f45bd83fb468eb67f5c3a068 b/fuzzer/corpus/bb12542fbbcba0a6f45bd83fb468eb67f5c3a068
new file mode 100644
index 0000000..889d238
--- /dev/null
+++ b/fuzzer/corpus/bb12542fbbcba0a6f45bd83fb468eb67f5c3a068
Binary files differ
diff --git a/fuzzer/corpus/bb5421891c0fe63fc68cc0c5b10b38964b648621 b/fuzzer/corpus/bb5421891c0fe63fc68cc0c5b10b38964b648621
new file mode 100644
index 0000000..a32c9c0
--- /dev/null
+++ b/fuzzer/corpus/bb5421891c0fe63fc68cc0c5b10b38964b648621
Binary files differ
diff --git a/fuzzer/corpus/bb8d8660035858ac33272a3ebca5ec75d1ce4152 b/fuzzer/corpus/bb8d8660035858ac33272a3ebca5ec75d1ce4152
new file mode 100644
index 0000000..e1ba7eb
--- /dev/null
+++ b/fuzzer/corpus/bb8d8660035858ac33272a3ebca5ec75d1ce4152
Binary files differ
diff --git a/fuzzer/corpus/bb94b690309f0e51f458dd695f6a8860e9df379a b/fuzzer/corpus/bb94b690309f0e51f458dd695f6a8860e9df379a
new file mode 100644
index 0000000..c19a177
--- /dev/null
+++ b/fuzzer/corpus/bb94b690309f0e51f458dd695f6a8860e9df379a
Binary files differ
diff --git a/fuzzer/corpus/bb97088074b584944d0c9acced60172d4adfc4e5 b/fuzzer/corpus/bb97088074b584944d0c9acced60172d4adfc4e5
new file mode 100644
index 0000000..ba83b6a
--- /dev/null
+++ b/fuzzer/corpus/bb97088074b584944d0c9acced60172d4adfc4e5
Binary files differ
diff --git a/fuzzer/corpus/bb9ce42c48c7bc07fb00585fb7a4e93827b0c561 b/fuzzer/corpus/bb9ce42c48c7bc07fb00585fb7a4e93827b0c561
new file mode 100644
index 0000000..7c9dfb4
--- /dev/null
+++ b/fuzzer/corpus/bb9ce42c48c7bc07fb00585fb7a4e93827b0c561
Binary files differ
diff --git a/fuzzer/corpus/bbbd45af44d2e41cd220e37483aefef6b2f52960 b/fuzzer/corpus/bbbd45af44d2e41cd220e37483aefef6b2f52960
new file mode 100644
index 0000000..66de6d5
--- /dev/null
+++ b/fuzzer/corpus/bbbd45af44d2e41cd220e37483aefef6b2f52960
Binary files differ
diff --git a/fuzzer/corpus/bbd426d0bccdb69e46a7483e5615cb4ab94d650d b/fuzzer/corpus/bbd426d0bccdb69e46a7483e5615cb4ab94d650d
new file mode 100644
index 0000000..796b279
--- /dev/null
+++ b/fuzzer/corpus/bbd426d0bccdb69e46a7483e5615cb4ab94d650d
Binary files differ
diff --git a/fuzzer/corpus/bc0ebc36e28b0f0c688902040f8e1ed8b2abd811 b/fuzzer/corpus/bc0ebc36e28b0f0c688902040f8e1ed8b2abd811
new file mode 100644
index 0000000..d4018ce
--- /dev/null
+++ b/fuzzer/corpus/bc0ebc36e28b0f0c688902040f8e1ed8b2abd811
Binary files differ
diff --git a/fuzzer/corpus/bc39a920a38aa8b64e7a685f27b79506ad0d23f1 b/fuzzer/corpus/bc39a920a38aa8b64e7a685f27b79506ad0d23f1
new file mode 100644
index 0000000..dce67a0
--- /dev/null
+++ b/fuzzer/corpus/bc39a920a38aa8b64e7a685f27b79506ad0d23f1
Binary files differ
diff --git a/fuzzer/corpus/bc4952d872662fbc291a277ba13ae22d4ace930d b/fuzzer/corpus/bc4952d872662fbc291a277ba13ae22d4ace930d
new file mode 100644
index 0000000..9dc1207
--- /dev/null
+++ b/fuzzer/corpus/bc4952d872662fbc291a277ba13ae22d4ace930d
Binary files differ
diff --git a/fuzzer/corpus/bc7826d580d440283dff429ac9c9905718bf75d6 b/fuzzer/corpus/bc7826d580d440283dff429ac9c9905718bf75d6
new file mode 100644
index 0000000..7f13f29
--- /dev/null
+++ b/fuzzer/corpus/bc7826d580d440283dff429ac9c9905718bf75d6
Binary files differ
diff --git a/fuzzer/corpus/bc9426282e32313a9cd0a3ece6cc715a5ffd06ff b/fuzzer/corpus/bc9426282e32313a9cd0a3ece6cc715a5ffd06ff
new file mode 100644
index 0000000..15e0a84
--- /dev/null
+++ b/fuzzer/corpus/bc9426282e32313a9cd0a3ece6cc715a5ffd06ff
Binary files differ
diff --git a/fuzzer/corpus/bc9cd7287ae59ba22c63b51218a0a91ae908838a b/fuzzer/corpus/bc9cd7287ae59ba22c63b51218a0a91ae908838a
new file mode 100644
index 0000000..169e666
--- /dev/null
+++ b/fuzzer/corpus/bc9cd7287ae59ba22c63b51218a0a91ae908838a
Binary files differ
diff --git a/fuzzer/corpus/bd5ab3828cbac216f5d83280d9789cf4769ad8ff b/fuzzer/corpus/bd5ab3828cbac216f5d83280d9789cf4769ad8ff
new file mode 100644
index 0000000..0ab4f26
--- /dev/null
+++ b/fuzzer/corpus/bd5ab3828cbac216f5d83280d9789cf4769ad8ff
Binary files differ
diff --git a/fuzzer/corpus/bd5e1582204b02899c6d0dc7cf0826d0bb724b3c b/fuzzer/corpus/bd5e1582204b02899c6d0dc7cf0826d0bb724b3c
new file mode 100644
index 0000000..80b19ae
--- /dev/null
+++ b/fuzzer/corpus/bd5e1582204b02899c6d0dc7cf0826d0bb724b3c
Binary files differ
diff --git a/fuzzer/corpus/bd635e6d7c9ebc629376a62e6af1aa0148afc566 b/fuzzer/corpus/bd635e6d7c9ebc629376a62e6af1aa0148afc566
new file mode 100644
index 0000000..6c565f1
--- /dev/null
+++ b/fuzzer/corpus/bd635e6d7c9ebc629376a62e6af1aa0148afc566
Binary files differ
diff --git a/fuzzer/corpus/bd72c459d5a0efe7e82bfe4f1d32aca6687f2fe5 b/fuzzer/corpus/bd72c459d5a0efe7e82bfe4f1d32aca6687f2fe5
new file mode 100644
index 0000000..2173539
--- /dev/null
+++ b/fuzzer/corpus/bd72c459d5a0efe7e82bfe4f1d32aca6687f2fe5
Binary files differ
diff --git a/fuzzer/corpus/bd9e7f46e6c5b1142ec9c009e5a83b523215e22d b/fuzzer/corpus/bd9e7f46e6c5b1142ec9c009e5a83b523215e22d
new file mode 100644
index 0000000..cee7c2e
--- /dev/null
+++ b/fuzzer/corpus/bd9e7f46e6c5b1142ec9c009e5a83b523215e22d
Binary files differ
diff --git a/fuzzer/corpus/bdea3acc726e3bd6d974fefb878197d5bd7a5485 b/fuzzer/corpus/bdea3acc726e3bd6d974fefb878197d5bd7a5485
new file mode 100644
index 0000000..52439b1
--- /dev/null
+++ b/fuzzer/corpus/bdea3acc726e3bd6d974fefb878197d5bd7a5485
Binary files differ
diff --git a/fuzzer/corpus/be09590cc41daae7ef0277a76c20bc4fd8b36a54 b/fuzzer/corpus/be09590cc41daae7ef0277a76c20bc4fd8b36a54
new file mode 100644
index 0000000..cee6a67
--- /dev/null
+++ b/fuzzer/corpus/be09590cc41daae7ef0277a76c20bc4fd8b36a54
Binary files differ
diff --git a/fuzzer/corpus/be23a59a45fe126b642362c68298fc63aaf13bf9 b/fuzzer/corpus/be23a59a45fe126b642362c68298fc63aaf13bf9
new file mode 100644
index 0000000..bb5a96f
--- /dev/null
+++ b/fuzzer/corpus/be23a59a45fe126b642362c68298fc63aaf13bf9
Binary files differ
diff --git a/fuzzer/corpus/be2699f198d68a817d9b05fa1db35cac7714a5ba b/fuzzer/corpus/be2699f198d68a817d9b05fa1db35cac7714a5ba
new file mode 100644
index 0000000..7182758
--- /dev/null
+++ b/fuzzer/corpus/be2699f198d68a817d9b05fa1db35cac7714a5ba
Binary files differ
diff --git a/fuzzer/corpus/be2d7751cc20fec3f4e6ae46fc83ab4e32638298 b/fuzzer/corpus/be2d7751cc20fec3f4e6ae46fc83ab4e32638298
new file mode 100644
index 0000000..1eaf6fb
--- /dev/null
+++ b/fuzzer/corpus/be2d7751cc20fec3f4e6ae46fc83ab4e32638298
Binary files differ
diff --git a/fuzzer/corpus/be5f64f7cf49e8529d9dfbdb32bc4b8a54c11ee5 b/fuzzer/corpus/be5f64f7cf49e8529d9dfbdb32bc4b8a54c11ee5
new file mode 100644
index 0000000..d88d58c
--- /dev/null
+++ b/fuzzer/corpus/be5f64f7cf49e8529d9dfbdb32bc4b8a54c11ee5
Binary files differ
diff --git a/fuzzer/corpus/bead7fdb23ee992cf34ec618b7056d1be31eaddb b/fuzzer/corpus/bead7fdb23ee992cf34ec618b7056d1be31eaddb
new file mode 100644
index 0000000..05a6696
--- /dev/null
+++ b/fuzzer/corpus/bead7fdb23ee992cf34ec618b7056d1be31eaddb
Binary files differ
diff --git a/fuzzer/corpus/beaf8e60ed55818f340fde040a81c00334546ff9 b/fuzzer/corpus/beaf8e60ed55818f340fde040a81c00334546ff9
new file mode 100644
index 0000000..0228b19
--- /dev/null
+++ b/fuzzer/corpus/beaf8e60ed55818f340fde040a81c00334546ff9
Binary files differ
diff --git a/fuzzer/corpus/bee09d5ddacce66a5d55c99d6dcd7166649391c4 b/fuzzer/corpus/bee09d5ddacce66a5d55c99d6dcd7166649391c4
new file mode 100644
index 0000000..477057b
--- /dev/null
+++ b/fuzzer/corpus/bee09d5ddacce66a5d55c99d6dcd7166649391c4
Binary files differ
diff --git a/fuzzer/corpus/bf25eda33a2717edffe85232d873613e4142aa64 b/fuzzer/corpus/bf25eda33a2717edffe85232d873613e4142aa64
new file mode 100644
index 0000000..c98e0bb
--- /dev/null
+++ b/fuzzer/corpus/bf25eda33a2717edffe85232d873613e4142aa64
Binary files differ
diff --git a/fuzzer/corpus/bf28d3c66562b717b60601e68e7fd8b4f266e528 b/fuzzer/corpus/bf28d3c66562b717b60601e68e7fd8b4f266e528
new file mode 100644
index 0000000..4eda14d
--- /dev/null
+++ b/fuzzer/corpus/bf28d3c66562b717b60601e68e7fd8b4f266e528
Binary files differ
diff --git a/fuzzer/corpus/bf4ca10ebc1e9daac0585d49f16c632d5dadb515 b/fuzzer/corpus/bf4ca10ebc1e9daac0585d49f16c632d5dadb515
new file mode 100644
index 0000000..c87bd2b
--- /dev/null
+++ b/fuzzer/corpus/bf4ca10ebc1e9daac0585d49f16c632d5dadb515
Binary files differ
diff --git a/fuzzer/corpus/bf5c0891eaa757f14ffcd5977168d814e9e18c06 b/fuzzer/corpus/bf5c0891eaa757f14ffcd5977168d814e9e18c06
new file mode 100644
index 0000000..0643b1e
--- /dev/null
+++ b/fuzzer/corpus/bf5c0891eaa757f14ffcd5977168d814e9e18c06
Binary files differ
diff --git a/fuzzer/corpus/bf6a832403a22548ac588dbf7cd340455f26b4cd b/fuzzer/corpus/bf6a832403a22548ac588dbf7cd340455f26b4cd
new file mode 100644
index 0000000..93b4179
--- /dev/null
+++ b/fuzzer/corpus/bf6a832403a22548ac588dbf7cd340455f26b4cd
Binary files differ
diff --git a/fuzzer/corpus/bf9a9a089dc3155f5bd73ecb3842a8c5a4e89628 b/fuzzer/corpus/bf9a9a089dc3155f5bd73ecb3842a8c5a4e89628
new file mode 100644
index 0000000..2f7401a
--- /dev/null
+++ b/fuzzer/corpus/bf9a9a089dc3155f5bd73ecb3842a8c5a4e89628
Binary files differ
diff --git a/fuzzer/corpus/bf9bdc5e37e1191c1006cc17edb9c2491e136797 b/fuzzer/corpus/bf9bdc5e37e1191c1006cc17edb9c2491e136797
new file mode 100644
index 0000000..b9a3dca
--- /dev/null
+++ b/fuzzer/corpus/bf9bdc5e37e1191c1006cc17edb9c2491e136797
Binary files differ
diff --git a/fuzzer/corpus/bfba791d6de2cb64a2fa5f88adc0b929f943747a b/fuzzer/corpus/bfba791d6de2cb64a2fa5f88adc0b929f943747a
new file mode 100644
index 0000000..f17a59b
--- /dev/null
+++ b/fuzzer/corpus/bfba791d6de2cb64a2fa5f88adc0b929f943747a
Binary files differ
diff --git a/fuzzer/corpus/bfcd9d6c1d8af57796c496e7474d230683d57aa0 b/fuzzer/corpus/bfcd9d6c1d8af57796c496e7474d230683d57aa0
new file mode 100644
index 0000000..6ec7c2a
--- /dev/null
+++ b/fuzzer/corpus/bfcd9d6c1d8af57796c496e7474d230683d57aa0
Binary files differ
diff --git a/fuzzer/corpus/bfe684ae2803f6dbfabf51657fb81687ec0af29e b/fuzzer/corpus/bfe684ae2803f6dbfabf51657fb81687ec0af29e
new file mode 100644
index 0000000..5eba99b
--- /dev/null
+++ b/fuzzer/corpus/bfe684ae2803f6dbfabf51657fb81687ec0af29e
Binary files differ
diff --git a/fuzzer/corpus/bfe71e8415c95c9697989f224bc1f7ab94f4316a b/fuzzer/corpus/bfe71e8415c95c9697989f224bc1f7ab94f4316a
new file mode 100644
index 0000000..c112854
--- /dev/null
+++ b/fuzzer/corpus/bfe71e8415c95c9697989f224bc1f7ab94f4316a
Binary files differ
diff --git a/fuzzer/corpus/c036de3b12eebd08719e83ba015d7fc81e6c956a b/fuzzer/corpus/c036de3b12eebd08719e83ba015d7fc81e6c956a
new file mode 100644
index 0000000..21aeb70
--- /dev/null
+++ b/fuzzer/corpus/c036de3b12eebd08719e83ba015d7fc81e6c956a
Binary files differ
diff --git a/fuzzer/corpus/c07f0071eb62d96cd63402853d07efb5b655fd0a b/fuzzer/corpus/c07f0071eb62d96cd63402853d07efb5b655fd0a
new file mode 100644
index 0000000..8345542
--- /dev/null
+++ b/fuzzer/corpus/c07f0071eb62d96cd63402853d07efb5b655fd0a
Binary files differ
diff --git a/fuzzer/corpus/c09d173f9ae068a42da028e60732bf0a70fe0fbd b/fuzzer/corpus/c09d173f9ae068a42da028e60732bf0a70fe0fbd
new file mode 100644
index 0000000..cfde2dc
--- /dev/null
+++ b/fuzzer/corpus/c09d173f9ae068a42da028e60732bf0a70fe0fbd
Binary files differ
diff --git a/fuzzer/corpus/c0f465088ec83d7c198850e7fe238beff5758588 b/fuzzer/corpus/c0f465088ec83d7c198850e7fe238beff5758588
new file mode 100644
index 0000000..4331001
--- /dev/null
+++ b/fuzzer/corpus/c0f465088ec83d7c198850e7fe238beff5758588
Binary files differ
diff --git a/fuzzer/corpus/c1069a65f457437affe1cd0900ca119211db2feb b/fuzzer/corpus/c1069a65f457437affe1cd0900ca119211db2feb
new file mode 100644
index 0000000..8f88d22
--- /dev/null
+++ b/fuzzer/corpus/c1069a65f457437affe1cd0900ca119211db2feb
Binary files differ
diff --git a/fuzzer/corpus/c11237425901fcc25154dedff96ffed3192ceadf b/fuzzer/corpus/c11237425901fcc25154dedff96ffed3192ceadf
new file mode 100644
index 0000000..bd28ca2
--- /dev/null
+++ b/fuzzer/corpus/c11237425901fcc25154dedff96ffed3192ceadf
Binary files differ
diff --git a/fuzzer/corpus/c12b91ee3a68f8296535c561809d067cc09527e3 b/fuzzer/corpus/c12b91ee3a68f8296535c561809d067cc09527e3
new file mode 100644
index 0000000..ee19d7f
--- /dev/null
+++ b/fuzzer/corpus/c12b91ee3a68f8296535c561809d067cc09527e3
Binary files differ
diff --git a/fuzzer/corpus/c1411b630bd7e3aa596b3a40e4e946abc4af88c1 b/fuzzer/corpus/c1411b630bd7e3aa596b3a40e4e946abc4af88c1
new file mode 100644
index 0000000..6bae414
--- /dev/null
+++ b/fuzzer/corpus/c1411b630bd7e3aa596b3a40e4e946abc4af88c1
Binary files differ
diff --git a/fuzzer/corpus/c16d3c8afbc3ca83624683d8c7e1492b5c907a31 b/fuzzer/corpus/c16d3c8afbc3ca83624683d8c7e1492b5c907a31
new file mode 100644
index 0000000..2ded83e
--- /dev/null
+++ b/fuzzer/corpus/c16d3c8afbc3ca83624683d8c7e1492b5c907a31
Binary files differ
diff --git a/fuzzer/corpus/c1e3907ee03b769749f19ab00cb28bf33e99ab09 b/fuzzer/corpus/c1e3907ee03b769749f19ab00cb28bf33e99ab09
new file mode 100644
index 0000000..09479d3
--- /dev/null
+++ b/fuzzer/corpus/c1e3907ee03b769749f19ab00cb28bf33e99ab09
Binary files differ
diff --git a/fuzzer/corpus/c1e89aa3e73fe909f61617bdbf43763597ad6fc3 b/fuzzer/corpus/c1e89aa3e73fe909f61617bdbf43763597ad6fc3
new file mode 100644
index 0000000..f072358
--- /dev/null
+++ b/fuzzer/corpus/c1e89aa3e73fe909f61617bdbf43763597ad6fc3
Binary files differ
diff --git a/fuzzer/corpus/c1eb459cd03d0a4d03e31106551c69ca97124b55 b/fuzzer/corpus/c1eb459cd03d0a4d03e31106551c69ca97124b55
new file mode 100644
index 0000000..b9ef5b9
--- /dev/null
+++ b/fuzzer/corpus/c1eb459cd03d0a4d03e31106551c69ca97124b55
Binary files differ
diff --git a/fuzzer/corpus/c1f3859559112f6c32c58d32232fddfdb526b922 b/fuzzer/corpus/c1f3859559112f6c32c58d32232fddfdb526b922
new file mode 100644
index 0000000..0a236e5
--- /dev/null
+++ b/fuzzer/corpus/c1f3859559112f6c32c58d32232fddfdb526b922
Binary files differ
diff --git a/fuzzer/corpus/c1f52c21de300b53a2e0c8d9d6545e0905698fa1 b/fuzzer/corpus/c1f52c21de300b53a2e0c8d9d6545e0905698fa1
new file mode 100644
index 0000000..5631829
--- /dev/null
+++ b/fuzzer/corpus/c1f52c21de300b53a2e0c8d9d6545e0905698fa1
Binary files differ
diff --git a/fuzzer/corpus/c203db055a500681a923313c2b92bc79e575526f b/fuzzer/corpus/c203db055a500681a923313c2b92bc79e575526f
new file mode 100644
index 0000000..0552b83
--- /dev/null
+++ b/fuzzer/corpus/c203db055a500681a923313c2b92bc79e575526f
Binary files differ
diff --git a/fuzzer/corpus/c22794f9f42f6280db779bc63a9ebe9c43bbce05 b/fuzzer/corpus/c22794f9f42f6280db779bc63a9ebe9c43bbce05
new file mode 100644
index 0000000..841aca6
--- /dev/null
+++ b/fuzzer/corpus/c22794f9f42f6280db779bc63a9ebe9c43bbce05
@@ -0,0 +1 @@
+s_0i
\ No newline at end of file
diff --git a/fuzzer/corpus/c2759a503427d4ffd8e1723afe56d2bdba100dc4 b/fuzzer/corpus/c2759a503427d4ffd8e1723afe56d2bdba100dc4
new file mode 100644
index 0000000..c2dbbe3
--- /dev/null
+++ b/fuzzer/corpus/c2759a503427d4ffd8e1723afe56d2bdba100dc4
Binary files differ
diff --git a/fuzzer/corpus/c278dfba9bfd8a3e0495a5f72e350174e1192888 b/fuzzer/corpus/c278dfba9bfd8a3e0495a5f72e350174e1192888
new file mode 100644
index 0000000..070f41e
--- /dev/null
+++ b/fuzzer/corpus/c278dfba9bfd8a3e0495a5f72e350174e1192888
Binary files differ
diff --git a/fuzzer/corpus/c285127a1a0b809aa3102e31a09c62c42c0d7631 b/fuzzer/corpus/c285127a1a0b809aa3102e31a09c62c42c0d7631
new file mode 100644
index 0000000..21e8aed
--- /dev/null
+++ b/fuzzer/corpus/c285127a1a0b809aa3102e31a09c62c42c0d7631
Binary files differ
diff --git a/fuzzer/corpus/c28e7cd1d2bb18d686da20b8f435c76a2e673a26 b/fuzzer/corpus/c28e7cd1d2bb18d686da20b8f435c76a2e673a26
new file mode 100644
index 0000000..b724a80
--- /dev/null
+++ b/fuzzer/corpus/c28e7cd1d2bb18d686da20b8f435c76a2e673a26
Binary files differ
diff --git a/fuzzer/corpus/c28f4fed438bfafe7306966c35cb77a6bab3f91b b/fuzzer/corpus/c28f4fed438bfafe7306966c35cb77a6bab3f91b
new file mode 100644
index 0000000..0319998
--- /dev/null
+++ b/fuzzer/corpus/c28f4fed438bfafe7306966c35cb77a6bab3f91b
Binary files differ
diff --git a/fuzzer/corpus/c2992980283a52be70113fb7f1277f9e2737f7d2 b/fuzzer/corpus/c2992980283a52be70113fb7f1277f9e2737f7d2
new file mode 100644
index 0000000..a50d184
--- /dev/null
+++ b/fuzzer/corpus/c2992980283a52be70113fb7f1277f9e2737f7d2
Binary files differ
diff --git a/fuzzer/corpus/c2a3722505d7fc1e1743e3b8c3da664b9e4ffdfa b/fuzzer/corpus/c2a3722505d7fc1e1743e3b8c3da664b9e4ffdfa
new file mode 100644
index 0000000..706e054
--- /dev/null
+++ b/fuzzer/corpus/c2a3722505d7fc1e1743e3b8c3da664b9e4ffdfa
Binary files differ
diff --git a/fuzzer/corpus/c2b7aa8e50612547e24dae560cb4cfc8653e64e8 b/fuzzer/corpus/c2b7aa8e50612547e24dae560cb4cfc8653e64e8
new file mode 100644
index 0000000..f828019
--- /dev/null
+++ b/fuzzer/corpus/c2b7aa8e50612547e24dae560cb4cfc8653e64e8
Binary files differ
diff --git a/fuzzer/corpus/c2cea58f238f9bf8c11a992a370998bd463e00b6 b/fuzzer/corpus/c2cea58f238f9bf8c11a992a370998bd463e00b6
new file mode 100644
index 0000000..7eea98b
--- /dev/null
+++ b/fuzzer/corpus/c2cea58f238f9bf8c11a992a370998bd463e00b6
Binary files differ
diff --git a/fuzzer/corpus/c2daed9a16520ef15a7fea26a5281386fac26c09 b/fuzzer/corpus/c2daed9a16520ef15a7fea26a5281386fac26c09
new file mode 100644
index 0000000..3053069
--- /dev/null
+++ b/fuzzer/corpus/c2daed9a16520ef15a7fea26a5281386fac26c09
Binary files differ
diff --git a/fuzzer/corpus/c2eeeecf81dc9b7041495009b1211f6a3cf63300 b/fuzzer/corpus/c2eeeecf81dc9b7041495009b1211f6a3cf63300
new file mode 100644
index 0000000..773938c
--- /dev/null
+++ b/fuzzer/corpus/c2eeeecf81dc9b7041495009b1211f6a3cf63300
Binary files differ
diff --git a/fuzzer/corpus/c320ebce64164499243bcadf7d3fbdc048658e37 b/fuzzer/corpus/c320ebce64164499243bcadf7d3fbdc048658e37
new file mode 100644
index 0000000..659605c
--- /dev/null
+++ b/fuzzer/corpus/c320ebce64164499243bcadf7d3fbdc048658e37
Binary files differ
diff --git a/fuzzer/corpus/c3502c0c149c2d815caeb5887b505a00bd8cc3e1 b/fuzzer/corpus/c3502c0c149c2d815caeb5887b505a00bd8cc3e1
new file mode 100644
index 0000000..281c2dc
--- /dev/null
+++ b/fuzzer/corpus/c3502c0c149c2d815caeb5887b505a00bd8cc3e1
Binary files differ
diff --git a/fuzzer/corpus/c35db0e03cf5ceb983298ecf8e7f43f651b4b058 b/fuzzer/corpus/c35db0e03cf5ceb983298ecf8e7f43f651b4b058
new file mode 100644
index 0000000..aca3104
--- /dev/null
+++ b/fuzzer/corpus/c35db0e03cf5ceb983298ecf8e7f43f651b4b058
Binary files differ
diff --git a/fuzzer/corpus/c373e20971c91af94c6ad258f0261fc21037a3af b/fuzzer/corpus/c373e20971c91af94c6ad258f0261fc21037a3af
new file mode 100644
index 0000000..46c10fe
--- /dev/null
+++ b/fuzzer/corpus/c373e20971c91af94c6ad258f0261fc21037a3af
Binary files differ
diff --git a/fuzzer/corpus/c37fdda0a01bc6bdb2850a750eee373338e5c40c b/fuzzer/corpus/c37fdda0a01bc6bdb2850a750eee373338e5c40c
new file mode 100644
index 0000000..6071cab
--- /dev/null
+++ b/fuzzer/corpus/c37fdda0a01bc6bdb2850a750eee373338e5c40c
Binary files differ
diff --git a/fuzzer/corpus/c39d08faf1a141c5c7a3cb2aefa623339b2579b8 b/fuzzer/corpus/c39d08faf1a141c5c7a3cb2aefa623339b2579b8
new file mode 100644
index 0000000..7c8617b
--- /dev/null
+++ b/fuzzer/corpus/c39d08faf1a141c5c7a3cb2aefa623339b2579b8
Binary files differ
diff --git a/fuzzer/corpus/c39f87156cfc35ed4440508caa05c4c3f956bc59 b/fuzzer/corpus/c39f87156cfc35ed4440508caa05c4c3f956bc59
new file mode 100644
index 0000000..a4c0900
--- /dev/null
+++ b/fuzzer/corpus/c39f87156cfc35ed4440508caa05c4c3f956bc59
Binary files differ
diff --git a/fuzzer/corpus/c3cca12bb9769a8a49bda58e3f111a7061fedb3c b/fuzzer/corpus/c3cca12bb9769a8a49bda58e3f111a7061fedb3c
new file mode 100644
index 0000000..dd14ae2
--- /dev/null
+++ b/fuzzer/corpus/c3cca12bb9769a8a49bda58e3f111a7061fedb3c
Binary files differ
diff --git a/fuzzer/corpus/c3f12d7f35d7d17a1c105547ed8800ff4a769490 b/fuzzer/corpus/c3f12d7f35d7d17a1c105547ed8800ff4a769490
new file mode 100644
index 0000000..99eac7a
--- /dev/null
+++ b/fuzzer/corpus/c3f12d7f35d7d17a1c105547ed8800ff4a769490
Binary files differ
diff --git a/fuzzer/corpus/c406d3bb7e6b5ad45ea5ecf4dadfec39b6ab83db b/fuzzer/corpus/c406d3bb7e6b5ad45ea5ecf4dadfec39b6ab83db
new file mode 100644
index 0000000..d5a9a36
--- /dev/null
+++ b/fuzzer/corpus/c406d3bb7e6b5ad45ea5ecf4dadfec39b6ab83db
Binary files differ
diff --git a/fuzzer/corpus/c4968ca50dce7eafd827b705c86a3c8c243c31d9 b/fuzzer/corpus/c4968ca50dce7eafd827b705c86a3c8c243c31d9
new file mode 100644
index 0000000..46f4c77
--- /dev/null
+++ b/fuzzer/corpus/c4968ca50dce7eafd827b705c86a3c8c243c31d9
Binary files differ
diff --git a/fuzzer/corpus/c4a194108fb7ab614960baa527ee628537d95c9c b/fuzzer/corpus/c4a194108fb7ab614960baa527ee628537d95c9c
new file mode 100644
index 0000000..50f7548
--- /dev/null
+++ b/fuzzer/corpus/c4a194108fb7ab614960baa527ee628537d95c9c
Binary files differ
diff --git a/fuzzer/corpus/c4b037bf36b8a8e329e1076545f13ccc01f26cce b/fuzzer/corpus/c4b037bf36b8a8e329e1076545f13ccc01f26cce
new file mode 100644
index 0000000..8332b2f
--- /dev/null
+++ b/fuzzer/corpus/c4b037bf36b8a8e329e1076545f13ccc01f26cce
Binary files differ
diff --git a/fuzzer/corpus/c4c6a62291252abcd228ce97cbe438eea026ea4c b/fuzzer/corpus/c4c6a62291252abcd228ce97cbe438eea026ea4c
new file mode 100644
index 0000000..9184a4d
--- /dev/null
+++ b/fuzzer/corpus/c4c6a62291252abcd228ce97cbe438eea026ea4c
Binary files differ
diff --git a/fuzzer/corpus/c4c9912ea6b2374c13c0ace6976f2f5f699ffc43 b/fuzzer/corpus/c4c9912ea6b2374c13c0ace6976f2f5f699ffc43
new file mode 100644
index 0000000..fa42023
--- /dev/null
+++ b/fuzzer/corpus/c4c9912ea6b2374c13c0ace6976f2f5f699ffc43
Binary files differ
diff --git a/fuzzer/corpus/c4cc17ce9208d1f2d50d74e06fc26da26c948a80 b/fuzzer/corpus/c4cc17ce9208d1f2d50d74e06fc26da26c948a80
new file mode 100644
index 0000000..11d6634
--- /dev/null
+++ b/fuzzer/corpus/c4cc17ce9208d1f2d50d74e06fc26da26c948a80
Binary files differ
diff --git a/fuzzer/corpus/c4e3b28572a3afa7a379f3267cdab64561948efc b/fuzzer/corpus/c4e3b28572a3afa7a379f3267cdab64561948efc
new file mode 100644
index 0000000..ce51884
--- /dev/null
+++ b/fuzzer/corpus/c4e3b28572a3afa7a379f3267cdab64561948efc
Binary files differ
diff --git a/fuzzer/corpus/c4f4c8c8a72b8786f036463efbea8cf93362402a b/fuzzer/corpus/c4f4c8c8a72b8786f036463efbea8cf93362402a
new file mode 100644
index 0000000..ac2c3a6
--- /dev/null
+++ b/fuzzer/corpus/c4f4c8c8a72b8786f036463efbea8cf93362402a
Binary files differ
diff --git a/fuzzer/corpus/c56253ae481518c118362e32bacb8e589583ed45 b/fuzzer/corpus/c56253ae481518c118362e32bacb8e589583ed45
new file mode 100644
index 0000000..9fa2984
--- /dev/null
+++ b/fuzzer/corpus/c56253ae481518c118362e32bacb8e589583ed45
Binary files differ
diff --git a/fuzzer/corpus/c5664724fffb21fe4aaedcc2f4cccb7c734baf74 b/fuzzer/corpus/c5664724fffb21fe4aaedcc2f4cccb7c734baf74
new file mode 100644
index 0000000..50503d4
--- /dev/null
+++ b/fuzzer/corpus/c5664724fffb21fe4aaedcc2f4cccb7c734baf74
Binary files differ
diff --git a/fuzzer/corpus/c56be33619e05333c72cd6a96122f506495baa3a b/fuzzer/corpus/c56be33619e05333c72cd6a96122f506495baa3a
new file mode 100644
index 0000000..2e4abc7
--- /dev/null
+++ b/fuzzer/corpus/c56be33619e05333c72cd6a96122f506495baa3a
Binary files differ
diff --git a/fuzzer/corpus/c5be0bd184229bcdc209d38b7717c203d540b609 b/fuzzer/corpus/c5be0bd184229bcdc209d38b7717c203d540b609
new file mode 100644
index 0000000..528d6e9
--- /dev/null
+++ b/fuzzer/corpus/c5be0bd184229bcdc209d38b7717c203d540b609
Binary files differ
diff --git a/fuzzer/corpus/c5c5c5329c41fc7d9e10875ae471e95a1d25000b b/fuzzer/corpus/c5c5c5329c41fc7d9e10875ae471e95a1d25000b
new file mode 100644
index 0000000..fa8856b
--- /dev/null
+++ b/fuzzer/corpus/c5c5c5329c41fc7d9e10875ae471e95a1d25000b
Binary files differ
diff --git a/fuzzer/corpus/c5dadfb7466af003759276ad3a4db2a31bd3a1f8 b/fuzzer/corpus/c5dadfb7466af003759276ad3a4db2a31bd3a1f8
new file mode 100644
index 0000000..31928ed
--- /dev/null
+++ b/fuzzer/corpus/c5dadfb7466af003759276ad3a4db2a31bd3a1f8
Binary files differ
diff --git a/fuzzer/corpus/c5e792503fa363e620df0ff1d53c1047a89a7854 b/fuzzer/corpus/c5e792503fa363e620df0ff1d53c1047a89a7854
new file mode 100644
index 0000000..3b0d1e4
--- /dev/null
+++ b/fuzzer/corpus/c5e792503fa363e620df0ff1d53c1047a89a7854
Binary files differ
diff --git a/fuzzer/corpus/c6092d37ed02088b0cf87d5a056aeff5f73afe60 b/fuzzer/corpus/c6092d37ed02088b0cf87d5a056aeff5f73afe60
new file mode 100644
index 0000000..f13caab
--- /dev/null
+++ b/fuzzer/corpus/c6092d37ed02088b0cf87d5a056aeff5f73afe60
Binary files differ
diff --git a/fuzzer/corpus/c612595448af7cbec999dea23dfc8027c85f5a24 b/fuzzer/corpus/c612595448af7cbec999dea23dfc8027c85f5a24
new file mode 100644
index 0000000..3c3f405
--- /dev/null
+++ b/fuzzer/corpus/c612595448af7cbec999dea23dfc8027c85f5a24
Binary files differ
diff --git a/fuzzer/corpus/c624a46979fc72671616c7a7a3b0af43a85b2d81 b/fuzzer/corpus/c624a46979fc72671616c7a7a3b0af43a85b2d81
new file mode 100644
index 0000000..934461b
--- /dev/null
+++ b/fuzzer/corpus/c624a46979fc72671616c7a7a3b0af43a85b2d81
Binary files differ
diff --git a/fuzzer/corpus/c6274846e4c681ba7c78592e01ce0491d486f286 b/fuzzer/corpus/c6274846e4c681ba7c78592e01ce0491d486f286
new file mode 100644
index 0000000..d5a762f
--- /dev/null
+++ b/fuzzer/corpus/c6274846e4c681ba7c78592e01ce0491d486f286
Binary files differ
diff --git a/fuzzer/corpus/c654b0d1ff308db5f6fbac10f1dbeb4a8b07ae8c b/fuzzer/corpus/c654b0d1ff308db5f6fbac10f1dbeb4a8b07ae8c
new file mode 100644
index 0000000..fb18600
--- /dev/null
+++ b/fuzzer/corpus/c654b0d1ff308db5f6fbac10f1dbeb4a8b07ae8c
Binary files differ
diff --git a/fuzzer/corpus/c65b95b4755c50f2cada1929690bece4316280e8 b/fuzzer/corpus/c65b95b4755c50f2cada1929690bece4316280e8
new file mode 100644
index 0000000..e88247b
--- /dev/null
+++ b/fuzzer/corpus/c65b95b4755c50f2cada1929690bece4316280e8
Binary files differ
diff --git a/fuzzer/corpus/c65d8988d02b26bc78043e664687663fbd060f7d b/fuzzer/corpus/c65d8988d02b26bc78043e664687663fbd060f7d
new file mode 100644
index 0000000..230140c
--- /dev/null
+++ b/fuzzer/corpus/c65d8988d02b26bc78043e664687663fbd060f7d
Binary files differ
diff --git a/fuzzer/corpus/c6711df234f649cdf74052665e6ab184f3bbe151 b/fuzzer/corpus/c6711df234f649cdf74052665e6ab184f3bbe151
new file mode 100644
index 0000000..8213d00
--- /dev/null
+++ b/fuzzer/corpus/c6711df234f649cdf74052665e6ab184f3bbe151
Binary files differ
diff --git a/fuzzer/corpus/c67285c5c3b640ae2064eb61661049d8b178660b b/fuzzer/corpus/c67285c5c3b640ae2064eb61661049d8b178660b
new file mode 100644
index 0000000..f23d71a
--- /dev/null
+++ b/fuzzer/corpus/c67285c5c3b640ae2064eb61661049d8b178660b
Binary files differ
diff --git a/fuzzer/corpus/c691cddd4168a6eb89aa72a640dac1458970518e b/fuzzer/corpus/c691cddd4168a6eb89aa72a640dac1458970518e
new file mode 100644
index 0000000..5f8a9ce
--- /dev/null
+++ b/fuzzer/corpus/c691cddd4168a6eb89aa72a640dac1458970518e
Binary files differ
diff --git a/fuzzer/corpus/c6996110092ddf633c57a9da68804f1fb0253ba7 b/fuzzer/corpus/c6996110092ddf633c57a9da68804f1fb0253ba7
new file mode 100644
index 0000000..3d16d46
--- /dev/null
+++ b/fuzzer/corpus/c6996110092ddf633c57a9da68804f1fb0253ba7
Binary files differ
diff --git a/fuzzer/corpus/c69be3fa3872e7cc34ea0cb72fc18c88a811a9c1 b/fuzzer/corpus/c69be3fa3872e7cc34ea0cb72fc18c88a811a9c1
new file mode 100644
index 0000000..115def0
--- /dev/null
+++ b/fuzzer/corpus/c69be3fa3872e7cc34ea0cb72fc18c88a811a9c1
Binary files differ
diff --git a/fuzzer/corpus/c6a571ce5c35b68b82a4c6767fc11a9d49154a2d b/fuzzer/corpus/c6a571ce5c35b68b82a4c6767fc11a9d49154a2d
new file mode 100644
index 0000000..e9a60d7
--- /dev/null
+++ b/fuzzer/corpus/c6a571ce5c35b68b82a4c6767fc11a9d49154a2d
Binary files differ
diff --git a/fuzzer/corpus/c6b069d2342f2357cc7f61532e8a3560a6723204 b/fuzzer/corpus/c6b069d2342f2357cc7f61532e8a3560a6723204
new file mode 100644
index 0000000..25a8ea0
--- /dev/null
+++ b/fuzzer/corpus/c6b069d2342f2357cc7f61532e8a3560a6723204
Binary files differ
diff --git a/fuzzer/corpus/c6c9c1f975551eeaab2ff3e5519f723a75494078 b/fuzzer/corpus/c6c9c1f975551eeaab2ff3e5519f723a75494078
new file mode 100644
index 0000000..efdfd7c
--- /dev/null
+++ b/fuzzer/corpus/c6c9c1f975551eeaab2ff3e5519f723a75494078
Binary files differ
diff --git a/fuzzer/corpus/c6e510c7b2921decc4755387eb6ca4fcfdaf07f8 b/fuzzer/corpus/c6e510c7b2921decc4755387eb6ca4fcfdaf07f8
new file mode 100644
index 0000000..223cc8f
--- /dev/null
+++ b/fuzzer/corpus/c6e510c7b2921decc4755387eb6ca4fcfdaf07f8
Binary files differ
diff --git a/fuzzer/corpus/c706d9f94f4e3d4b1c1e9c98962ed77d6537c54d b/fuzzer/corpus/c706d9f94f4e3d4b1c1e9c98962ed77d6537c54d
new file mode 100644
index 0000000..81be723
--- /dev/null
+++ b/fuzzer/corpus/c706d9f94f4e3d4b1c1e9c98962ed77d6537c54d
Binary files differ
diff --git a/fuzzer/corpus/c70a79cd3fdc7fee7c7b2d96b65a4678e29fa657 b/fuzzer/corpus/c70a79cd3fdc7fee7c7b2d96b65a4678e29fa657
new file mode 100644
index 0000000..c89bebd
--- /dev/null
+++ b/fuzzer/corpus/c70a79cd3fdc7fee7c7b2d96b65a4678e29fa657
Binary files differ
diff --git a/fuzzer/corpus/c72a2338bf5493bf10a0047f00aea94d7a10dcd0 b/fuzzer/corpus/c72a2338bf5493bf10a0047f00aea94d7a10dcd0
new file mode 100644
index 0000000..52ca0b8
--- /dev/null
+++ b/fuzzer/corpus/c72a2338bf5493bf10a0047f00aea94d7a10dcd0
Binary files differ
diff --git a/fuzzer/corpus/c72abe9f4196721dcb62adf662bb7df1b99023a3 b/fuzzer/corpus/c72abe9f4196721dcb62adf662bb7df1b99023a3
new file mode 100644
index 0000000..00bb0be
--- /dev/null
+++ b/fuzzer/corpus/c72abe9f4196721dcb62adf662bb7df1b99023a3
Binary files differ
diff --git a/fuzzer/corpus/c7416348fec1d098c05d0c807753cb378433d70d b/fuzzer/corpus/c7416348fec1d098c05d0c807753cb378433d70d
new file mode 100644
index 0000000..e63dcfb
--- /dev/null
+++ b/fuzzer/corpus/c7416348fec1d098c05d0c807753cb378433d70d
Binary files differ
diff --git a/fuzzer/corpus/c74fce558990731d1b6c4bc112d124e4b4be76b4 b/fuzzer/corpus/c74fce558990731d1b6c4bc112d124e4b4be76b4
new file mode 100644
index 0000000..28d4820
--- /dev/null
+++ b/fuzzer/corpus/c74fce558990731d1b6c4bc112d124e4b4be76b4
Binary files differ
diff --git a/fuzzer/corpus/c758ec9fa65a245017a4cbb6e0b81b05d62920cc b/fuzzer/corpus/c758ec9fa65a245017a4cbb6e0b81b05d62920cc
new file mode 100644
index 0000000..bc7c5b4
--- /dev/null
+++ b/fuzzer/corpus/c758ec9fa65a245017a4cbb6e0b81b05d62920cc
Binary files differ
diff --git a/fuzzer/corpus/c7706f33b8ea531644b84641cc9f830572b4df89 b/fuzzer/corpus/c7706f33b8ea531644b84641cc9f830572b4df89
new file mode 100644
index 0000000..4407f47
--- /dev/null
+++ b/fuzzer/corpus/c7706f33b8ea531644b84641cc9f830572b4df89
Binary files differ
diff --git a/fuzzer/corpus/c778f53511dcd17e8bf0d4d445a399301e33de92 b/fuzzer/corpus/c778f53511dcd17e8bf0d4d445a399301e33de92
new file mode 100644
index 0000000..61baeac
--- /dev/null
+++ b/fuzzer/corpus/c778f53511dcd17e8bf0d4d445a399301e33de92
Binary files differ
diff --git a/fuzzer/corpus/c78cfaf4ce942c3806ee9e47c1ba3b36b978560a b/fuzzer/corpus/c78cfaf4ce942c3806ee9e47c1ba3b36b978560a
new file mode 100644
index 0000000..7b268f3
--- /dev/null
+++ b/fuzzer/corpus/c78cfaf4ce942c3806ee9e47c1ba3b36b978560a
Binary files differ
diff --git a/fuzzer/corpus/c79e9bc3125722cf4f5de6e03f8ab1f46644e9cc b/fuzzer/corpus/c79e9bc3125722cf4f5de6e03f8ab1f46644e9cc
new file mode 100644
index 0000000..7779ceb
--- /dev/null
+++ b/fuzzer/corpus/c79e9bc3125722cf4f5de6e03f8ab1f46644e9cc
Binary files differ
diff --git a/fuzzer/corpus/c79fcc7f3f545c0943c2817b6b11110d61c79a27 b/fuzzer/corpus/c79fcc7f3f545c0943c2817b6b11110d61c79a27
new file mode 100644
index 0000000..955bdda
--- /dev/null
+++ b/fuzzer/corpus/c79fcc7f3f545c0943c2817b6b11110d61c79a27
Binary files differ
diff --git a/fuzzer/corpus/c7aae761a287af4a79aa68e660f69f433879e0f3 b/fuzzer/corpus/c7aae761a287af4a79aa68e660f69f433879e0f3
new file mode 100644
index 0000000..82f0439
--- /dev/null
+++ b/fuzzer/corpus/c7aae761a287af4a79aa68e660f69f433879e0f3
Binary files differ
diff --git a/fuzzer/corpus/c7e54dcee056c6deaf8fa3ba0e1ef7bafffb680f b/fuzzer/corpus/c7e54dcee056c6deaf8fa3ba0e1ef7bafffb680f
new file mode 100644
index 0000000..7db6549
--- /dev/null
+++ b/fuzzer/corpus/c7e54dcee056c6deaf8fa3ba0e1ef7bafffb680f
Binary files differ
diff --git a/fuzzer/corpus/c7fd8a6586fbe6e3e5127700514262d5289d2e0a b/fuzzer/corpus/c7fd8a6586fbe6e3e5127700514262d5289d2e0a
new file mode 100644
index 0000000..807be6a
--- /dev/null
+++ b/fuzzer/corpus/c7fd8a6586fbe6e3e5127700514262d5289d2e0a
Binary files differ
diff --git a/fuzzer/corpus/c87fffd6bce59326050af06433afdeb5f56640b7 b/fuzzer/corpus/c87fffd6bce59326050af06433afdeb5f56640b7
new file mode 100644
index 0000000..847e812
--- /dev/null
+++ b/fuzzer/corpus/c87fffd6bce59326050af06433afdeb5f56640b7
Binary files differ
diff --git a/fuzzer/corpus/c885d4e934ded27b595be49adcb64a2ee930e1f6 b/fuzzer/corpus/c885d4e934ded27b595be49adcb64a2ee930e1f6
new file mode 100644
index 0000000..4488dc8
--- /dev/null
+++ b/fuzzer/corpus/c885d4e934ded27b595be49adcb64a2ee930e1f6
Binary files differ
diff --git a/fuzzer/corpus/c89fc8bec2aacd1960d1dcfb4f0af442f9031759 b/fuzzer/corpus/c89fc8bec2aacd1960d1dcfb4f0af442f9031759
new file mode 100644
index 0000000..2f6dde8
--- /dev/null
+++ b/fuzzer/corpus/c89fc8bec2aacd1960d1dcfb4f0af442f9031759
Binary files differ
diff --git a/fuzzer/corpus/c8a324c6f9e6acda5e9869e5346176cdd0ab146f b/fuzzer/corpus/c8a324c6f9e6acda5e9869e5346176cdd0ab146f
new file mode 100644
index 0000000..bad2aaa
--- /dev/null
+++ b/fuzzer/corpus/c8a324c6f9e6acda5e9869e5346176cdd0ab146f
@@ -0,0 +1 @@
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5i_0ÿÿÿÿÿÿÿÿÿÿÿ5i_i
\ No newline at end of file
diff --git a/fuzzer/corpus/c8c49640b501d957bce4df15bb613b69da71e96d b/fuzzer/corpus/c8c49640b501d957bce4df15bb613b69da71e96d
new file mode 100644
index 0000000..7b72cf1
--- /dev/null
+++ b/fuzzer/corpus/c8c49640b501d957bce4df15bb613b69da71e96d
Binary files differ
diff --git a/fuzzer/corpus/c8f6333fbf8e772ee2fc2831ef7286199320c315 b/fuzzer/corpus/c8f6333fbf8e772ee2fc2831ef7286199320c315
new file mode 100644
index 0000000..2ae8d74
--- /dev/null
+++ b/fuzzer/corpus/c8f6333fbf8e772ee2fc2831ef7286199320c315
Binary files differ
diff --git a/fuzzer/corpus/c8fc63056d32b214eeae41550e7c1e92532720ca b/fuzzer/corpus/c8fc63056d32b214eeae41550e7c1e92532720ca
new file mode 100644
index 0000000..6c69fcc
--- /dev/null
+++ b/fuzzer/corpus/c8fc63056d32b214eeae41550e7c1e92532720ca
Binary files differ
diff --git a/fuzzer/corpus/c92e26e8feb8075f32d63c887fccf53f801ae9db b/fuzzer/corpus/c92e26e8feb8075f32d63c887fccf53f801ae9db
new file mode 100644
index 0000000..4fa8f0a
--- /dev/null
+++ b/fuzzer/corpus/c92e26e8feb8075f32d63c887fccf53f801ae9db
Binary files differ
diff --git a/fuzzer/corpus/c96741ea1192395e90d2a86d5537ed6f20914df5 b/fuzzer/corpus/c96741ea1192395e90d2a86d5537ed6f20914df5
new file mode 100644
index 0000000..4a455f2
--- /dev/null
+++ b/fuzzer/corpus/c96741ea1192395e90d2a86d5537ed6f20914df5
Binary files differ
diff --git a/fuzzer/corpus/c982bed40242835ad29a8311f65792f5e27468b3 b/fuzzer/corpus/c982bed40242835ad29a8311f65792f5e27468b3
new file mode 100644
index 0000000..ba5b78c
--- /dev/null
+++ b/fuzzer/corpus/c982bed40242835ad29a8311f65792f5e27468b3
Binary files differ
diff --git a/fuzzer/corpus/c9e3994dd8c9fc3633edd9058ba0e891428b8fed b/fuzzer/corpus/c9e3994dd8c9fc3633edd9058ba0e891428b8fed
new file mode 100644
index 0000000..70559a6
--- /dev/null
+++ b/fuzzer/corpus/c9e3994dd8c9fc3633edd9058ba0e891428b8fed
Binary files differ
diff --git a/fuzzer/corpus/c9e5ef211a0d346179b4c57ea68a60bab5f055c4 b/fuzzer/corpus/c9e5ef211a0d346179b4c57ea68a60bab5f055c4
new file mode 100644
index 0000000..1857dfa
--- /dev/null
+++ b/fuzzer/corpus/c9e5ef211a0d346179b4c57ea68a60bab5f055c4
Binary files differ
diff --git a/fuzzer/corpus/ca11304a8c71477b12b246deebedb8e7a4377478 b/fuzzer/corpus/ca11304a8c71477b12b246deebedb8e7a4377478
new file mode 100644
index 0000000..7cabe2f
--- /dev/null
+++ b/fuzzer/corpus/ca11304a8c71477b12b246deebedb8e7a4377478
Binary files differ
diff --git a/fuzzer/corpus/ca1cd287450cf47cd3a5a32e1ec545d40b0f5222 b/fuzzer/corpus/ca1cd287450cf47cd3a5a32e1ec545d40b0f5222
new file mode 100644
index 0000000..e5d29c0
--- /dev/null
+++ b/fuzzer/corpus/ca1cd287450cf47cd3a5a32e1ec545d40b0f5222
Binary files differ
diff --git a/fuzzer/corpus/ca37a2f08915bd7a9ac1988b29887b10cb98cadb b/fuzzer/corpus/ca37a2f08915bd7a9ac1988b29887b10cb98cadb
new file mode 100644
index 0000000..efc2ba1
--- /dev/null
+++ b/fuzzer/corpus/ca37a2f08915bd7a9ac1988b29887b10cb98cadb
Binary files differ
diff --git a/fuzzer/corpus/ca54415b2181663aa978355ec72cf9435c4ccd8c b/fuzzer/corpus/ca54415b2181663aa978355ec72cf9435c4ccd8c
new file mode 100644
index 0000000..b893183
--- /dev/null
+++ b/fuzzer/corpus/ca54415b2181663aa978355ec72cf9435c4ccd8c
Binary files differ
diff --git a/fuzzer/corpus/ca9ba8fb49867faa4c26829869d2cf0b2d00a651 b/fuzzer/corpus/ca9ba8fb49867faa4c26829869d2cf0b2d00a651
new file mode 100644
index 0000000..fc1809b
--- /dev/null
+++ b/fuzzer/corpus/ca9ba8fb49867faa4c26829869d2cf0b2d00a651
Binary files differ
diff --git a/fuzzer/corpus/caa1a16a87c8cbf3931d8a34f84c3381635ed56f b/fuzzer/corpus/caa1a16a87c8cbf3931d8a34f84c3381635ed56f
new file mode 100644
index 0000000..ef7a4dd
--- /dev/null
+++ b/fuzzer/corpus/caa1a16a87c8cbf3931d8a34f84c3381635ed56f
Binary files differ
diff --git a/fuzzer/corpus/caa5305ca2de94339ed73515b7d3f75dd6847414 b/fuzzer/corpus/caa5305ca2de94339ed73515b7d3f75dd6847414
new file mode 100644
index 0000000..22221ad
--- /dev/null
+++ b/fuzzer/corpus/caa5305ca2de94339ed73515b7d3f75dd6847414
Binary files differ
diff --git a/fuzzer/corpus/caa7a34683fa73ce233b6b4969bcd0c414a2f764 b/fuzzer/corpus/caa7a34683fa73ce233b6b4969bcd0c414a2f764
new file mode 100644
index 0000000..c16ec43
--- /dev/null
+++ b/fuzzer/corpus/caa7a34683fa73ce233b6b4969bcd0c414a2f764
Binary files differ
diff --git a/fuzzer/corpus/cac0084ef7e39a66daf848b7e96e02f95524b40a b/fuzzer/corpus/cac0084ef7e39a66daf848b7e96e02f95524b40a
new file mode 100644
index 0000000..7edfd4b
--- /dev/null
+++ b/fuzzer/corpus/cac0084ef7e39a66daf848b7e96e02f95524b40a
Binary files differ
diff --git a/fuzzer/corpus/caed6aa4f3955e947b45532b8aa7a81e6c17a4d5 b/fuzzer/corpus/caed6aa4f3955e947b45532b8aa7a81e6c17a4d5
new file mode 100644
index 0000000..46e08dd
--- /dev/null
+++ b/fuzzer/corpus/caed6aa4f3955e947b45532b8aa7a81e6c17a4d5
Binary files differ
diff --git a/fuzzer/corpus/cb7a32fd05f4bc7254396a23aa29cbfda662181f b/fuzzer/corpus/cb7a32fd05f4bc7254396a23aa29cbfda662181f
new file mode 100644
index 0000000..2a1603a
--- /dev/null
+++ b/fuzzer/corpus/cb7a32fd05f4bc7254396a23aa29cbfda662181f
Binary files differ
diff --git a/fuzzer/corpus/cbd0717c174942743197b51f7013f4fddf04df6b b/fuzzer/corpus/cbd0717c174942743197b51f7013f4fddf04df6b
new file mode 100644
index 0000000..62e3c70
--- /dev/null
+++ b/fuzzer/corpus/cbd0717c174942743197b51f7013f4fddf04df6b
Binary files differ
diff --git a/fuzzer/corpus/cbe6344d0391e969f5cdb73426cb5b8752077068 b/fuzzer/corpus/cbe6344d0391e969f5cdb73426cb5b8752077068
new file mode 100644
index 0000000..7e29641
--- /dev/null
+++ b/fuzzer/corpus/cbe6344d0391e969f5cdb73426cb5b8752077068
Binary files differ
diff --git a/fuzzer/corpus/cc0fea9c65c25e831ca3f76bd867ece650c01e28 b/fuzzer/corpus/cc0fea9c65c25e831ca3f76bd867ece650c01e28
new file mode 100644
index 0000000..2e89392
--- /dev/null
+++ b/fuzzer/corpus/cc0fea9c65c25e831ca3f76bd867ece650c01e28
Binary files differ
diff --git a/fuzzer/corpus/cc27c11056cf4590bbfa72b498e2b350710c03d9 b/fuzzer/corpus/cc27c11056cf4590bbfa72b498e2b350710c03d9
new file mode 100644
index 0000000..45faa27
--- /dev/null
+++ b/fuzzer/corpus/cc27c11056cf4590bbfa72b498e2b350710c03d9
Binary files differ
diff --git a/fuzzer/corpus/cc38cb68a800702ebe89fdb081416f955ad55f0c b/fuzzer/corpus/cc38cb68a800702ebe89fdb081416f955ad55f0c
new file mode 100644
index 0000000..b000eee
--- /dev/null
+++ b/fuzzer/corpus/cc38cb68a800702ebe89fdb081416f955ad55f0c
Binary files differ
diff --git a/fuzzer/corpus/ccbbd4d4c034a0d57e04471466b739f2e146fa3d b/fuzzer/corpus/ccbbd4d4c034a0d57e04471466b739f2e146fa3d
new file mode 100644
index 0000000..ce61b98
--- /dev/null
+++ b/fuzzer/corpus/ccbbd4d4c034a0d57e04471466b739f2e146fa3d
Binary files differ
diff --git a/fuzzer/corpus/ccbef69d827dda8e68a70ac42670785e65366c1e b/fuzzer/corpus/ccbef69d827dda8e68a70ac42670785e65366c1e
new file mode 100644
index 0000000..a1f1b2b
--- /dev/null
+++ b/fuzzer/corpus/ccbef69d827dda8e68a70ac42670785e65366c1e
Binary files differ
diff --git a/fuzzer/corpus/cce4e6135b059ac313a5befed1dfd0b79f27324f b/fuzzer/corpus/cce4e6135b059ac313a5befed1dfd0b79f27324f
new file mode 100644
index 0000000..f69aa6a
--- /dev/null
+++ b/fuzzer/corpus/cce4e6135b059ac313a5befed1dfd0b79f27324f
Binary files differ
diff --git a/fuzzer/corpus/cd1f25c66282ecd98e8e6d3dea033c382522c7ad b/fuzzer/corpus/cd1f25c66282ecd98e8e6d3dea033c382522c7ad
new file mode 100644
index 0000000..a372578
--- /dev/null
+++ b/fuzzer/corpus/cd1f25c66282ecd98e8e6d3dea033c382522c7ad
Binary files differ
diff --git a/fuzzer/corpus/cd296a7d2baa3daf5d983f2cb30ad6ca3ce74df4 b/fuzzer/corpus/cd296a7d2baa3daf5d983f2cb30ad6ca3ce74df4
new file mode 100644
index 0000000..e079dd6
--- /dev/null
+++ b/fuzzer/corpus/cd296a7d2baa3daf5d983f2cb30ad6ca3ce74df4
Binary files differ
diff --git a/fuzzer/corpus/cd54a4b235bdc936ab4471bc34a2b74c7f782184 b/fuzzer/corpus/cd54a4b235bdc936ab4471bc34a2b74c7f782184
new file mode 100644
index 0000000..e7fa2b6
--- /dev/null
+++ b/fuzzer/corpus/cd54a4b235bdc936ab4471bc34a2b74c7f782184
Binary files differ
diff --git a/fuzzer/corpus/cd5ca368cd0a670971a45082c71f142700346747 b/fuzzer/corpus/cd5ca368cd0a670971a45082c71f142700346747
new file mode 100644
index 0000000..83f0a2f
--- /dev/null
+++ b/fuzzer/corpus/cd5ca368cd0a670971a45082c71f142700346747
Binary files differ
diff --git a/fuzzer/corpus/cd892915f092cfde339cf5ca9bd411b2b9497e1a b/fuzzer/corpus/cd892915f092cfde339cf5ca9bd411b2b9497e1a
new file mode 100644
index 0000000..30557b5
--- /dev/null
+++ b/fuzzer/corpus/cd892915f092cfde339cf5ca9bd411b2b9497e1a
Binary files differ
diff --git a/fuzzer/corpus/cd9d7abb0418ac92ae0f529c4d9e7d420da14b50 b/fuzzer/corpus/cd9d7abb0418ac92ae0f529c4d9e7d420da14b50
new file mode 100644
index 0000000..1f8ad8f
--- /dev/null
+++ b/fuzzer/corpus/cd9d7abb0418ac92ae0f529c4d9e7d420da14b50
Binary files differ
diff --git a/fuzzer/corpus/cdb0f7126374d95a4155cbec6f1740a727aff666 b/fuzzer/corpus/cdb0f7126374d95a4155cbec6f1740a727aff666
new file mode 100644
index 0000000..8e6e957
--- /dev/null
+++ b/fuzzer/corpus/cdb0f7126374d95a4155cbec6f1740a727aff666
Binary files differ
diff --git a/fuzzer/corpus/cdbccfd8ea91e5f44c13e7aebc6498b424145121 b/fuzzer/corpus/cdbccfd8ea91e5f44c13e7aebc6498b424145121
new file mode 100644
index 0000000..a137507
--- /dev/null
+++ b/fuzzer/corpus/cdbccfd8ea91e5f44c13e7aebc6498b424145121
Binary files differ
diff --git a/fuzzer/corpus/cdcc248525d2c629b83f5a815d7daa05105e44a2 b/fuzzer/corpus/cdcc248525d2c629b83f5a815d7daa05105e44a2
new file mode 100644
index 0000000..f1d837e
--- /dev/null
+++ b/fuzzer/corpus/cdcc248525d2c629b83f5a815d7daa05105e44a2
Binary files differ
diff --git a/fuzzer/corpus/cdcef0781a108edea5523dff574b7d2257c36b81 b/fuzzer/corpus/cdcef0781a108edea5523dff574b7d2257c36b81
new file mode 100644
index 0000000..a817ebf
--- /dev/null
+++ b/fuzzer/corpus/cdcef0781a108edea5523dff574b7d2257c36b81
Binary files differ
diff --git a/fuzzer/corpus/ce10b19d79358c860d8a11f639a7bbfb56abd171 b/fuzzer/corpus/ce10b19d79358c860d8a11f639a7bbfb56abd171
new file mode 100644
index 0000000..5fd6741
--- /dev/null
+++ b/fuzzer/corpus/ce10b19d79358c860d8a11f639a7bbfb56abd171
Binary files differ
diff --git a/fuzzer/corpus/ce2d5784dd0cb116a7903977da51dcd9bd669128 b/fuzzer/corpus/ce2d5784dd0cb116a7903977da51dcd9bd669128
new file mode 100644
index 0000000..1070a8c
--- /dev/null
+++ b/fuzzer/corpus/ce2d5784dd0cb116a7903977da51dcd9bd669128
Binary files differ
diff --git a/fuzzer/corpus/ce445157963acf16cfb95c1894742140002b5204 b/fuzzer/corpus/ce445157963acf16cfb95c1894742140002b5204
new file mode 100644
index 0000000..25f74c2
--- /dev/null
+++ b/fuzzer/corpus/ce445157963acf16cfb95c1894742140002b5204
Binary files differ
diff --git a/fuzzer/corpus/ce5339e0496213c0e19c3296ac96f0591ac50289 b/fuzzer/corpus/ce5339e0496213c0e19c3296ac96f0591ac50289
new file mode 100644
index 0000000..159e69b
--- /dev/null
+++ b/fuzzer/corpus/ce5339e0496213c0e19c3296ac96f0591ac50289
Binary files differ
diff --git a/fuzzer/corpus/ce5fcc6f69e4cdbc9f563d5b06fec3c220db2a62 b/fuzzer/corpus/ce5fcc6f69e4cdbc9f563d5b06fec3c220db2a62
new file mode 100644
index 0000000..709abec
--- /dev/null
+++ b/fuzzer/corpus/ce5fcc6f69e4cdbc9f563d5b06fec3c220db2a62
Binary files differ
diff --git a/fuzzer/corpus/ce9b9c4d5094a874ded6caa3e0b3bea2c66a672c b/fuzzer/corpus/ce9b9c4d5094a874ded6caa3e0b3bea2c66a672c
new file mode 100644
index 0000000..f6a3d08
--- /dev/null
+++ b/fuzzer/corpus/ce9b9c4d5094a874ded6caa3e0b3bea2c66a672c
Binary files differ
diff --git a/fuzzer/corpus/ceb3f7aa23f8a22fae7a939752d3c4664b483df3 b/fuzzer/corpus/ceb3f7aa23f8a22fae7a939752d3c4664b483df3
new file mode 100644
index 0000000..7d1bd41
--- /dev/null
+++ b/fuzzer/corpus/ceb3f7aa23f8a22fae7a939752d3c4664b483df3
Binary files differ
diff --git a/fuzzer/corpus/cec2152fdffa5cd17459775824378dfc369773c7 b/fuzzer/corpus/cec2152fdffa5cd17459775824378dfc369773c7
new file mode 100644
index 0000000..2dd2e62
--- /dev/null
+++ b/fuzzer/corpus/cec2152fdffa5cd17459775824378dfc369773c7
Binary files differ
diff --git a/fuzzer/corpus/cefc3942c377bad56e45cc3730f8f9242621f751 b/fuzzer/corpus/cefc3942c377bad56e45cc3730f8f9242621f751
new file mode 100644
index 0000000..6b61ca4
--- /dev/null
+++ b/fuzzer/corpus/cefc3942c377bad56e45cc3730f8f9242621f751
Binary files differ
diff --git a/fuzzer/corpus/cf0e0ead7aa41476b072cefe7c9ead66ec31c562 b/fuzzer/corpus/cf0e0ead7aa41476b072cefe7c9ead66ec31c562
new file mode 100644
index 0000000..6424dd0
--- /dev/null
+++ b/fuzzer/corpus/cf0e0ead7aa41476b072cefe7c9ead66ec31c562
Binary files differ
diff --git a/fuzzer/corpus/cf2786796b3d0611819e69d00c3b2785c5daa987 b/fuzzer/corpus/cf2786796b3d0611819e69d00c3b2785c5daa987
new file mode 100644
index 0000000..2cfc473
--- /dev/null
+++ b/fuzzer/corpus/cf2786796b3d0611819e69d00c3b2785c5daa987
Binary files differ
diff --git a/fuzzer/corpus/cf426b8b6ce33c44a221c704820191efde0fb226 b/fuzzer/corpus/cf426b8b6ce33c44a221c704820191efde0fb226
new file mode 100644
index 0000000..61a44d6
--- /dev/null
+++ b/fuzzer/corpus/cf426b8b6ce33c44a221c704820191efde0fb226
Binary files differ
diff --git a/fuzzer/corpus/cf4465ad351e6129ecda2126c8078a49d882ad9f b/fuzzer/corpus/cf4465ad351e6129ecda2126c8078a49d882ad9f
new file mode 100644
index 0000000..bfc3d09
--- /dev/null
+++ b/fuzzer/corpus/cf4465ad351e6129ecda2126c8078a49d882ad9f
Binary files differ
diff --git a/fuzzer/corpus/cf563882ac7eeb71f0fde1dd36f22f9bd1a5a2ef b/fuzzer/corpus/cf563882ac7eeb71f0fde1dd36f22f9bd1a5a2ef
new file mode 100644
index 0000000..12f769b
--- /dev/null
+++ b/fuzzer/corpus/cf563882ac7eeb71f0fde1dd36f22f9bd1a5a2ef
Binary files differ
diff --git a/fuzzer/corpus/cf94a895f1a8090736e9b61874a82fbda3b6c300 b/fuzzer/corpus/cf94a895f1a8090736e9b61874a82fbda3b6c300
new file mode 100644
index 0000000..e9808cd
--- /dev/null
+++ b/fuzzer/corpus/cf94a895f1a8090736e9b61874a82fbda3b6c300
Binary files differ
diff --git a/fuzzer/corpus/cfa56ebde00a1fab5173e0eff7a0f1f4bd1af77c b/fuzzer/corpus/cfa56ebde00a1fab5173e0eff7a0f1f4bd1af77c
new file mode 100644
index 0000000..801988f
--- /dev/null
+++ b/fuzzer/corpus/cfa56ebde00a1fab5173e0eff7a0f1f4bd1af77c
Binary files differ
diff --git a/fuzzer/corpus/cfc516d23c2dfb0ae85094323b8b14d4f222bec3 b/fuzzer/corpus/cfc516d23c2dfb0ae85094323b8b14d4f222bec3
new file mode 100644
index 0000000..0dfbfd8
--- /dev/null
+++ b/fuzzer/corpus/cfc516d23c2dfb0ae85094323b8b14d4f222bec3
Binary files differ
diff --git a/fuzzer/corpus/cfd0d6bc1f78e03fbaa6990e751ccae66f674640 b/fuzzer/corpus/cfd0d6bc1f78e03fbaa6990e751ccae66f674640
new file mode 100644
index 0000000..39cb104
--- /dev/null
+++ b/fuzzer/corpus/cfd0d6bc1f78e03fbaa6990e751ccae66f674640
Binary files differ
diff --git a/fuzzer/corpus/cfd5256cebc5ddbf045a099af9c2aed984a06b22 b/fuzzer/corpus/cfd5256cebc5ddbf045a099af9c2aed984a06b22
new file mode 100644
index 0000000..2c758df
--- /dev/null
+++ b/fuzzer/corpus/cfd5256cebc5ddbf045a099af9c2aed984a06b22
Binary files differ
diff --git a/fuzzer/corpus/d0286867a9a40eefe46c98727c9fd06a2cf1df59 b/fuzzer/corpus/d0286867a9a40eefe46c98727c9fd06a2cf1df59
new file mode 100644
index 0000000..c8ce95a
--- /dev/null
+++ b/fuzzer/corpus/d0286867a9a40eefe46c98727c9fd06a2cf1df59
Binary files differ
diff --git a/fuzzer/corpus/d02d8d90d95b71a88b634f8ee4e8b3a94409e92c b/fuzzer/corpus/d02d8d90d95b71a88b634f8ee4e8b3a94409e92c
new file mode 100644
index 0000000..cde15bc
--- /dev/null
+++ b/fuzzer/corpus/d02d8d90d95b71a88b634f8ee4e8b3a94409e92c
Binary files differ
diff --git a/fuzzer/corpus/d02ffe597db3e53bd478ce0f799845834fb37758 b/fuzzer/corpus/d02ffe597db3e53bd478ce0f799845834fb37758
new file mode 100644
index 0000000..7220edc
--- /dev/null
+++ b/fuzzer/corpus/d02ffe597db3e53bd478ce0f799845834fb37758
Binary files differ
diff --git a/fuzzer/corpus/d031d343ba645a52ab822b8c5aeff2c1adf78271 b/fuzzer/corpus/d031d343ba645a52ab822b8c5aeff2c1adf78271
new file mode 100644
index 0000000..ef4e571
--- /dev/null
+++ b/fuzzer/corpus/d031d343ba645a52ab822b8c5aeff2c1adf78271
Binary files differ
diff --git a/fuzzer/corpus/d04353d0b588f28ae24e9a8070517733cecea63d b/fuzzer/corpus/d04353d0b588f28ae24e9a8070517733cecea63d
new file mode 100644
index 0000000..04c9952
--- /dev/null
+++ b/fuzzer/corpus/d04353d0b588f28ae24e9a8070517733cecea63d
Binary files differ
diff --git a/fuzzer/corpus/d057f87ceab445641eca2b2410f0cf777780466e b/fuzzer/corpus/d057f87ceab445641eca2b2410f0cf777780466e
new file mode 100644
index 0000000..f446aaa
--- /dev/null
+++ b/fuzzer/corpus/d057f87ceab445641eca2b2410f0cf777780466e
Binary files differ
diff --git a/fuzzer/corpus/d079ec49f52a1bb718f3bddbe4e20daa450ac010 b/fuzzer/corpus/d079ec49f52a1bb718f3bddbe4e20daa450ac010
new file mode 100644
index 0000000..fdc9a49
--- /dev/null
+++ b/fuzzer/corpus/d079ec49f52a1bb718f3bddbe4e20daa450ac010
Binary files differ
diff --git a/fuzzer/corpus/d07bda374e7e88e4ca026fa4c00443be8cbd3169 b/fuzzer/corpus/d07bda374e7e88e4ca026fa4c00443be8cbd3169
new file mode 100644
index 0000000..d3dbd39
--- /dev/null
+++ b/fuzzer/corpus/d07bda374e7e88e4ca026fa4c00443be8cbd3169
Binary files differ
diff --git a/fuzzer/corpus/d0b0a301657dcf4805c6dcd3f4fc144705e07389 b/fuzzer/corpus/d0b0a301657dcf4805c6dcd3f4fc144705e07389
new file mode 100644
index 0000000..ab2a5e2
--- /dev/null
+++ b/fuzzer/corpus/d0b0a301657dcf4805c6dcd3f4fc144705e07389
Binary files differ
diff --git a/fuzzer/corpus/d0b93f8e00e90d36c66068393ae0fb0c6a95dbe1 b/fuzzer/corpus/d0b93f8e00e90d36c66068393ae0fb0c6a95dbe1
new file mode 100644
index 0000000..e8da19f
--- /dev/null
+++ b/fuzzer/corpus/d0b93f8e00e90d36c66068393ae0fb0c6a95dbe1
Binary files differ
diff --git a/fuzzer/corpus/d0ce1f5e5efca547b3768aa02735f279d7c3e03b b/fuzzer/corpus/d0ce1f5e5efca547b3768aa02735f279d7c3e03b
new file mode 100644
index 0000000..d147649
--- /dev/null
+++ b/fuzzer/corpus/d0ce1f5e5efca547b3768aa02735f279d7c3e03b
Binary files differ
diff --git a/fuzzer/corpus/d0d46e2d7d7af4d4d2854b3e702874e9adc36f0d b/fuzzer/corpus/d0d46e2d7d7af4d4d2854b3e702874e9adc36f0d
new file mode 100644
index 0000000..7ef32b1
--- /dev/null
+++ b/fuzzer/corpus/d0d46e2d7d7af4d4d2854b3e702874e9adc36f0d
Binary files differ
diff --git a/fuzzer/corpus/d0f5075f11df42aba75cc94b58de6ee9224ce2dd b/fuzzer/corpus/d0f5075f11df42aba75cc94b58de6ee9224ce2dd
new file mode 100644
index 0000000..1b77791
--- /dev/null
+++ b/fuzzer/corpus/d0f5075f11df42aba75cc94b58de6ee9224ce2dd
Binary files differ
diff --git a/fuzzer/corpus/d1141e2f1eff32caeb93c2e86424f9b32ecab656 b/fuzzer/corpus/d1141e2f1eff32caeb93c2e86424f9b32ecab656
new file mode 100644
index 0000000..7a10541
--- /dev/null
+++ b/fuzzer/corpus/d1141e2f1eff32caeb93c2e86424f9b32ecab656
Binary files differ
diff --git a/fuzzer/corpus/d11aaa3f763944e66460c5c95c9940bd57036406 b/fuzzer/corpus/d11aaa3f763944e66460c5c95c9940bd57036406
new file mode 100644
index 0000000..52cb6b0
--- /dev/null
+++ b/fuzzer/corpus/d11aaa3f763944e66460c5c95c9940bd57036406
Binary files differ
diff --git a/fuzzer/corpus/d1d82f2754ff02073bc989023db179df7fd797f7 b/fuzzer/corpus/d1d82f2754ff02073bc989023db179df7fd797f7
new file mode 100644
index 0000000..072a961
--- /dev/null
+++ b/fuzzer/corpus/d1d82f2754ff02073bc989023db179df7fd797f7
Binary files differ
diff --git a/fuzzer/corpus/d1e3035c943cf57e9965a3a30a2a5abb787e8dd8 b/fuzzer/corpus/d1e3035c943cf57e9965a3a30a2a5abb787e8dd8
new file mode 100644
index 0000000..da96c84
--- /dev/null
+++ b/fuzzer/corpus/d1e3035c943cf57e9965a3a30a2a5abb787e8dd8
Binary files differ
diff --git a/fuzzer/corpus/d1ed8b7bf002647ed552c115f2acc0490a828f36 b/fuzzer/corpus/d1ed8b7bf002647ed552c115f2acc0490a828f36
new file mode 100644
index 0000000..45d9a40
--- /dev/null
+++ b/fuzzer/corpus/d1ed8b7bf002647ed552c115f2acc0490a828f36
Binary files differ
diff --git a/fuzzer/corpus/d1f13863e3eb0a7a85c12dba44ab16c666cca019 b/fuzzer/corpus/d1f13863e3eb0a7a85c12dba44ab16c666cca019
new file mode 100644
index 0000000..79aae6d
--- /dev/null
+++ b/fuzzer/corpus/d1f13863e3eb0a7a85c12dba44ab16c666cca019
Binary files differ
diff --git a/fuzzer/corpus/d20a44d80ee2ba2c4d97352e9f0fe7f950b70687 b/fuzzer/corpus/d20a44d80ee2ba2c4d97352e9f0fe7f950b70687
new file mode 100644
index 0000000..4ccab3b
--- /dev/null
+++ b/fuzzer/corpus/d20a44d80ee2ba2c4d97352e9f0fe7f950b70687
Binary files differ
diff --git a/fuzzer/corpus/d248267c8185eaea4425691b96efc36028273a9d b/fuzzer/corpus/d248267c8185eaea4425691b96efc36028273a9d
new file mode 100644
index 0000000..1c4733a
--- /dev/null
+++ b/fuzzer/corpus/d248267c8185eaea4425691b96efc36028273a9d
Binary files differ
diff --git a/fuzzer/corpus/d24d9eff7fcdf6f4a40f0d6f1e1808a33f79e237 b/fuzzer/corpus/d24d9eff7fcdf6f4a40f0d6f1e1808a33f79e237
new file mode 100644
index 0000000..645f0be
--- /dev/null
+++ b/fuzzer/corpus/d24d9eff7fcdf6f4a40f0d6f1e1808a33f79e237
Binary files differ
diff --git a/fuzzer/corpus/d26c0fcd2637abb33b75d0307e3f50b02a7f5b8a b/fuzzer/corpus/d26c0fcd2637abb33b75d0307e3f50b02a7f5b8a
new file mode 100644
index 0000000..388a8cc
--- /dev/null
+++ b/fuzzer/corpus/d26c0fcd2637abb33b75d0307e3f50b02a7f5b8a
Binary files differ
diff --git a/fuzzer/corpus/d270291d131d6b8ecbbcfc1942894db9be5b74e2 b/fuzzer/corpus/d270291d131d6b8ecbbcfc1942894db9be5b74e2
new file mode 100644
index 0000000..086e2c5
--- /dev/null
+++ b/fuzzer/corpus/d270291d131d6b8ecbbcfc1942894db9be5b74e2
Binary files differ
diff --git a/fuzzer/corpus/d2830a6f96665cebb8b8389dc4400ec1921e828c b/fuzzer/corpus/d2830a6f96665cebb8b8389dc4400ec1921e828c
new file mode 100644
index 0000000..08b6166
--- /dev/null
+++ b/fuzzer/corpus/d2830a6f96665cebb8b8389dc4400ec1921e828c
Binary files differ
diff --git a/fuzzer/corpus/d2a114f6d6e7209dbbe15a603164fb0dd0f8357f b/fuzzer/corpus/d2a114f6d6e7209dbbe15a603164fb0dd0f8357f
new file mode 100644
index 0000000..05b67ad
--- /dev/null
+++ b/fuzzer/corpus/d2a114f6d6e7209dbbe15a603164fb0dd0f8357f
Binary files differ
diff --git a/fuzzer/corpus/d2a7edbe25a7611ae1fa19ed0200e67d20f30869 b/fuzzer/corpus/d2a7edbe25a7611ae1fa19ed0200e67d20f30869
new file mode 100644
index 0000000..9234031
--- /dev/null
+++ b/fuzzer/corpus/d2a7edbe25a7611ae1fa19ed0200e67d20f30869
Binary files differ
diff --git a/fuzzer/corpus/d2b1ef6c8944f2e881d8467ac8bd99ddd83a945a b/fuzzer/corpus/d2b1ef6c8944f2e881d8467ac8bd99ddd83a945a
new file mode 100644
index 0000000..fe0f28a
--- /dev/null
+++ b/fuzzer/corpus/d2b1ef6c8944f2e881d8467ac8bd99ddd83a945a
Binary files differ
diff --git a/fuzzer/corpus/d30e49357fa2da4ffdf45aec13968a1bf028ef3d b/fuzzer/corpus/d30e49357fa2da4ffdf45aec13968a1bf028ef3d
new file mode 100644
index 0000000..7ea490f
--- /dev/null
+++ b/fuzzer/corpus/d30e49357fa2da4ffdf45aec13968a1bf028ef3d
Binary files differ
diff --git a/fuzzer/corpus/d31c01b5d791844e563bf59d88beb46adc59499f b/fuzzer/corpus/d31c01b5d791844e563bf59d88beb46adc59499f
new file mode 100644
index 0000000..e64a9d7
--- /dev/null
+++ b/fuzzer/corpus/d31c01b5d791844e563bf59d88beb46adc59499f
Binary files differ
diff --git a/fuzzer/corpus/d3255f6dcf44ff3fce3832e68b05df7ed2e2c096 b/fuzzer/corpus/d3255f6dcf44ff3fce3832e68b05df7ed2e2c096
new file mode 100644
index 0000000..a91aff0
--- /dev/null
+++ b/fuzzer/corpus/d3255f6dcf44ff3fce3832e68b05df7ed2e2c096
Binary files differ
diff --git a/fuzzer/corpus/d3260713b8603b337c776e95be380df4e3bf51d6 b/fuzzer/corpus/d3260713b8603b337c776e95be380df4e3bf51d6
new file mode 100644
index 0000000..7342f37
--- /dev/null
+++ b/fuzzer/corpus/d3260713b8603b337c776e95be380df4e3bf51d6
Binary files differ
diff --git a/fuzzer/corpus/d33fda0247b0269d223a45817f6a5fdfef2e8380 b/fuzzer/corpus/d33fda0247b0269d223a45817f6a5fdfef2e8380
new file mode 100644
index 0000000..3bb767d
--- /dev/null
+++ b/fuzzer/corpus/d33fda0247b0269d223a45817f6a5fdfef2e8380
Binary files differ
diff --git a/fuzzer/corpus/d34fd332d61e28636723070912e873d6f086c179 b/fuzzer/corpus/d34fd332d61e28636723070912e873d6f086c179
new file mode 100644
index 0000000..fcbfc96
--- /dev/null
+++ b/fuzzer/corpus/d34fd332d61e28636723070912e873d6f086c179
Binary files differ
diff --git a/fuzzer/corpus/d35e97781b13cede28c2c8a2df96b2ca29959905 b/fuzzer/corpus/d35e97781b13cede28c2c8a2df96b2ca29959905
new file mode 100644
index 0000000..db0c7db
--- /dev/null
+++ b/fuzzer/corpus/d35e97781b13cede28c2c8a2df96b2ca29959905
Binary files differ
diff --git a/fuzzer/corpus/d3945a1047680d560a57b83792e52838f4c77e23 b/fuzzer/corpus/d3945a1047680d560a57b83792e52838f4c77e23
new file mode 100644
index 0000000..4e07454
--- /dev/null
+++ b/fuzzer/corpus/d3945a1047680d560a57b83792e52838f4c77e23
Binary files differ
diff --git a/fuzzer/corpus/d3a2751c86b28596c5c8d5d9c57213f2aadd2f24 b/fuzzer/corpus/d3a2751c86b28596c5c8d5d9c57213f2aadd2f24
new file mode 100644
index 0000000..972e463
--- /dev/null
+++ b/fuzzer/corpus/d3a2751c86b28596c5c8d5d9c57213f2aadd2f24
Binary files differ
diff --git a/fuzzer/corpus/d3ab149e5c1cb609842f55b565cb516145678caf b/fuzzer/corpus/d3ab149e5c1cb609842f55b565cb516145678caf
new file mode 100644
index 0000000..56a0fae
--- /dev/null
+++ b/fuzzer/corpus/d3ab149e5c1cb609842f55b565cb516145678caf
Binary files differ
diff --git a/fuzzer/corpus/d3c9aa0f7eca577aa41e5ce7d118890bfb33abf7 b/fuzzer/corpus/d3c9aa0f7eca577aa41e5ce7d118890bfb33abf7
new file mode 100644
index 0000000..285ec8f
--- /dev/null
+++ b/fuzzer/corpus/d3c9aa0f7eca577aa41e5ce7d118890bfb33abf7
Binary files differ
diff --git a/fuzzer/corpus/d3d9c64378addec6052b3e22d3bfe2cdb59822ef b/fuzzer/corpus/d3d9c64378addec6052b3e22d3bfe2cdb59822ef
new file mode 100644
index 0000000..2ba4613
--- /dev/null
+++ b/fuzzer/corpus/d3d9c64378addec6052b3e22d3bfe2cdb59822ef
Binary files differ
diff --git a/fuzzer/corpus/d4048366b2561abfe2fed3cb0e4b6248606e59fb b/fuzzer/corpus/d4048366b2561abfe2fed3cb0e4b6248606e59fb
new file mode 100644
index 0000000..c990441
--- /dev/null
+++ b/fuzzer/corpus/d4048366b2561abfe2fed3cb0e4b6248606e59fb
Binary files differ
diff --git a/fuzzer/corpus/d40beafba088aaa47eeee2e125983f253104a3a4 b/fuzzer/corpus/d40beafba088aaa47eeee2e125983f253104a3a4
new file mode 100644
index 0000000..06d06e3
--- /dev/null
+++ b/fuzzer/corpus/d40beafba088aaa47eeee2e125983f253104a3a4
Binary files differ
diff --git a/fuzzer/corpus/d414ccf23759eedeaa2d42db29b215158ee23764 b/fuzzer/corpus/d414ccf23759eedeaa2d42db29b215158ee23764
new file mode 100644
index 0000000..7a3b40a
--- /dev/null
+++ b/fuzzer/corpus/d414ccf23759eedeaa2d42db29b215158ee23764
Binary files differ
diff --git a/fuzzer/corpus/d456cec2575aa27e5d4b85fb70f8afa971db3330 b/fuzzer/corpus/d456cec2575aa27e5d4b85fb70f8afa971db3330
new file mode 100644
index 0000000..9cd75cb
--- /dev/null
+++ b/fuzzer/corpus/d456cec2575aa27e5d4b85fb70f8afa971db3330
Binary files differ
diff --git a/fuzzer/corpus/d49bb7f3855d7f9878c9864b916558a439e53cf6 b/fuzzer/corpus/d49bb7f3855d7f9878c9864b916558a439e53cf6
new file mode 100644
index 0000000..a8a0e89
--- /dev/null
+++ b/fuzzer/corpus/d49bb7f3855d7f9878c9864b916558a439e53cf6
Binary files differ
diff --git a/fuzzer/corpus/d4e6203130344061ecbbeeba56d501e46e9f0c02 b/fuzzer/corpus/d4e6203130344061ecbbeeba56d501e46e9f0c02
new file mode 100644
index 0000000..5df36f0
--- /dev/null
+++ b/fuzzer/corpus/d4e6203130344061ecbbeeba56d501e46e9f0c02
Binary files differ
diff --git a/fuzzer/corpus/d4eb367a3608d272e1bc1053300c8f5e0045862f b/fuzzer/corpus/d4eb367a3608d272e1bc1053300c8f5e0045862f
new file mode 100644
index 0000000..07e2ce7
--- /dev/null
+++ b/fuzzer/corpus/d4eb367a3608d272e1bc1053300c8f5e0045862f
Binary files differ
diff --git a/fuzzer/corpus/d4eeba4d10d0df6b37df70d13b346d6e63c53802 b/fuzzer/corpus/d4eeba4d10d0df6b37df70d13b346d6e63c53802
new file mode 100644
index 0000000..f75d482
--- /dev/null
+++ b/fuzzer/corpus/d4eeba4d10d0df6b37df70d13b346d6e63c53802
Binary files differ
diff --git a/fuzzer/corpus/d4ef2d723c263dd1faf63de6f6cef5b680c70435 b/fuzzer/corpus/d4ef2d723c263dd1faf63de6f6cef5b680c70435
new file mode 100644
index 0000000..8a05bf4
--- /dev/null
+++ b/fuzzer/corpus/d4ef2d723c263dd1faf63de6f6cef5b680c70435
Binary files differ
diff --git a/fuzzer/corpus/d538ed38a6021ee134d512906058f692a1f7b409 b/fuzzer/corpus/d538ed38a6021ee134d512906058f692a1f7b409
new file mode 100644
index 0000000..3f240d2
--- /dev/null
+++ b/fuzzer/corpus/d538ed38a6021ee134d512906058f692a1f7b409
Binary files differ
diff --git a/fuzzer/corpus/d53f8b80b76651c0a71fc786d598ab60589ca31e b/fuzzer/corpus/d53f8b80b76651c0a71fc786d598ab60589ca31e
new file mode 100644
index 0000000..63bcdd1
--- /dev/null
+++ b/fuzzer/corpus/d53f8b80b76651c0a71fc786d598ab60589ca31e
Binary files differ
diff --git a/fuzzer/corpus/d564e03d6b83fa5ade5fee4496fc6cbd4bcdc503 b/fuzzer/corpus/d564e03d6b83fa5ade5fee4496fc6cbd4bcdc503
new file mode 100644
index 0000000..fd760e4
--- /dev/null
+++ b/fuzzer/corpus/d564e03d6b83fa5ade5fee4496fc6cbd4bcdc503
Binary files differ
diff --git a/fuzzer/corpus/d584a0d2694f58abe1c29316720319cb32a3745b b/fuzzer/corpus/d584a0d2694f58abe1c29316720319cb32a3745b
new file mode 100644
index 0000000..d8511a1
--- /dev/null
+++ b/fuzzer/corpus/d584a0d2694f58abe1c29316720319cb32a3745b
Binary files differ
diff --git a/fuzzer/corpus/d5924106fc83b0da01dfc76eab3ca1a7f69368c1 b/fuzzer/corpus/d5924106fc83b0da01dfc76eab3ca1a7f69368c1
new file mode 100644
index 0000000..c994dc4
--- /dev/null
+++ b/fuzzer/corpus/d5924106fc83b0da01dfc76eab3ca1a7f69368c1
Binary files differ
diff --git a/fuzzer/corpus/d5a04e30f6d0b4c8b93aba48c03128d490c93299 b/fuzzer/corpus/d5a04e30f6d0b4c8b93aba48c03128d490c93299
new file mode 100644
index 0000000..5386b27
--- /dev/null
+++ b/fuzzer/corpus/d5a04e30f6d0b4c8b93aba48c03128d490c93299
Binary files differ
diff --git a/fuzzer/corpus/d5b63bba975637e9a05dc0775b2a25262721a013 b/fuzzer/corpus/d5b63bba975637e9a05dc0775b2a25262721a013
new file mode 100644
index 0000000..8b0f6a8
--- /dev/null
+++ b/fuzzer/corpus/d5b63bba975637e9a05dc0775b2a25262721a013
Binary files differ
diff --git a/fuzzer/corpus/d617c156f8add1aca9f9ed9ecf6f178434844c1d b/fuzzer/corpus/d617c156f8add1aca9f9ed9ecf6f178434844c1d
new file mode 100644
index 0000000..63c571a
--- /dev/null
+++ b/fuzzer/corpus/d617c156f8add1aca9f9ed9ecf6f178434844c1d
Binary files differ
diff --git a/fuzzer/corpus/d627a5bfa8031a15f91b4c1e53584d912f48ea41 b/fuzzer/corpus/d627a5bfa8031a15f91b4c1e53584d912f48ea41
new file mode 100644
index 0000000..dabbe12
--- /dev/null
+++ b/fuzzer/corpus/d627a5bfa8031a15f91b4c1e53584d912f48ea41
Binary files differ
diff --git a/fuzzer/corpus/d6299d106713090e7e031f799118be78f1b97d9c b/fuzzer/corpus/d6299d106713090e7e031f799118be78f1b97d9c
new file mode 100644
index 0000000..a4529e6
--- /dev/null
+++ b/fuzzer/corpus/d6299d106713090e7e031f799118be78f1b97d9c
Binary files differ
diff --git a/fuzzer/corpus/d66d8ba52072490550f35f22a83488c7c242f304 b/fuzzer/corpus/d66d8ba52072490550f35f22a83488c7c242f304
new file mode 100644
index 0000000..c8437b5
--- /dev/null
+++ b/fuzzer/corpus/d66d8ba52072490550f35f22a83488c7c242f304
Binary files differ
diff --git a/fuzzer/corpus/d67ee847e6170f63a71190335d274b1caf1d2948 b/fuzzer/corpus/d67ee847e6170f63a71190335d274b1caf1d2948
new file mode 100644
index 0000000..fb92f50
--- /dev/null
+++ b/fuzzer/corpus/d67ee847e6170f63a71190335d274b1caf1d2948
Binary files differ
diff --git a/fuzzer/corpus/d68087b453669cce4195fba0b972038d7fc58b08 b/fuzzer/corpus/d68087b453669cce4195fba0b972038d7fc58b08
new file mode 100644
index 0000000..c857a5a
--- /dev/null
+++ b/fuzzer/corpus/d68087b453669cce4195fba0b972038d7fc58b08
Binary files differ
diff --git a/fuzzer/corpus/d6b53d53a88b7942aaa96e140929b0009f907db2 b/fuzzer/corpus/d6b53d53a88b7942aaa96e140929b0009f907db2
new file mode 100644
index 0000000..e4fefb5
--- /dev/null
+++ b/fuzzer/corpus/d6b53d53a88b7942aaa96e140929b0009f907db2
Binary files differ
diff --git a/fuzzer/corpus/d6ce92c0ceaca8522ef64653103f3d8a16b50bb7 b/fuzzer/corpus/d6ce92c0ceaca8522ef64653103f3d8a16b50bb7
new file mode 100644
index 0000000..4753327
--- /dev/null
+++ b/fuzzer/corpus/d6ce92c0ceaca8522ef64653103f3d8a16b50bb7
Binary files differ
diff --git a/fuzzer/corpus/d6dd23b471088f8889d8504f153011b67dcd6de2 b/fuzzer/corpus/d6dd23b471088f8889d8504f153011b67dcd6de2
new file mode 100644
index 0000000..650f5c3
--- /dev/null
+++ b/fuzzer/corpus/d6dd23b471088f8889d8504f153011b67dcd6de2
Binary files differ
diff --git a/fuzzer/corpus/d6eb0ca72bebd0db0d43439885ad172ab2c9b5b8 b/fuzzer/corpus/d6eb0ca72bebd0db0d43439885ad172ab2c9b5b8
new file mode 100644
index 0000000..1622bf6
--- /dev/null
+++ b/fuzzer/corpus/d6eb0ca72bebd0db0d43439885ad172ab2c9b5b8
Binary files differ
diff --git a/fuzzer/corpus/d6f4a9abc74ccb8cd87f1e59204f7df3a2530fcf b/fuzzer/corpus/d6f4a9abc74ccb8cd87f1e59204f7df3a2530fcf
new file mode 100644
index 0000000..35164b8
--- /dev/null
+++ b/fuzzer/corpus/d6f4a9abc74ccb8cd87f1e59204f7df3a2530fcf
Binary files differ
diff --git a/fuzzer/corpus/d6fd0be7a56f267c6c1bb3f00551d068e75dce31 b/fuzzer/corpus/d6fd0be7a56f267c6c1bb3f00551d068e75dce31
new file mode 100644
index 0000000..f208a12
--- /dev/null
+++ b/fuzzer/corpus/d6fd0be7a56f267c6c1bb3f00551d068e75dce31
Binary files differ
diff --git a/fuzzer/corpus/d71496a6c97e10574c0a6378334237c26917b3e6 b/fuzzer/corpus/d71496a6c97e10574c0a6378334237c26917b3e6
new file mode 100644
index 0000000..02f265a
--- /dev/null
+++ b/fuzzer/corpus/d71496a6c97e10574c0a6378334237c26917b3e6
Binary files differ
diff --git a/fuzzer/corpus/d71ac84919378e263e7f8de363f06e01a73ad614 b/fuzzer/corpus/d71ac84919378e263e7f8de363f06e01a73ad614
new file mode 100644
index 0000000..2d69455
--- /dev/null
+++ b/fuzzer/corpus/d71ac84919378e263e7f8de363f06e01a73ad614
Binary files differ
diff --git a/fuzzer/corpus/d71ed070dfa1a23451fccc45bd286a642d2d0f25 b/fuzzer/corpus/d71ed070dfa1a23451fccc45bd286a642d2d0f25
new file mode 100644
index 0000000..5bee2fe
--- /dev/null
+++ b/fuzzer/corpus/d71ed070dfa1a23451fccc45bd286a642d2d0f25
Binary files differ
diff --git a/fuzzer/corpus/d7265e3f69d695ce1fefc893078f666516667418 b/fuzzer/corpus/d7265e3f69d695ce1fefc893078f666516667418
new file mode 100644
index 0000000..e1fb5c1
--- /dev/null
+++ b/fuzzer/corpus/d7265e3f69d695ce1fefc893078f666516667418
Binary files differ
diff --git a/fuzzer/corpus/d72888039e173fb59116b0bafe9e5af6ab46dbb2 b/fuzzer/corpus/d72888039e173fb59116b0bafe9e5af6ab46dbb2
new file mode 100644
index 0000000..81acdbe
--- /dev/null
+++ b/fuzzer/corpus/d72888039e173fb59116b0bafe9e5af6ab46dbb2
Binary files differ
diff --git a/fuzzer/corpus/d75b92734161809e82ea62e0bed26b2481f303f8 b/fuzzer/corpus/d75b92734161809e82ea62e0bed26b2481f303f8
new file mode 100644
index 0000000..4134927
--- /dev/null
+++ b/fuzzer/corpus/d75b92734161809e82ea62e0bed26b2481f303f8
Binary files differ
diff --git a/fuzzer/corpus/d75e24076c7217f29c9fb8fc9169dfc95a119ede b/fuzzer/corpus/d75e24076c7217f29c9fb8fc9169dfc95a119ede
new file mode 100644
index 0000000..4baff06
--- /dev/null
+++ b/fuzzer/corpus/d75e24076c7217f29c9fb8fc9169dfc95a119ede
Binary files differ
diff --git a/fuzzer/corpus/d781fceea762f5c716dae52eb94f9dfb67514e62 b/fuzzer/corpus/d781fceea762f5c716dae52eb94f9dfb67514e62
new file mode 100644
index 0000000..3e4ffeb
--- /dev/null
+++ b/fuzzer/corpus/d781fceea762f5c716dae52eb94f9dfb67514e62
Binary files differ
diff --git a/fuzzer/corpus/d789e4ff7d0561d47354313ad534778b3ad832e3 b/fuzzer/corpus/d789e4ff7d0561d47354313ad534778b3ad832e3
new file mode 100644
index 0000000..7477829
--- /dev/null
+++ b/fuzzer/corpus/d789e4ff7d0561d47354313ad534778b3ad832e3
Binary files differ
diff --git a/fuzzer/corpus/d79a4b9626b363119a990cc25932860c8f97a7d6 b/fuzzer/corpus/d79a4b9626b363119a990cc25932860c8f97a7d6
new file mode 100644
index 0000000..e0a772c
--- /dev/null
+++ b/fuzzer/corpus/d79a4b9626b363119a990cc25932860c8f97a7d6
Binary files differ
diff --git a/fuzzer/corpus/d7b4bde787daaca7cfebd860e3579404bcfe0207 b/fuzzer/corpus/d7b4bde787daaca7cfebd860e3579404bcfe0207
new file mode 100644
index 0000000..8d0fb98
--- /dev/null
+++ b/fuzzer/corpus/d7b4bde787daaca7cfebd860e3579404bcfe0207
Binary files differ
diff --git a/fuzzer/corpus/d7c5d185ba98a1f76dbd97de50ea281877ecbf4a b/fuzzer/corpus/d7c5d185ba98a1f76dbd97de50ea281877ecbf4a
new file mode 100644
index 0000000..9fd3496
--- /dev/null
+++ b/fuzzer/corpus/d7c5d185ba98a1f76dbd97de50ea281877ecbf4a
Binary files differ
diff --git a/fuzzer/corpus/d809314cef9c3264868ba63183d8180bd12c93df b/fuzzer/corpus/d809314cef9c3264868ba63183d8180bd12c93df
new file mode 100644
index 0000000..daf166d
--- /dev/null
+++ b/fuzzer/corpus/d809314cef9c3264868ba63183d8180bd12c93df
Binary files differ
diff --git a/fuzzer/corpus/d848fa1ccf89d98df57a2e2c6a40869f81b9971d b/fuzzer/corpus/d848fa1ccf89d98df57a2e2c6a40869f81b9971d
new file mode 100644
index 0000000..20440fc
--- /dev/null
+++ b/fuzzer/corpus/d848fa1ccf89d98df57a2e2c6a40869f81b9971d
Binary files differ
diff --git a/fuzzer/corpus/d85617cf6726d45c5b9a4c46f1bb7e252acea4b1 b/fuzzer/corpus/d85617cf6726d45c5b9a4c46f1bb7e252acea4b1
new file mode 100644
index 0000000..1336484
--- /dev/null
+++ b/fuzzer/corpus/d85617cf6726d45c5b9a4c46f1bb7e252acea4b1
Binary files differ
diff --git a/fuzzer/corpus/d85d0dbc6d67ee1b69bb8f11fffea1344495c3fa b/fuzzer/corpus/d85d0dbc6d67ee1b69bb8f11fffea1344495c3fa
new file mode 100644
index 0000000..0d954b7
--- /dev/null
+++ b/fuzzer/corpus/d85d0dbc6d67ee1b69bb8f11fffea1344495c3fa
Binary files differ
diff --git a/fuzzer/corpus/d864846a65c1be4a0b06984516b29685eb907070 b/fuzzer/corpus/d864846a65c1be4a0b06984516b29685eb907070
new file mode 100644
index 0000000..1e55b4f
--- /dev/null
+++ b/fuzzer/corpus/d864846a65c1be4a0b06984516b29685eb907070
Binary files differ
diff --git a/fuzzer/corpus/d875368bcdd75d662c93d2c537bffbdb72804a9a b/fuzzer/corpus/d875368bcdd75d662c93d2c537bffbdb72804a9a
new file mode 100644
index 0000000..534c655
--- /dev/null
+++ b/fuzzer/corpus/d875368bcdd75d662c93d2c537bffbdb72804a9a
Binary files differ
diff --git a/fuzzer/corpus/d888a39eec6a74844416f80fe9668322a2a8a0f8 b/fuzzer/corpus/d888a39eec6a74844416f80fe9668322a2a8a0f8
new file mode 100644
index 0000000..397d206
--- /dev/null
+++ b/fuzzer/corpus/d888a39eec6a74844416f80fe9668322a2a8a0f8
Binary files differ
diff --git a/fuzzer/corpus/d8a5e06f53da63007f410198d8700d6f3b15c75f b/fuzzer/corpus/d8a5e06f53da63007f410198d8700d6f3b15c75f
new file mode 100644
index 0000000..db36473
--- /dev/null
+++ b/fuzzer/corpus/d8a5e06f53da63007f410198d8700d6f3b15c75f
Binary files differ
diff --git a/fuzzer/corpus/d8ae193f4f67eb2cdde635220cfcacab0ae8d0b4 b/fuzzer/corpus/d8ae193f4f67eb2cdde635220cfcacab0ae8d0b4
new file mode 100644
index 0000000..a5d2e57
--- /dev/null
+++ b/fuzzer/corpus/d8ae193f4f67eb2cdde635220cfcacab0ae8d0b4
Binary files differ
diff --git a/fuzzer/corpus/d8e44ed28873a3a02c9261988940227a3c8f5584 b/fuzzer/corpus/d8e44ed28873a3a02c9261988940227a3c8f5584
new file mode 100644
index 0000000..9c879aa
--- /dev/null
+++ b/fuzzer/corpus/d8e44ed28873a3a02c9261988940227a3c8f5584
Binary files differ
diff --git a/fuzzer/corpus/d93fd9291ee9aac39f3e0aa9a0df6bbedc80f69f b/fuzzer/corpus/d93fd9291ee9aac39f3e0aa9a0df6bbedc80f69f
new file mode 100644
index 0000000..6af9c25
--- /dev/null
+++ b/fuzzer/corpus/d93fd9291ee9aac39f3e0aa9a0df6bbedc80f69f
Binary files differ
diff --git a/fuzzer/corpus/d960c0eab8fe08c08ff247c19ad0cd8bd2635ca3 b/fuzzer/corpus/d960c0eab8fe08c08ff247c19ad0cd8bd2635ca3
new file mode 100644
index 0000000..58180f3
--- /dev/null
+++ b/fuzzer/corpus/d960c0eab8fe08c08ff247c19ad0cd8bd2635ca3
Binary files differ
diff --git a/fuzzer/corpus/d9854c46ebc5b99048ac9fd9b0aa810f416dd43d b/fuzzer/corpus/d9854c46ebc5b99048ac9fd9b0aa810f416dd43d
new file mode 100644
index 0000000..d265093
--- /dev/null
+++ b/fuzzer/corpus/d9854c46ebc5b99048ac9fd9b0aa810f416dd43d
Binary files differ
diff --git a/fuzzer/corpus/d9a48b14aa054ecfde4b93c433cd84b58538725e b/fuzzer/corpus/d9a48b14aa054ecfde4b93c433cd84b58538725e
new file mode 100644
index 0000000..8844cc6
--- /dev/null
+++ b/fuzzer/corpus/d9a48b14aa054ecfde4b93c433cd84b58538725e
Binary files differ
diff --git a/fuzzer/corpus/d9cae8d7f17912fa57ec6c5218424f50f0f83304 b/fuzzer/corpus/d9cae8d7f17912fa57ec6c5218424f50f0f83304
new file mode 100644
index 0000000..bb93570
--- /dev/null
+++ b/fuzzer/corpus/d9cae8d7f17912fa57ec6c5218424f50f0f83304
Binary files differ
diff --git a/fuzzer/corpus/d9da15e86526870a5de3d3596c857070dd1a6a78 b/fuzzer/corpus/d9da15e86526870a5de3d3596c857070dd1a6a78
new file mode 100644
index 0000000..19ffc86
--- /dev/null
+++ b/fuzzer/corpus/d9da15e86526870a5de3d3596c857070dd1a6a78
Binary files differ
diff --git a/fuzzer/corpus/d9f5164820147fa6e1b7cf28b949053a82095107 b/fuzzer/corpus/d9f5164820147fa6e1b7cf28b949053a82095107
new file mode 100644
index 0000000..53b6139
--- /dev/null
+++ b/fuzzer/corpus/d9f5164820147fa6e1b7cf28b949053a82095107
Binary files differ
diff --git a/fuzzer/corpus/d9fe9965084aad0081d5fb1bb858e85e2ad6cb16 b/fuzzer/corpus/d9fe9965084aad0081d5fb1bb858e85e2ad6cb16
new file mode 100644
index 0000000..acdf53d
--- /dev/null
+++ b/fuzzer/corpus/d9fe9965084aad0081d5fb1bb858e85e2ad6cb16
Binary files differ
diff --git a/fuzzer/corpus/da07a113b6b3cf701919895ed621d2093228505a b/fuzzer/corpus/da07a113b6b3cf701919895ed621d2093228505a
new file mode 100644
index 0000000..5a8eec8
--- /dev/null
+++ b/fuzzer/corpus/da07a113b6b3cf701919895ed621d2093228505a
Binary files differ
diff --git a/fuzzer/corpus/da0da68a82c7bd3a0f097260704aea9f63041f09 b/fuzzer/corpus/da0da68a82c7bd3a0f097260704aea9f63041f09
new file mode 100644
index 0000000..deeb949
--- /dev/null
+++ b/fuzzer/corpus/da0da68a82c7bd3a0f097260704aea9f63041f09
Binary files differ
diff --git a/fuzzer/corpus/da1002d28c0f1a51565f64a79e6231549089222d b/fuzzer/corpus/da1002d28c0f1a51565f64a79e6231549089222d
new file mode 100644
index 0000000..91aa133
--- /dev/null
+++ b/fuzzer/corpus/da1002d28c0f1a51565f64a79e6231549089222d
Binary files differ
diff --git a/fuzzer/corpus/da1bfd406502ee8361aceca8926c68f681f72fcc b/fuzzer/corpus/da1bfd406502ee8361aceca8926c68f681f72fcc
new file mode 100644
index 0000000..5a070e8
--- /dev/null
+++ b/fuzzer/corpus/da1bfd406502ee8361aceca8926c68f681f72fcc
Binary files differ
diff --git a/fuzzer/corpus/da2f13f5261c8d49e338e9edee8bda0853b1acc9 b/fuzzer/corpus/da2f13f5261c8d49e338e9edee8bda0853b1acc9
new file mode 100644
index 0000000..da91baa
--- /dev/null
+++ b/fuzzer/corpus/da2f13f5261c8d49e338e9edee8bda0853b1acc9
Binary files differ
diff --git a/fuzzer/corpus/da7efb8ab79b6782d364ff2ab03b55944d11460c b/fuzzer/corpus/da7efb8ab79b6782d364ff2ab03b55944d11460c
new file mode 100644
index 0000000..313ffa6
--- /dev/null
+++ b/fuzzer/corpus/da7efb8ab79b6782d364ff2ab03b55944d11460c
Binary files differ
diff --git a/fuzzer/corpus/da950c304829b8c0b5f89cebd3dc17a600d1e36b b/fuzzer/corpus/da950c304829b8c0b5f89cebd3dc17a600d1e36b
new file mode 100644
index 0000000..6869f06
--- /dev/null
+++ b/fuzzer/corpus/da950c304829b8c0b5f89cebd3dc17a600d1e36b
Binary files differ
diff --git a/fuzzer/corpus/da99db29fd53d20ca815d4dd60822ac52a702cda b/fuzzer/corpus/da99db29fd53d20ca815d4dd60822ac52a702cda
new file mode 100644
index 0000000..9f9183a
--- /dev/null
+++ b/fuzzer/corpus/da99db29fd53d20ca815d4dd60822ac52a702cda
Binary files differ
diff --git a/fuzzer/corpus/daa4fa2885909ad7ffc983c60643a44ac90ca4cc b/fuzzer/corpus/daa4fa2885909ad7ffc983c60643a44ac90ca4cc
new file mode 100644
index 0000000..0c13733
--- /dev/null
+++ b/fuzzer/corpus/daa4fa2885909ad7ffc983c60643a44ac90ca4cc
Binary files differ
diff --git a/fuzzer/corpus/daa92ea4600a8737e9fd37f83a9c852f545537c2 b/fuzzer/corpus/daa92ea4600a8737e9fd37f83a9c852f545537c2
new file mode 100644
index 0000000..a840fa9
--- /dev/null
+++ b/fuzzer/corpus/daa92ea4600a8737e9fd37f83a9c852f545537c2
Binary files differ
diff --git a/fuzzer/corpus/dacc18e91c81a6bfcba0340ecb58bba6556e57eb b/fuzzer/corpus/dacc18e91c81a6bfcba0340ecb58bba6556e57eb
new file mode 100644
index 0000000..c56440e
--- /dev/null
+++ b/fuzzer/corpus/dacc18e91c81a6bfcba0340ecb58bba6556e57eb
Binary files differ
diff --git a/fuzzer/corpus/db1d12798a20e9035b9a5abf805394c855059313 b/fuzzer/corpus/db1d12798a20e9035b9a5abf805394c855059313
new file mode 100644
index 0000000..f059412
--- /dev/null
+++ b/fuzzer/corpus/db1d12798a20e9035b9a5abf805394c855059313
Binary files differ
diff --git a/fuzzer/corpus/db7c8b0d344767d301a3b076919f6c36fa53193d b/fuzzer/corpus/db7c8b0d344767d301a3b076919f6c36fa53193d
new file mode 100644
index 0000000..7b8891e
--- /dev/null
+++ b/fuzzer/corpus/db7c8b0d344767d301a3b076919f6c36fa53193d
Binary files differ
diff --git a/fuzzer/corpus/db903aaf171f26afaa2f67bb24c000d7bec621d8 b/fuzzer/corpus/db903aaf171f26afaa2f67bb24c000d7bec621d8
new file mode 100644
index 0000000..d4cc8d4
--- /dev/null
+++ b/fuzzer/corpus/db903aaf171f26afaa2f67bb24c000d7bec621d8
Binary files differ
diff --git a/fuzzer/corpus/dbadd3f18ba2c307ca91180fe4aeb1b4580bcca7 b/fuzzer/corpus/dbadd3f18ba2c307ca91180fe4aeb1b4580bcca7
new file mode 100644
index 0000000..077d365
--- /dev/null
+++ b/fuzzer/corpus/dbadd3f18ba2c307ca91180fe4aeb1b4580bcca7
Binary files differ
diff --git a/fuzzer/corpus/dbb4f3bc0bb09722267e7d0969d2ec0d9b1e085a b/fuzzer/corpus/dbb4f3bc0bb09722267e7d0969d2ec0d9b1e085a
new file mode 100644
index 0000000..61de24c
--- /dev/null
+++ b/fuzzer/corpus/dbb4f3bc0bb09722267e7d0969d2ec0d9b1e085a
Binary files differ
diff --git a/fuzzer/corpus/dbc2b27e3cbb9fed8d92c7c60b25fd2a64bdc9ee b/fuzzer/corpus/dbc2b27e3cbb9fed8d92c7c60b25fd2a64bdc9ee
new file mode 100644
index 0000000..883dd61
--- /dev/null
+++ b/fuzzer/corpus/dbc2b27e3cbb9fed8d92c7c60b25fd2a64bdc9ee
Binary files differ
diff --git a/fuzzer/corpus/dbeefe004d68f9ffa8e45b64362c6737b22e3de5 b/fuzzer/corpus/dbeefe004d68f9ffa8e45b64362c6737b22e3de5
new file mode 100644
index 0000000..2fd66ba
--- /dev/null
+++ b/fuzzer/corpus/dbeefe004d68f9ffa8e45b64362c6737b22e3de5
Binary files differ
diff --git a/fuzzer/corpus/dbf50cbbad010e57d112f069929e50a8e6800b27 b/fuzzer/corpus/dbf50cbbad010e57d112f069929e50a8e6800b27
new file mode 100644
index 0000000..7935584
--- /dev/null
+++ b/fuzzer/corpus/dbf50cbbad010e57d112f069929e50a8e6800b27
Binary files differ
diff --git a/fuzzer/corpus/dc0ce718c3648df982b66a8d17ba07554dad528b b/fuzzer/corpus/dc0ce718c3648df982b66a8d17ba07554dad528b
new file mode 100644
index 0000000..c41131c
--- /dev/null
+++ b/fuzzer/corpus/dc0ce718c3648df982b66a8d17ba07554dad528b
Binary files differ
diff --git a/fuzzer/corpus/dc48283fd7e9ac4b61c740457f288a6e7e4b9f35 b/fuzzer/corpus/dc48283fd7e9ac4b61c740457f288a6e7e4b9f35
new file mode 100644
index 0000000..8628c5c
--- /dev/null
+++ b/fuzzer/corpus/dc48283fd7e9ac4b61c740457f288a6e7e4b9f35
Binary files differ
diff --git a/fuzzer/corpus/dc68425075dfef8c3146f582479ea22a7a5723ab b/fuzzer/corpus/dc68425075dfef8c3146f582479ea22a7a5723ab
new file mode 100644
index 0000000..8e4e65d
--- /dev/null
+++ b/fuzzer/corpus/dc68425075dfef8c3146f582479ea22a7a5723ab
Binary files differ
diff --git a/fuzzer/corpus/dc6c395aa0dea86ac6ba8b3ff4a076e99d528f32 b/fuzzer/corpus/dc6c395aa0dea86ac6ba8b3ff4a076e99d528f32
new file mode 100644
index 0000000..ad6fe2e
--- /dev/null
+++ b/fuzzer/corpus/dc6c395aa0dea86ac6ba8b3ff4a076e99d528f32
Binary files differ
diff --git a/fuzzer/corpus/dc7287b83a08942f085ff81b5e6e155a9327e749 b/fuzzer/corpus/dc7287b83a08942f085ff81b5e6e155a9327e749
new file mode 100644
index 0000000..4ff3fcb
--- /dev/null
+++ b/fuzzer/corpus/dc7287b83a08942f085ff81b5e6e155a9327e749
Binary files differ
diff --git a/fuzzer/corpus/dc89fb2b8158788bca28632748593e14c1f10587 b/fuzzer/corpus/dc89fb2b8158788bca28632748593e14c1f10587
new file mode 100644
index 0000000..8efae66
--- /dev/null
+++ b/fuzzer/corpus/dc89fb2b8158788bca28632748593e14c1f10587
Binary files differ
diff --git a/fuzzer/corpus/dc8cfe2221ad910e170cedf09671c9292a09bbf0 b/fuzzer/corpus/dc8cfe2221ad910e170cedf09671c9292a09bbf0
new file mode 100644
index 0000000..43c590b
--- /dev/null
+++ b/fuzzer/corpus/dc8cfe2221ad910e170cedf09671c9292a09bbf0
Binary files differ
diff --git a/fuzzer/corpus/dc907469f9e0fc79c4a0eecfa8cebf5e3eeb8534 b/fuzzer/corpus/dc907469f9e0fc79c4a0eecfa8cebf5e3eeb8534
new file mode 100644
index 0000000..a0fef47
--- /dev/null
+++ b/fuzzer/corpus/dc907469f9e0fc79c4a0eecfa8cebf5e3eeb8534
Binary files differ
diff --git a/fuzzer/corpus/dca6505d695c2a0e7247ff2dee70ffaea4bc7c0d b/fuzzer/corpus/dca6505d695c2a0e7247ff2dee70ffaea4bc7c0d
new file mode 100644
index 0000000..bd5da74
--- /dev/null
+++ b/fuzzer/corpus/dca6505d695c2a0e7247ff2dee70ffaea4bc7c0d
Binary files differ
diff --git a/fuzzer/corpus/dcb501fbbb94c31e2be960dc4898b3aa252310a7 b/fuzzer/corpus/dcb501fbbb94c31e2be960dc4898b3aa252310a7
new file mode 100644
index 0000000..2b39e99
--- /dev/null
+++ b/fuzzer/corpus/dcb501fbbb94c31e2be960dc4898b3aa252310a7
Binary files differ
diff --git a/fuzzer/corpus/dcff5752df020ec00d95f49f463d66f9dc49d7d5 b/fuzzer/corpus/dcff5752df020ec00d95f49f463d66f9dc49d7d5
new file mode 100644
index 0000000..8e9755e
--- /dev/null
+++ b/fuzzer/corpus/dcff5752df020ec00d95f49f463d66f9dc49d7d5
Binary files differ
diff --git a/fuzzer/corpus/dd04c9200f6068173671eeec932444f83efd80ac b/fuzzer/corpus/dd04c9200f6068173671eeec932444f83efd80ac
new file mode 100644
index 0000000..4510881
--- /dev/null
+++ b/fuzzer/corpus/dd04c9200f6068173671eeec932444f83efd80ac
Binary files differ
diff --git a/fuzzer/corpus/dd0e12e170d32c6f7aa8c5729d258ed2e02acf6a b/fuzzer/corpus/dd0e12e170d32c6f7aa8c5729d258ed2e02acf6a
new file mode 100644
index 0000000..aa48a53
--- /dev/null
+++ b/fuzzer/corpus/dd0e12e170d32c6f7aa8c5729d258ed2e02acf6a
Binary files differ
diff --git a/fuzzer/corpus/dd655371b3af77e124d99d4c34e545b0355a0f02 b/fuzzer/corpus/dd655371b3af77e124d99d4c34e545b0355a0f02
new file mode 100644
index 0000000..9e35468
--- /dev/null
+++ b/fuzzer/corpus/dd655371b3af77e124d99d4c34e545b0355a0f02
Binary files differ
diff --git a/fuzzer/corpus/dd6b6aa89f2f1c46e60e86ea705720bc5f44fcc7 b/fuzzer/corpus/dd6b6aa89f2f1c46e60e86ea705720bc5f44fcc7
new file mode 100644
index 0000000..d3200a5
--- /dev/null
+++ b/fuzzer/corpus/dd6b6aa89f2f1c46e60e86ea705720bc5f44fcc7
Binary files differ
diff --git a/fuzzer/corpus/dda0cdaab12c354534d015fcd77d7c0f0f8a9fe3 b/fuzzer/corpus/dda0cdaab12c354534d015fcd77d7c0f0f8a9fe3
new file mode 100644
index 0000000..3c3167b
--- /dev/null
+++ b/fuzzer/corpus/dda0cdaab12c354534d015fcd77d7c0f0f8a9fe3
Binary files differ
diff --git a/fuzzer/corpus/ddb0b04c9ceafdc0295f8489665a32ab0ea10f25 b/fuzzer/corpus/ddb0b04c9ceafdc0295f8489665a32ab0ea10f25
new file mode 100644
index 0000000..d0acef2
--- /dev/null
+++ b/fuzzer/corpus/ddb0b04c9ceafdc0295f8489665a32ab0ea10f25
Binary files differ
diff --git a/fuzzer/corpus/ddb8b2d424ece63cf6467b9a0f616749bf091469 b/fuzzer/corpus/ddb8b2d424ece63cf6467b9a0f616749bf091469
new file mode 100644
index 0000000..07b0848
--- /dev/null
+++ b/fuzzer/corpus/ddb8b2d424ece63cf6467b9a0f616749bf091469
Binary files differ
diff --git a/fuzzer/corpus/ddcfa3fe1e0c57792fc3bb8dae41142a8a1ca29f b/fuzzer/corpus/ddcfa3fe1e0c57792fc3bb8dae41142a8a1ca29f
new file mode 100644
index 0000000..089ac54
--- /dev/null
+++ b/fuzzer/corpus/ddcfa3fe1e0c57792fc3bb8dae41142a8a1ca29f
Binary files differ
diff --git a/fuzzer/corpus/de12ea7a0a4d6eca893b8b990a4a4f9342decc0e b/fuzzer/corpus/de12ea7a0a4d6eca893b8b990a4a4f9342decc0e
new file mode 100644
index 0000000..07bc043
--- /dev/null
+++ b/fuzzer/corpus/de12ea7a0a4d6eca893b8b990a4a4f9342decc0e
Binary files differ
diff --git a/fuzzer/corpus/de20009e5dd442964c04154d85910e7059e084b9 b/fuzzer/corpus/de20009e5dd442964c04154d85910e7059e084b9
new file mode 100644
index 0000000..b736850
--- /dev/null
+++ b/fuzzer/corpus/de20009e5dd442964c04154d85910e7059e084b9
Binary files differ
diff --git a/fuzzer/corpus/de5eb0d67c436883a0089b189ddaa11df92c965c b/fuzzer/corpus/de5eb0d67c436883a0089b189ddaa11df92c965c
new file mode 100644
index 0000000..c6ea9e5
--- /dev/null
+++ b/fuzzer/corpus/de5eb0d67c436883a0089b189ddaa11df92c965c
Binary files differ
diff --git a/fuzzer/corpus/de84d2616593dddce2f28615e28c0c72f746de9d b/fuzzer/corpus/de84d2616593dddce2f28615e28c0c72f746de9d
new file mode 100644
index 0000000..0a625ef
--- /dev/null
+++ b/fuzzer/corpus/de84d2616593dddce2f28615e28c0c72f746de9d
Binary files differ
diff --git a/fuzzer/corpus/de9259b73a79b875b3e20ce9fda7647a45d6ba26 b/fuzzer/corpus/de9259b73a79b875b3e20ce9fda7647a45d6ba26
new file mode 100644
index 0000000..a0dd1c3
--- /dev/null
+++ b/fuzzer/corpus/de9259b73a79b875b3e20ce9fda7647a45d6ba26
Binary files differ
diff --git a/fuzzer/corpus/ded0e3fce4f5a1c5572ce632a29adcf37897881f b/fuzzer/corpus/ded0e3fce4f5a1c5572ce632a29adcf37897881f
new file mode 100644
index 0000000..1bf146f
--- /dev/null
+++ b/fuzzer/corpus/ded0e3fce4f5a1c5572ce632a29adcf37897881f
Binary files differ
diff --git a/fuzzer/corpus/dee7c3e7cac3ebd62b0de576789c0ed0129e5d2c b/fuzzer/corpus/dee7c3e7cac3ebd62b0de576789c0ed0129e5d2c
new file mode 100644
index 0000000..bcbbe6b
--- /dev/null
+++ b/fuzzer/corpus/dee7c3e7cac3ebd62b0de576789c0ed0129e5d2c
Binary files differ
diff --git a/fuzzer/corpus/def4bb0f286f7c45281a035b558581b327e505f7 b/fuzzer/corpus/def4bb0f286f7c45281a035b558581b327e505f7
new file mode 100644
index 0000000..a1f3540
--- /dev/null
+++ b/fuzzer/corpus/def4bb0f286f7c45281a035b558581b327e505f7
Binary files differ
diff --git a/fuzzer/corpus/df2cff3e2d1845b09e31e2e99b50fe3aef5da229 b/fuzzer/corpus/df2cff3e2d1845b09e31e2e99b50fe3aef5da229
new file mode 100644
index 0000000..548c3da
--- /dev/null
+++ b/fuzzer/corpus/df2cff3e2d1845b09e31e2e99b50fe3aef5da229
Binary files differ
diff --git a/fuzzer/corpus/df2fa8b9efa11a9511dfeb146446f597bd82b6dd b/fuzzer/corpus/df2fa8b9efa11a9511dfeb146446f597bd82b6dd
new file mode 100644
index 0000000..443a6ab
--- /dev/null
+++ b/fuzzer/corpus/df2fa8b9efa11a9511dfeb146446f597bd82b6dd
Binary files differ
diff --git a/fuzzer/corpus/df4c7b880af9427c854b76c0d11f60c340a0a922 b/fuzzer/corpus/df4c7b880af9427c854b76c0d11f60c340a0a922
new file mode 100644
index 0000000..2b7e098
--- /dev/null
+++ b/fuzzer/corpus/df4c7b880af9427c854b76c0d11f60c340a0a922
Binary files differ
diff --git a/fuzzer/corpus/df74057846da618e308c75b9389616d125845bba b/fuzzer/corpus/df74057846da618e308c75b9389616d125845bba
new file mode 100644
index 0000000..ffcf9a5
--- /dev/null
+++ b/fuzzer/corpus/df74057846da618e308c75b9389616d125845bba
Binary files differ
diff --git a/fuzzer/corpus/df8087a243ae78d551a128d812ea8336a3042f75 b/fuzzer/corpus/df8087a243ae78d551a128d812ea8336a3042f75
new file mode 100644
index 0000000..348cfd3
--- /dev/null
+++ b/fuzzer/corpus/df8087a243ae78d551a128d812ea8336a3042f75
Binary files differ
diff --git a/fuzzer/corpus/df9f04b41873b05b7485b379b40f126e9915d9f0 b/fuzzer/corpus/df9f04b41873b05b7485b379b40f126e9915d9f0
new file mode 100644
index 0000000..8310ac8
--- /dev/null
+++ b/fuzzer/corpus/df9f04b41873b05b7485b379b40f126e9915d9f0
Binary files differ
diff --git a/fuzzer/corpus/dfac03fb3798072a55d8ccf0f28ef4f81c3ca355 b/fuzzer/corpus/dfac03fb3798072a55d8ccf0f28ef4f81c3ca355
new file mode 100644
index 0000000..3e4e887
--- /dev/null
+++ b/fuzzer/corpus/dfac03fb3798072a55d8ccf0f28ef4f81c3ca355
Binary files differ
diff --git a/fuzzer/corpus/dfbca3b91615e12cbdfdf2d302c2411137eaec86 b/fuzzer/corpus/dfbca3b91615e12cbdfdf2d302c2411137eaec86
new file mode 100644
index 0000000..48c9de0
--- /dev/null
+++ b/fuzzer/corpus/dfbca3b91615e12cbdfdf2d302c2411137eaec86
Binary files differ
diff --git a/fuzzer/corpus/dfbff6b133d07b84b48b20402c1dfa295735f144 b/fuzzer/corpus/dfbff6b133d07b84b48b20402c1dfa295735f144
new file mode 100644
index 0000000..3bc3a57
--- /dev/null
+++ b/fuzzer/corpus/dfbff6b133d07b84b48b20402c1dfa295735f144
Binary files differ
diff --git a/fuzzer/corpus/dfc459b99d0e933191615817e735395cc2f8b6c1 b/fuzzer/corpus/dfc459b99d0e933191615817e735395cc2f8b6c1
new file mode 100644
index 0000000..2ea6472
--- /dev/null
+++ b/fuzzer/corpus/dfc459b99d0e933191615817e735395cc2f8b6c1
Binary files differ
diff --git a/fuzzer/corpus/dfca552d0a2f6b45984b31d8644eed7aa205af71 b/fuzzer/corpus/dfca552d0a2f6b45984b31d8644eed7aa205af71
new file mode 100644
index 0000000..673a6f7
--- /dev/null
+++ b/fuzzer/corpus/dfca552d0a2f6b45984b31d8644eed7aa205af71
Binary files differ
diff --git a/fuzzer/corpus/dffea25836343414ddf96e76d8853c21819b5fee b/fuzzer/corpus/dffea25836343414ddf96e76d8853c21819b5fee
new file mode 100644
index 0000000..a33974a
--- /dev/null
+++ b/fuzzer/corpus/dffea25836343414ddf96e76d8853c21819b5fee
Binary files differ
diff --git a/fuzzer/corpus/e02da98090daa0d3e750cc83581cbe8843d25acd b/fuzzer/corpus/e02da98090daa0d3e750cc83581cbe8843d25acd
new file mode 100644
index 0000000..ed1fa82
--- /dev/null
+++ b/fuzzer/corpus/e02da98090daa0d3e750cc83581cbe8843d25acd
Binary files differ
diff --git a/fuzzer/corpus/e0347261cfbdee5566c1188b107b40329039cd8f b/fuzzer/corpus/e0347261cfbdee5566c1188b107b40329039cd8f
new file mode 100644
index 0000000..2619ad4
--- /dev/null
+++ b/fuzzer/corpus/e0347261cfbdee5566c1188b107b40329039cd8f
Binary files differ
diff --git a/fuzzer/corpus/e05959e65d29bd2833ff854b5421d8d7d802a49a b/fuzzer/corpus/e05959e65d29bd2833ff854b5421d8d7d802a49a
new file mode 100644
index 0000000..6327a39
--- /dev/null
+++ b/fuzzer/corpus/e05959e65d29bd2833ff854b5421d8d7d802a49a
Binary files differ
diff --git a/fuzzer/corpus/e06bf2dfcf2fa17f033f9cc3f763107b9e07c715 b/fuzzer/corpus/e06bf2dfcf2fa17f033f9cc3f763107b9e07c715
new file mode 100644
index 0000000..652bc8b
--- /dev/null
+++ b/fuzzer/corpus/e06bf2dfcf2fa17f033f9cc3f763107b9e07c715
Binary files differ
diff --git a/fuzzer/corpus/e06d264feb90a182320761ca936fc35887dba84a b/fuzzer/corpus/e06d264feb90a182320761ca936fc35887dba84a
new file mode 100644
index 0000000..d0cea61
--- /dev/null
+++ b/fuzzer/corpus/e06d264feb90a182320761ca936fc35887dba84a
Binary files differ
diff --git a/fuzzer/corpus/e09c5721b6c55681eee5481a476f4d1ffe8f56c3 b/fuzzer/corpus/e09c5721b6c55681eee5481a476f4d1ffe8f56c3
new file mode 100644
index 0000000..0de0d6a
--- /dev/null
+++ b/fuzzer/corpus/e09c5721b6c55681eee5481a476f4d1ffe8f56c3
Binary files differ
diff --git a/fuzzer/corpus/e0ba21767e10ff2bffafb1fe90ebd6ffdd8bc6b8 b/fuzzer/corpus/e0ba21767e10ff2bffafb1fe90ebd6ffdd8bc6b8
new file mode 100644
index 0000000..fbd9813
--- /dev/null
+++ b/fuzzer/corpus/e0ba21767e10ff2bffafb1fe90ebd6ffdd8bc6b8
Binary files differ
diff --git a/fuzzer/corpus/e1263d4e0e1ed6868a4e4168a620e6f893358213 b/fuzzer/corpus/e1263d4e0e1ed6868a4e4168a620e6f893358213
new file mode 100644
index 0000000..f06e91b
--- /dev/null
+++ b/fuzzer/corpus/e1263d4e0e1ed6868a4e4168a620e6f893358213
Binary files differ
diff --git a/fuzzer/corpus/e1724c8cb267c6efd73dddea9cf6facd5c561e68 b/fuzzer/corpus/e1724c8cb267c6efd73dddea9cf6facd5c561e68
new file mode 100644
index 0000000..432b959
--- /dev/null
+++ b/fuzzer/corpus/e1724c8cb267c6efd73dddea9cf6facd5c561e68
Binary files differ
diff --git a/fuzzer/corpus/e187531dae9a9095709353882ed7d298b43f8551 b/fuzzer/corpus/e187531dae9a9095709353882ed7d298b43f8551
new file mode 100644
index 0000000..722669b
--- /dev/null
+++ b/fuzzer/corpus/e187531dae9a9095709353882ed7d298b43f8551
Binary files differ
diff --git a/fuzzer/corpus/e1bb1e140c9c63c1c36cf54a3a62da93c14fbafb b/fuzzer/corpus/e1bb1e140c9c63c1c36cf54a3a62da93c14fbafb
new file mode 100644
index 0000000..caa234c
--- /dev/null
+++ b/fuzzer/corpus/e1bb1e140c9c63c1c36cf54a3a62da93c14fbafb
Binary files differ
diff --git a/fuzzer/corpus/e1cf89658b836d3f662012d3d2a288d5da975993 b/fuzzer/corpus/e1cf89658b836d3f662012d3d2a288d5da975993
new file mode 100644
index 0000000..2027872
--- /dev/null
+++ b/fuzzer/corpus/e1cf89658b836d3f662012d3d2a288d5da975993
Binary files differ
diff --git a/fuzzer/corpus/e1d7d8013afbdab4d3989b86d781dbf513bf5839 b/fuzzer/corpus/e1d7d8013afbdab4d3989b86d781dbf513bf5839
new file mode 100644
index 0000000..148d613
--- /dev/null
+++ b/fuzzer/corpus/e1d7d8013afbdab4d3989b86d781dbf513bf5839
Binary files differ
diff --git a/fuzzer/corpus/e227f418bbc10b012cab197e463e8dae45853356 b/fuzzer/corpus/e227f418bbc10b012cab197e463e8dae45853356
new file mode 100644
index 0000000..269d74d
--- /dev/null
+++ b/fuzzer/corpus/e227f418bbc10b012cab197e463e8dae45853356
Binary files differ
diff --git a/fuzzer/corpus/e2554b800d5d37c9e508155ebcbceec3793fe6d0 b/fuzzer/corpus/e2554b800d5d37c9e508155ebcbceec3793fe6d0
new file mode 100644
index 0000000..da272e2
--- /dev/null
+++ b/fuzzer/corpus/e2554b800d5d37c9e508155ebcbceec3793fe6d0
Binary files differ
diff --git a/fuzzer/corpus/e263798e59a5d270abf73edaa624be0700242a53 b/fuzzer/corpus/e263798e59a5d270abf73edaa624be0700242a53
new file mode 100644
index 0000000..a145618
--- /dev/null
+++ b/fuzzer/corpus/e263798e59a5d270abf73edaa624be0700242a53
Binary files differ
diff --git a/fuzzer/corpus/e26a332fc58db1c372fcb67697bcad0ec6b2664f b/fuzzer/corpus/e26a332fc58db1c372fcb67697bcad0ec6b2664f
new file mode 100644
index 0000000..a71030e
--- /dev/null
+++ b/fuzzer/corpus/e26a332fc58db1c372fcb67697bcad0ec6b2664f
Binary files differ
diff --git a/fuzzer/corpus/e27b58f72661df12161b25eb208a2dd380e00058 b/fuzzer/corpus/e27b58f72661df12161b25eb208a2dd380e00058
new file mode 100644
index 0000000..cf0fd5e
--- /dev/null
+++ b/fuzzer/corpus/e27b58f72661df12161b25eb208a2dd380e00058
Binary files differ
diff --git a/fuzzer/corpus/e2e9d9a7e4578a32921a8704d6352067a2a1cf14 b/fuzzer/corpus/e2e9d9a7e4578a32921a8704d6352067a2a1cf14
new file mode 100644
index 0000000..8eda506
--- /dev/null
+++ b/fuzzer/corpus/e2e9d9a7e4578a32921a8704d6352067a2a1cf14
Binary files differ
diff --git a/fuzzer/corpus/e2ff946658b253ef36ea36da4b4c869b46e0308d b/fuzzer/corpus/e2ff946658b253ef36ea36da4b4c869b46e0308d
new file mode 100644
index 0000000..888b2d5
--- /dev/null
+++ b/fuzzer/corpus/e2ff946658b253ef36ea36da4b4c869b46e0308d
Binary files differ
diff --git a/fuzzer/corpus/e3062519c6b0bfe605e4247d493c8efaddee6b97 b/fuzzer/corpus/e3062519c6b0bfe605e4247d493c8efaddee6b97
new file mode 100644
index 0000000..7f82e6d
--- /dev/null
+++ b/fuzzer/corpus/e3062519c6b0bfe605e4247d493c8efaddee6b97
Binary files differ
diff --git a/fuzzer/corpus/e30d49ee6f7ead7b4f24b8fcb88792b4c521d4a1 b/fuzzer/corpus/e30d49ee6f7ead7b4f24b8fcb88792b4c521d4a1
new file mode 100644
index 0000000..1bd47e4
--- /dev/null
+++ b/fuzzer/corpus/e30d49ee6f7ead7b4f24b8fcb88792b4c521d4a1
Binary files differ
diff --git a/fuzzer/corpus/e313b472b8e3780b2d77b1394ea1cb191f028896 b/fuzzer/corpus/e313b472b8e3780b2d77b1394ea1cb191f028896
new file mode 100644
index 0000000..99b56a6
--- /dev/null
+++ b/fuzzer/corpus/e313b472b8e3780b2d77b1394ea1cb191f028896
Binary files differ
diff --git a/fuzzer/corpus/e315fca490e48b2e33f0ff395fd359f9befc2132 b/fuzzer/corpus/e315fca490e48b2e33f0ff395fd359f9befc2132
new file mode 100644
index 0000000..a7b006f
--- /dev/null
+++ b/fuzzer/corpus/e315fca490e48b2e33f0ff395fd359f9befc2132
Binary files differ
diff --git a/fuzzer/corpus/e3261856e55ec4324076b259314dce283739c4d4 b/fuzzer/corpus/e3261856e55ec4324076b259314dce283739c4d4
new file mode 100644
index 0000000..42c7252
--- /dev/null
+++ b/fuzzer/corpus/e3261856e55ec4324076b259314dce283739c4d4
Binary files differ
diff --git a/fuzzer/corpus/e33c7989843428aa27bea82df1d7144112034a1d b/fuzzer/corpus/e33c7989843428aa27bea82df1d7144112034a1d
new file mode 100644
index 0000000..4efdc6c
--- /dev/null
+++ b/fuzzer/corpus/e33c7989843428aa27bea82df1d7144112034a1d
Binary files differ
diff --git a/fuzzer/corpus/e342a3e59590671c6d6437c42cb537751085d03d b/fuzzer/corpus/e342a3e59590671c6d6437c42cb537751085d03d
new file mode 100644
index 0000000..e2a55d4
--- /dev/null
+++ b/fuzzer/corpus/e342a3e59590671c6d6437c42cb537751085d03d
Binary files differ
diff --git a/fuzzer/corpus/e3692bc33b8a25a54b8cf31d374056bb958d6f9c b/fuzzer/corpus/e3692bc33b8a25a54b8cf31d374056bb958d6f9c
new file mode 100644
index 0000000..372ed54
--- /dev/null
+++ b/fuzzer/corpus/e3692bc33b8a25a54b8cf31d374056bb958d6f9c
Binary files differ
diff --git a/fuzzer/corpus/e3837c6d2e4cf4041061e1c10f1f873fc3e162f7 b/fuzzer/corpus/e3837c6d2e4cf4041061e1c10f1f873fc3e162f7
new file mode 100644
index 0000000..5c76d0c
--- /dev/null
+++ b/fuzzer/corpus/e3837c6d2e4cf4041061e1c10f1f873fc3e162f7
Binary files differ
diff --git a/fuzzer/corpus/e4189007af713f980b50c47f1e4794725c57a1de b/fuzzer/corpus/e4189007af713f980b50c47f1e4794725c57a1de
new file mode 100644
index 0000000..23cf826
--- /dev/null
+++ b/fuzzer/corpus/e4189007af713f980b50c47f1e4794725c57a1de
Binary files differ
diff --git a/fuzzer/corpus/e4309d4eefa74c5f1e318e17707d30ca56cd1e7b b/fuzzer/corpus/e4309d4eefa74c5f1e318e17707d30ca56cd1e7b
new file mode 100644
index 0000000..e5b0fb2
--- /dev/null
+++ b/fuzzer/corpus/e4309d4eefa74c5f1e318e17707d30ca56cd1e7b
Binary files differ
diff --git a/fuzzer/corpus/e4582704c43bd71deca14d631423da232abd51d5 b/fuzzer/corpus/e4582704c43bd71deca14d631423da232abd51d5
new file mode 100644
index 0000000..0e88987
--- /dev/null
+++ b/fuzzer/corpus/e4582704c43bd71deca14d631423da232abd51d5
Binary files differ
diff --git a/fuzzer/corpus/e459f0c472dc20b4d0b01f3b63e95ba9cc8e7512 b/fuzzer/corpus/e459f0c472dc20b4d0b01f3b63e95ba9cc8e7512
new file mode 100644
index 0000000..223e29b
--- /dev/null
+++ b/fuzzer/corpus/e459f0c472dc20b4d0b01f3b63e95ba9cc8e7512
Binary files differ
diff --git a/fuzzer/corpus/e462823402b1be1965b492d9da008a2ec8b9d8ba b/fuzzer/corpus/e462823402b1be1965b492d9da008a2ec8b9d8ba
new file mode 100644
index 0000000..afceef4
--- /dev/null
+++ b/fuzzer/corpus/e462823402b1be1965b492d9da008a2ec8b9d8ba
Binary files differ
diff --git a/fuzzer/corpus/e482b35af1c67890c17ddf534f579dc2e1940557 b/fuzzer/corpus/e482b35af1c67890c17ddf534f579dc2e1940557
new file mode 100644
index 0000000..442f13d
--- /dev/null
+++ b/fuzzer/corpus/e482b35af1c67890c17ddf534f579dc2e1940557
Binary files differ
diff --git a/fuzzer/corpus/e4ab5ceeed7e78124c0b1b13da7af7ce2acac25d b/fuzzer/corpus/e4ab5ceeed7e78124c0b1b13da7af7ce2acac25d
new file mode 100644
index 0000000..a5d2b05
--- /dev/null
+++ b/fuzzer/corpus/e4ab5ceeed7e78124c0b1b13da7af7ce2acac25d
Binary files differ
diff --git a/fuzzer/corpus/e4ebe578013e5a5230eb290e27c224ba2fb7f3d1 b/fuzzer/corpus/e4ebe578013e5a5230eb290e27c224ba2fb7f3d1
new file mode 100644
index 0000000..5555bb1
--- /dev/null
+++ b/fuzzer/corpus/e4ebe578013e5a5230eb290e27c224ba2fb7f3d1
Binary files differ
diff --git a/fuzzer/corpus/e4f22162b2dd655dca074bf2679ebe8b039b2cf0 b/fuzzer/corpus/e4f22162b2dd655dca074bf2679ebe8b039b2cf0
new file mode 100644
index 0000000..b2f3f78
--- /dev/null
+++ b/fuzzer/corpus/e4f22162b2dd655dca074bf2679ebe8b039b2cf0
Binary files differ
diff --git a/fuzzer/corpus/e4f7f398637af48001261e0131d2f560601a1a41 b/fuzzer/corpus/e4f7f398637af48001261e0131d2f560601a1a41
new file mode 100644
index 0000000..bf07aeb
--- /dev/null
+++ b/fuzzer/corpus/e4f7f398637af48001261e0131d2f560601a1a41
Binary files differ
diff --git a/fuzzer/corpus/e50b6b4f412137b8d28f6cc2f3074cc4e4ca474f b/fuzzer/corpus/e50b6b4f412137b8d28f6cc2f3074cc4e4ca474f
new file mode 100644
index 0000000..44887b7
--- /dev/null
+++ b/fuzzer/corpus/e50b6b4f412137b8d28f6cc2f3074cc4e4ca474f
Binary files differ
diff --git a/fuzzer/corpus/e52c04168e8e4103462c2bb9d0bc993fe53ba13b b/fuzzer/corpus/e52c04168e8e4103462c2bb9d0bc993fe53ba13b
new file mode 100644
index 0000000..7cd08c9
--- /dev/null
+++ b/fuzzer/corpus/e52c04168e8e4103462c2bb9d0bc993fe53ba13b
Binary files differ
diff --git a/fuzzer/corpus/e5651106cd93be0ac68f7c2f81d6f274a727ebb3 b/fuzzer/corpus/e5651106cd93be0ac68f7c2f81d6f274a727ebb3
new file mode 100644
index 0000000..a147702
--- /dev/null
+++ b/fuzzer/corpus/e5651106cd93be0ac68f7c2f81d6f274a727ebb3
Binary files differ
diff --git a/fuzzer/corpus/e59b3a4b2d0b6bdd8c2558ee32ed0af04dffdad2 b/fuzzer/corpus/e59b3a4b2d0b6bdd8c2558ee32ed0af04dffdad2
new file mode 100644
index 0000000..5e93b02
--- /dev/null
+++ b/fuzzer/corpus/e59b3a4b2d0b6bdd8c2558ee32ed0af04dffdad2
Binary files differ
diff --git a/fuzzer/corpus/e5b37fb5b8be337ca0f01fe30334ed3d4d5c684a b/fuzzer/corpus/e5b37fb5b8be337ca0f01fe30334ed3d4d5c684a
new file mode 100644
index 0000000..6847478
--- /dev/null
+++ b/fuzzer/corpus/e5b37fb5b8be337ca0f01fe30334ed3d4d5c684a
Binary files differ
diff --git a/fuzzer/corpus/e5c3461cf7cfff32ac4fd52307207deeff46262e b/fuzzer/corpus/e5c3461cf7cfff32ac4fd52307207deeff46262e
new file mode 100644
index 0000000..3bf467a
--- /dev/null
+++ b/fuzzer/corpus/e5c3461cf7cfff32ac4fd52307207deeff46262e
Binary files differ
diff --git a/fuzzer/corpus/e5dc0ee26c8cb6fd079b751cf0ac3d3232035749 b/fuzzer/corpus/e5dc0ee26c8cb6fd079b751cf0ac3d3232035749
new file mode 100644
index 0000000..d56365c
--- /dev/null
+++ b/fuzzer/corpus/e5dc0ee26c8cb6fd079b751cf0ac3d3232035749
Binary files differ
diff --git a/fuzzer/corpus/e6090fd057eabf660f91e3d2341ec3c5849ee324 b/fuzzer/corpus/e6090fd057eabf660f91e3d2341ec3c5849ee324
new file mode 100644
index 0000000..a1c7b0d
--- /dev/null
+++ b/fuzzer/corpus/e6090fd057eabf660f91e3d2341ec3c5849ee324
Binary files differ
diff --git a/fuzzer/corpus/e62e395eba8efd5026e743540fa0657aac71b795 b/fuzzer/corpus/e62e395eba8efd5026e743540fa0657aac71b795
new file mode 100644
index 0000000..c2a826d
--- /dev/null
+++ b/fuzzer/corpus/e62e395eba8efd5026e743540fa0657aac71b795
Binary files differ
diff --git a/fuzzer/corpus/e62fe5b7e839ab0058f01e0809bb492813f73691 b/fuzzer/corpus/e62fe5b7e839ab0058f01e0809bb492813f73691
new file mode 100644
index 0000000..b4a1be1
--- /dev/null
+++ b/fuzzer/corpus/e62fe5b7e839ab0058f01e0809bb492813f73691
Binary files differ
diff --git a/fuzzer/corpus/e673b0bce870c3ae72b554b013fda36cfe5bf241 b/fuzzer/corpus/e673b0bce870c3ae72b554b013fda36cfe5bf241
new file mode 100644
index 0000000..b49f398
--- /dev/null
+++ b/fuzzer/corpus/e673b0bce870c3ae72b554b013fda36cfe5bf241
Binary files differ
diff --git a/fuzzer/corpus/e690ab4aa1902585c1f03163fa2fd44b5e55309c b/fuzzer/corpus/e690ab4aa1902585c1f03163fa2fd44b5e55309c
new file mode 100644
index 0000000..adde0ef
--- /dev/null
+++ b/fuzzer/corpus/e690ab4aa1902585c1f03163fa2fd44b5e55309c
Binary files differ
diff --git a/fuzzer/corpus/e69b72d2e1c1047ff3130814a4451666d6ea7e22 b/fuzzer/corpus/e69b72d2e1c1047ff3130814a4451666d6ea7e22
new file mode 100644
index 0000000..69eedb2
--- /dev/null
+++ b/fuzzer/corpus/e69b72d2e1c1047ff3130814a4451666d6ea7e22
Binary files differ
diff --git a/fuzzer/corpus/e6e23396fdef4750a3833247bc63fe5774488c46 b/fuzzer/corpus/e6e23396fdef4750a3833247bc63fe5774488c46
new file mode 100644
index 0000000..62f61ef
--- /dev/null
+++ b/fuzzer/corpus/e6e23396fdef4750a3833247bc63fe5774488c46
Binary files differ
diff --git a/fuzzer/corpus/e6f59822479477dd4f7802628b8590472948621b b/fuzzer/corpus/e6f59822479477dd4f7802628b8590472948621b
new file mode 100644
index 0000000..50e2fa0
--- /dev/null
+++ b/fuzzer/corpus/e6f59822479477dd4f7802628b8590472948621b
Binary files differ
diff --git a/fuzzer/corpus/e70149bf42394a6061e2d00095f581739dd44818 b/fuzzer/corpus/e70149bf42394a6061e2d00095f581739dd44818
new file mode 100644
index 0000000..e28aea1
--- /dev/null
+++ b/fuzzer/corpus/e70149bf42394a6061e2d00095f581739dd44818
Binary files differ
diff --git a/fuzzer/corpus/e7195da10d3844dd8b0d9aa3d34ffb28c9dbfaa6 b/fuzzer/corpus/e7195da10d3844dd8b0d9aa3d34ffb28c9dbfaa6
new file mode 100644
index 0000000..2f51064
--- /dev/null
+++ b/fuzzer/corpus/e7195da10d3844dd8b0d9aa3d34ffb28c9dbfaa6
Binary files differ
diff --git a/fuzzer/corpus/e7254f572fa927cecd700e22d42a327e5ec9e777 b/fuzzer/corpus/e7254f572fa927cecd700e22d42a327e5ec9e777
new file mode 100644
index 0000000..eda8dbe
--- /dev/null
+++ b/fuzzer/corpus/e7254f572fa927cecd700e22d42a327e5ec9e777
Binary files differ
diff --git a/fuzzer/corpus/e72d9f2f5c822a13c99798ee0fb80b6521b61d3f b/fuzzer/corpus/e72d9f2f5c822a13c99798ee0fb80b6521b61d3f
new file mode 100644
index 0000000..37de153
--- /dev/null
+++ b/fuzzer/corpus/e72d9f2f5c822a13c99798ee0fb80b6521b61d3f
Binary files differ
diff --git a/fuzzer/corpus/e72e14359deaf76577b6368b4ca05102daae538d b/fuzzer/corpus/e72e14359deaf76577b6368b4ca05102daae538d
new file mode 100644
index 0000000..e129dee
--- /dev/null
+++ b/fuzzer/corpus/e72e14359deaf76577b6368b4ca05102daae538d
Binary files differ
diff --git a/fuzzer/corpus/e7441f5521f1b9ad33caaa8cce88161e5bdd8275 b/fuzzer/corpus/e7441f5521f1b9ad33caaa8cce88161e5bdd8275
new file mode 100644
index 0000000..f9bb543
--- /dev/null
+++ b/fuzzer/corpus/e7441f5521f1b9ad33caaa8cce88161e5bdd8275
Binary files differ
diff --git a/fuzzer/corpus/e76ab8e03532cd5d2bf0c63432e2993bcd7467ba b/fuzzer/corpus/e76ab8e03532cd5d2bf0c63432e2993bcd7467ba
new file mode 100644
index 0000000..6363c2c
--- /dev/null
+++ b/fuzzer/corpus/e76ab8e03532cd5d2bf0c63432e2993bcd7467ba
Binary files differ
diff --git a/fuzzer/corpus/e76cd955107fbb3a5e66ed566f83ac0fd8c6a19a b/fuzzer/corpus/e76cd955107fbb3a5e66ed566f83ac0fd8c6a19a
new file mode 100644
index 0000000..ea29f31
--- /dev/null
+++ b/fuzzer/corpus/e76cd955107fbb3a5e66ed566f83ac0fd8c6a19a
Binary files differ
diff --git a/fuzzer/corpus/e76fbdddd517f74f4c231fb5ac936df72c47ccff b/fuzzer/corpus/e76fbdddd517f74f4c231fb5ac936df72c47ccff
new file mode 100644
index 0000000..55145fe
--- /dev/null
+++ b/fuzzer/corpus/e76fbdddd517f74f4c231fb5ac936df72c47ccff
Binary files differ
diff --git a/fuzzer/corpus/e7879d078f5484de76394ba51fac6e5a7fe3aad2 b/fuzzer/corpus/e7879d078f5484de76394ba51fac6e5a7fe3aad2
new file mode 100644
index 0000000..3903b1a
--- /dev/null
+++ b/fuzzer/corpus/e7879d078f5484de76394ba51fac6e5a7fe3aad2
Binary files differ
diff --git a/fuzzer/corpus/e7a9bddd61c41a3182fe299dc246a1c129edbcd2 b/fuzzer/corpus/e7a9bddd61c41a3182fe299dc246a1c129edbcd2
new file mode 100644
index 0000000..c81cb90
--- /dev/null
+++ b/fuzzer/corpus/e7a9bddd61c41a3182fe299dc246a1c129edbcd2
Binary files differ
diff --git a/fuzzer/corpus/e822c7b78743a719c5c6d4e5288dc6b3fcc4651c b/fuzzer/corpus/e822c7b78743a719c5c6d4e5288dc6b3fcc4651c
new file mode 100644
index 0000000..e60c402
--- /dev/null
+++ b/fuzzer/corpus/e822c7b78743a719c5c6d4e5288dc6b3fcc4651c
Binary files differ
diff --git a/fuzzer/corpus/e8666037f5297d357bd557495b64ad02d1551d09 b/fuzzer/corpus/e8666037f5297d357bd557495b64ad02d1551d09
new file mode 100644
index 0000000..14ad3d9
--- /dev/null
+++ b/fuzzer/corpus/e8666037f5297d357bd557495b64ad02d1551d09
Binary files differ
diff --git a/fuzzer/corpus/e86d59d7b45d680cff3132d6ea38341dc73b5364 b/fuzzer/corpus/e86d59d7b45d680cff3132d6ea38341dc73b5364
new file mode 100644
index 0000000..8e7c5c2
--- /dev/null
+++ b/fuzzer/corpus/e86d59d7b45d680cff3132d6ea38341dc73b5364
Binary files differ
diff --git a/fuzzer/corpus/e89451aa8f9b3de5f529ca316a0d0f330a86f93b b/fuzzer/corpus/e89451aa8f9b3de5f529ca316a0d0f330a86f93b
new file mode 100644
index 0000000..60f2c9f
--- /dev/null
+++ b/fuzzer/corpus/e89451aa8f9b3de5f529ca316a0d0f330a86f93b
Binary files differ
diff --git a/fuzzer/corpus/e89c4cb982aa29baa96b250fe51ed043a942e89d b/fuzzer/corpus/e89c4cb982aa29baa96b250fe51ed043a942e89d
new file mode 100644
index 0000000..7a97bc3
--- /dev/null
+++ b/fuzzer/corpus/e89c4cb982aa29baa96b250fe51ed043a942e89d
Binary files differ
diff --git a/fuzzer/corpus/e8abc42b656993e3049332d239bc1b6e398a7920 b/fuzzer/corpus/e8abc42b656993e3049332d239bc1b6e398a7920
new file mode 100644
index 0000000..7e94f25
--- /dev/null
+++ b/fuzzer/corpus/e8abc42b656993e3049332d239bc1b6e398a7920
Binary files differ
diff --git a/fuzzer/corpus/e8c54feaec75dc91dd44c7ea1177c83333f475b3 b/fuzzer/corpus/e8c54feaec75dc91dd44c7ea1177c83333f475b3
new file mode 100644
index 0000000..4e14d10
--- /dev/null
+++ b/fuzzer/corpus/e8c54feaec75dc91dd44c7ea1177c83333f475b3
Binary files differ
diff --git a/fuzzer/corpus/e8ec0e7be7457ca689de76a45cd47f5344d46888 b/fuzzer/corpus/e8ec0e7be7457ca689de76a45cd47f5344d46888
new file mode 100644
index 0000000..b9ace5e
--- /dev/null
+++ b/fuzzer/corpus/e8ec0e7be7457ca689de76a45cd47f5344d46888
Binary files differ
diff --git a/fuzzer/corpus/e90f234d63465e33c341241ca9d2b2570f1f564a b/fuzzer/corpus/e90f234d63465e33c341241ca9d2b2570f1f564a
new file mode 100644
index 0000000..9c6e118
--- /dev/null
+++ b/fuzzer/corpus/e90f234d63465e33c341241ca9d2b2570f1f564a
Binary files differ
diff --git a/fuzzer/corpus/e937e740fce6a4659d70d14580c6dadd3884a566 b/fuzzer/corpus/e937e740fce6a4659d70d14580c6dadd3884a566
new file mode 100644
index 0000000..31ec373
--- /dev/null
+++ b/fuzzer/corpus/e937e740fce6a4659d70d14580c6dadd3884a566
Binary files differ
diff --git a/fuzzer/corpus/e93c87eb3e91c5d0fab981d2e26b5ab5d868dbe0 b/fuzzer/corpus/e93c87eb3e91c5d0fab981d2e26b5ab5d868dbe0
new file mode 100644
index 0000000..fa62de9
--- /dev/null
+++ b/fuzzer/corpus/e93c87eb3e91c5d0fab981d2e26b5ab5d868dbe0
Binary files differ
diff --git a/fuzzer/corpus/e94c4f6c4edf12fbbf58e701099d97ea9a328818 b/fuzzer/corpus/e94c4f6c4edf12fbbf58e701099d97ea9a328818
new file mode 100644
index 0000000..fc8306e
--- /dev/null
+++ b/fuzzer/corpus/e94c4f6c4edf12fbbf58e701099d97ea9a328818
Binary files differ
diff --git a/fuzzer/corpus/e992e28d6c2ac26bc01507faf7ef6ba10807d5de b/fuzzer/corpus/e992e28d6c2ac26bc01507faf7ef6ba10807d5de
new file mode 100644
index 0000000..fd1b018
--- /dev/null
+++ b/fuzzer/corpus/e992e28d6c2ac26bc01507faf7ef6ba10807d5de
Binary files differ
diff --git a/fuzzer/corpus/e996fb9b53c28053deb15b5dd1edea0d1bd0c5da b/fuzzer/corpus/e996fb9b53c28053deb15b5dd1edea0d1bd0c5da
new file mode 100644
index 0000000..7df4b97
--- /dev/null
+++ b/fuzzer/corpus/e996fb9b53c28053deb15b5dd1edea0d1bd0c5da
Binary files differ
diff --git a/fuzzer/corpus/e9c3016cb8e841d277b7acda4b101aacb5ca66fe b/fuzzer/corpus/e9c3016cb8e841d277b7acda4b101aacb5ca66fe
new file mode 100644
index 0000000..5a1a028
--- /dev/null
+++ b/fuzzer/corpus/e9c3016cb8e841d277b7acda4b101aacb5ca66fe
Binary files differ
diff --git a/fuzzer/corpus/e9cf294779ba84c956e4d86f71dd75625d0762f9 b/fuzzer/corpus/e9cf294779ba84c956e4d86f71dd75625d0762f9
new file mode 100644
index 0000000..11db4de
--- /dev/null
+++ b/fuzzer/corpus/e9cf294779ba84c956e4d86f71dd75625d0762f9
Binary files differ
diff --git a/fuzzer/corpus/e9df0bb499dcd3c192868387b60387520f28cc08 b/fuzzer/corpus/e9df0bb499dcd3c192868387b60387520f28cc08
new file mode 100644
index 0000000..87a72a3
--- /dev/null
+++ b/fuzzer/corpus/e9df0bb499dcd3c192868387b60387520f28cc08
Binary files differ
diff --git a/fuzzer/corpus/e9ff11b3eb0c7ee2fbca38b7405d083b6736ecfe b/fuzzer/corpus/e9ff11b3eb0c7ee2fbca38b7405d083b6736ecfe
new file mode 100644
index 0000000..38d61cc
--- /dev/null
+++ b/fuzzer/corpus/e9ff11b3eb0c7ee2fbca38b7405d083b6736ecfe
Binary files differ
diff --git a/fuzzer/corpus/ea06e03d06e62bbee4909e1f8938e03a57370afa b/fuzzer/corpus/ea06e03d06e62bbee4909e1f8938e03a57370afa
new file mode 100644
index 0000000..d006454
--- /dev/null
+++ b/fuzzer/corpus/ea06e03d06e62bbee4909e1f8938e03a57370afa
Binary files differ
diff --git a/fuzzer/corpus/ea14569f45a4153b18c1caa48b698835d67d831a b/fuzzer/corpus/ea14569f45a4153b18c1caa48b698835d67d831a
new file mode 100644
index 0000000..96a8edf
--- /dev/null
+++ b/fuzzer/corpus/ea14569f45a4153b18c1caa48b698835d67d831a
Binary files differ
diff --git a/fuzzer/corpus/ea155a9c3398ca9a8adb38a8e80ca22a7ffab7a4 b/fuzzer/corpus/ea155a9c3398ca9a8adb38a8e80ca22a7ffab7a4
new file mode 100644
index 0000000..4361d12
--- /dev/null
+++ b/fuzzer/corpus/ea155a9c3398ca9a8adb38a8e80ca22a7ffab7a4
Binary files differ
diff --git a/fuzzer/corpus/ea48b945cbc74956549e731a90991474b8bd102a b/fuzzer/corpus/ea48b945cbc74956549e731a90991474b8bd102a
new file mode 100644
index 0000000..d414e6c
--- /dev/null
+++ b/fuzzer/corpus/ea48b945cbc74956549e731a90991474b8bd102a
Binary files differ
diff --git a/fuzzer/corpus/ea9342e01ca8641af66988b4ba4c60619932a0a5 b/fuzzer/corpus/ea9342e01ca8641af66988b4ba4c60619932a0a5
new file mode 100644
index 0000000..994542e
--- /dev/null
+++ b/fuzzer/corpus/ea9342e01ca8641af66988b4ba4c60619932a0a5
Binary files differ
diff --git a/fuzzer/corpus/ea946153f6ef41b7f5c97ef5024d82ec0e26403a b/fuzzer/corpus/ea946153f6ef41b7f5c97ef5024d82ec0e26403a
new file mode 100644
index 0000000..4837f90
--- /dev/null
+++ b/fuzzer/corpus/ea946153f6ef41b7f5c97ef5024d82ec0e26403a
Binary files differ
diff --git a/fuzzer/corpus/eac6f88668703168aa31b255e7e58142da0a9136 b/fuzzer/corpus/eac6f88668703168aa31b255e7e58142da0a9136
new file mode 100644
index 0000000..b32ca28
--- /dev/null
+++ b/fuzzer/corpus/eac6f88668703168aa31b255e7e58142da0a9136
Binary files differ
diff --git a/fuzzer/corpus/eb4666946169dad175a572771d2d1592308b2ff0 b/fuzzer/corpus/eb4666946169dad175a572771d2d1592308b2ff0
new file mode 100644
index 0000000..3ff882c
--- /dev/null
+++ b/fuzzer/corpus/eb4666946169dad175a572771d2d1592308b2ff0
Binary files differ
diff --git a/fuzzer/corpus/eb5a3da6e5351d9fbb8a67c81cb59532c5f200c8 b/fuzzer/corpus/eb5a3da6e5351d9fbb8a67c81cb59532c5f200c8
new file mode 100644
index 0000000..4be55ff
--- /dev/null
+++ b/fuzzer/corpus/eb5a3da6e5351d9fbb8a67c81cb59532c5f200c8
Binary files differ
diff --git a/fuzzer/corpus/eb7fbf41c750f2592692482d7a0683f55a9c2c80 b/fuzzer/corpus/eb7fbf41c750f2592692482d7a0683f55a9c2c80
new file mode 100644
index 0000000..2eb4514
--- /dev/null
+++ b/fuzzer/corpus/eb7fbf41c750f2592692482d7a0683f55a9c2c80
Binary files differ
diff --git a/fuzzer/corpus/eb86052af19123140592f4b21ff095395e5c8578 b/fuzzer/corpus/eb86052af19123140592f4b21ff095395e5c8578
new file mode 100644
index 0000000..e479266
--- /dev/null
+++ b/fuzzer/corpus/eb86052af19123140592f4b21ff095395e5c8578
Binary files differ
diff --git a/fuzzer/corpus/eb88e0ff6771ec04dfae3a964ff6399958e3cb70 b/fuzzer/corpus/eb88e0ff6771ec04dfae3a964ff6399958e3cb70
new file mode 100644
index 0000000..f0b7d8b
--- /dev/null
+++ b/fuzzer/corpus/eb88e0ff6771ec04dfae3a964ff6399958e3cb70
Binary files differ
diff --git a/fuzzer/corpus/eba7da018882ad9b2e31df6fcf493d15de3fbf7e b/fuzzer/corpus/eba7da018882ad9b2e31df6fcf493d15de3fbf7e
new file mode 100644
index 0000000..1071f78
--- /dev/null
+++ b/fuzzer/corpus/eba7da018882ad9b2e31df6fcf493d15de3fbf7e
Binary files differ
diff --git a/fuzzer/corpus/ebf9ae2db9db98e7973100483990f9f7eb6252f7 b/fuzzer/corpus/ebf9ae2db9db98e7973100483990f9f7eb6252f7
new file mode 100644
index 0000000..bea4c8e
--- /dev/null
+++ b/fuzzer/corpus/ebf9ae2db9db98e7973100483990f9f7eb6252f7
Binary files differ
diff --git a/fuzzer/corpus/ec2445c037618464c2202c67ef6a98a7943e2bc8 b/fuzzer/corpus/ec2445c037618464c2202c67ef6a98a7943e2bc8
new file mode 100644
index 0000000..4148f77
--- /dev/null
+++ b/fuzzer/corpus/ec2445c037618464c2202c67ef6a98a7943e2bc8
Binary files differ
diff --git a/fuzzer/corpus/ec3370b62ad722d3f5df2d3e1f14cdc6676ffaf6 b/fuzzer/corpus/ec3370b62ad722d3f5df2d3e1f14cdc6676ffaf6
new file mode 100644
index 0000000..9903b1d
--- /dev/null
+++ b/fuzzer/corpus/ec3370b62ad722d3f5df2d3e1f14cdc6676ffaf6
Binary files differ
diff --git a/fuzzer/corpus/ecc6ac62b9ee137f2dbdacfa17a3fe691c214c30 b/fuzzer/corpus/ecc6ac62b9ee137f2dbdacfa17a3fe691c214c30
new file mode 100644
index 0000000..c0fb493
--- /dev/null
+++ b/fuzzer/corpus/ecc6ac62b9ee137f2dbdacfa17a3fe691c214c30
Binary files differ
diff --git a/fuzzer/corpus/ece102d726cea0f485cb30f3b0b68ee13b87a1cf b/fuzzer/corpus/ece102d726cea0f485cb30f3b0b68ee13b87a1cf
new file mode 100644
index 0000000..f690a45
--- /dev/null
+++ b/fuzzer/corpus/ece102d726cea0f485cb30f3b0b68ee13b87a1cf
Binary files differ
diff --git a/fuzzer/corpus/eceabe1a94cd4261d53be1612b7bc91d7c8386cc b/fuzzer/corpus/eceabe1a94cd4261d53be1612b7bc91d7c8386cc
new file mode 100644
index 0000000..29000b3
--- /dev/null
+++ b/fuzzer/corpus/eceabe1a94cd4261d53be1612b7bc91d7c8386cc
Binary files differ
diff --git a/fuzzer/corpus/ed1064ddcb3c11b7f3ade049846882ff8cc6de11 b/fuzzer/corpus/ed1064ddcb3c11b7f3ade049846882ff8cc6de11
new file mode 100644
index 0000000..f127acd
--- /dev/null
+++ b/fuzzer/corpus/ed1064ddcb3c11b7f3ade049846882ff8cc6de11
Binary files differ
diff --git a/fuzzer/corpus/ed2ff0a9923c4ffed9bd3270fb573ee12842f06c b/fuzzer/corpus/ed2ff0a9923c4ffed9bd3270fb573ee12842f06c
new file mode 100644
index 0000000..ba90234
--- /dev/null
+++ b/fuzzer/corpus/ed2ff0a9923c4ffed9bd3270fb573ee12842f06c
Binary files differ
diff --git a/fuzzer/corpus/ed3f24599af798db6367c33c728ca8a298430c90 b/fuzzer/corpus/ed3f24599af798db6367c33c728ca8a298430c90
new file mode 100644
index 0000000..4f7ffa0
--- /dev/null
+++ b/fuzzer/corpus/ed3f24599af798db6367c33c728ca8a298430c90
Binary files differ
diff --git a/fuzzer/corpus/ed7e68111214223cf0ac50fb85ded5eb8791c775 b/fuzzer/corpus/ed7e68111214223cf0ac50fb85ded5eb8791c775
new file mode 100644
index 0000000..d1b95d3
--- /dev/null
+++ b/fuzzer/corpus/ed7e68111214223cf0ac50fb85ded5eb8791c775
Binary files differ
diff --git a/fuzzer/corpus/ed88758b1713b053d5bbae3906680bc00939cc4c b/fuzzer/corpus/ed88758b1713b053d5bbae3906680bc00939cc4c
new file mode 100644
index 0000000..4717ae6
--- /dev/null
+++ b/fuzzer/corpus/ed88758b1713b053d5bbae3906680bc00939cc4c
Binary files differ
diff --git a/fuzzer/corpus/eda2b4c3485fcf5fc8e42bd6cd713ec9137bb99f b/fuzzer/corpus/eda2b4c3485fcf5fc8e42bd6cd713ec9137bb99f
new file mode 100644
index 0000000..bfe27d1
--- /dev/null
+++ b/fuzzer/corpus/eda2b4c3485fcf5fc8e42bd6cd713ec9137bb99f
Binary files differ
diff --git a/fuzzer/corpus/edc13238e8ebab8da3ef26e599993aacddc70bfa b/fuzzer/corpus/edc13238e8ebab8da3ef26e599993aacddc70bfa
new file mode 100644
index 0000000..9eadd3c
--- /dev/null
+++ b/fuzzer/corpus/edc13238e8ebab8da3ef26e599993aacddc70bfa
Binary files differ
diff --git a/fuzzer/corpus/ede187b22dc3c4dcdefe28b51b2679e8a47ddc0b b/fuzzer/corpus/ede187b22dc3c4dcdefe28b51b2679e8a47ddc0b
new file mode 100644
index 0000000..97bd9d4
--- /dev/null
+++ b/fuzzer/corpus/ede187b22dc3c4dcdefe28b51b2679e8a47ddc0b
Binary files differ
diff --git a/fuzzer/corpus/edf84125f3683938326c73a7acb1c27a87da8a51 b/fuzzer/corpus/edf84125f3683938326c73a7acb1c27a87da8a51
new file mode 100644
index 0000000..bb49b2c
--- /dev/null
+++ b/fuzzer/corpus/edf84125f3683938326c73a7acb1c27a87da8a51
Binary files differ
diff --git a/fuzzer/corpus/edf95e3d9fa56fd280f99e211e13715f9415d708 b/fuzzer/corpus/edf95e3d9fa56fd280f99e211e13715f9415d708
new file mode 100644
index 0000000..e16f9f4
--- /dev/null
+++ b/fuzzer/corpus/edf95e3d9fa56fd280f99e211e13715f9415d708
Binary files differ
diff --git a/fuzzer/corpus/ee23b2e0e0981ba0768c0af7be21256ad1c31ab0 b/fuzzer/corpus/ee23b2e0e0981ba0768c0af7be21256ad1c31ab0
new file mode 100644
index 0000000..960dca2
--- /dev/null
+++ b/fuzzer/corpus/ee23b2e0e0981ba0768c0af7be21256ad1c31ab0
Binary files differ
diff --git a/fuzzer/corpus/ee4143cba56a62392cfa98fcd0198887fd360b33 b/fuzzer/corpus/ee4143cba56a62392cfa98fcd0198887fd360b33
new file mode 100644
index 0000000..975d2f9
--- /dev/null
+++ b/fuzzer/corpus/ee4143cba56a62392cfa98fcd0198887fd360b33
Binary files differ
diff --git a/fuzzer/corpus/ee59b9d2d302cdf3b5768c78d6438da6543eb3ee b/fuzzer/corpus/ee59b9d2d302cdf3b5768c78d6438da6543eb3ee
new file mode 100644
index 0000000..d1f9beb
--- /dev/null
+++ b/fuzzer/corpus/ee59b9d2d302cdf3b5768c78d6438da6543eb3ee
Binary files differ
diff --git a/fuzzer/corpus/ee61ff2e7e4c8640e4451e780a264b3171088569 b/fuzzer/corpus/ee61ff2e7e4c8640e4451e780a264b3171088569
new file mode 100644
index 0000000..d420d4f
--- /dev/null
+++ b/fuzzer/corpus/ee61ff2e7e4c8640e4451e780a264b3171088569
Binary files differ
diff --git a/fuzzer/corpus/ee629945ac1d7129ea5cb4514c9385ac38a8423d b/fuzzer/corpus/ee629945ac1d7129ea5cb4514c9385ac38a8423d
new file mode 100644
index 0000000..a3f0895
--- /dev/null
+++ b/fuzzer/corpus/ee629945ac1d7129ea5cb4514c9385ac38a8423d
Binary files differ
diff --git a/fuzzer/corpus/ee7613b93209394eea757ba614a0b9277f792d9b b/fuzzer/corpus/ee7613b93209394eea757ba614a0b9277f792d9b
new file mode 100644
index 0000000..b2b5e04
--- /dev/null
+++ b/fuzzer/corpus/ee7613b93209394eea757ba614a0b9277f792d9b
Binary files differ
diff --git a/fuzzer/corpus/eeb1ad989122ab36a0ae2c3182b9f54e62051927 b/fuzzer/corpus/eeb1ad989122ab36a0ae2c3182b9f54e62051927
new file mode 100644
index 0000000..9e76bc5
--- /dev/null
+++ b/fuzzer/corpus/eeb1ad989122ab36a0ae2c3182b9f54e62051927
Binary files differ
diff --git a/fuzzer/corpus/eeb2d99d630e9990996b4b4b23c1dbf97fd75747 b/fuzzer/corpus/eeb2d99d630e9990996b4b4b23c1dbf97fd75747
new file mode 100644
index 0000000..e5ce972
--- /dev/null
+++ b/fuzzer/corpus/eeb2d99d630e9990996b4b4b23c1dbf97fd75747
Binary files differ
diff --git a/fuzzer/corpus/eef72ee9c4c35ef707acc959c7294d5ced10fe68 b/fuzzer/corpus/eef72ee9c4c35ef707acc959c7294d5ced10fe68
new file mode 100644
index 0000000..3fcfc4c
--- /dev/null
+++ b/fuzzer/corpus/eef72ee9c4c35ef707acc959c7294d5ced10fe68
Binary files differ
diff --git a/fuzzer/corpus/ef45313934c87273348fe3949e49050dbbf213e0 b/fuzzer/corpus/ef45313934c87273348fe3949e49050dbbf213e0
new file mode 100644
index 0000000..66c32c6
--- /dev/null
+++ b/fuzzer/corpus/ef45313934c87273348fe3949e49050dbbf213e0
Binary files differ
diff --git a/fuzzer/corpus/ef682b9f5a22ad759caa4b598d67c9320278f488 b/fuzzer/corpus/ef682b9f5a22ad759caa4b598d67c9320278f488
new file mode 100644
index 0000000..c13e5ec
--- /dev/null
+++ b/fuzzer/corpus/ef682b9f5a22ad759caa4b598d67c9320278f488
Binary files differ
diff --git a/fuzzer/corpus/ef79e7c334518bfdd1265db7480f0cae019360b1 b/fuzzer/corpus/ef79e7c334518bfdd1265db7480f0cae019360b1
new file mode 100644
index 0000000..025716c
--- /dev/null
+++ b/fuzzer/corpus/ef79e7c334518bfdd1265db7480f0cae019360b1
Binary files differ
diff --git a/fuzzer/corpus/ef876ed45ad7c879018480241dd5ba5f7778f462 b/fuzzer/corpus/ef876ed45ad7c879018480241dd5ba5f7778f462
new file mode 100644
index 0000000..1626e83
--- /dev/null
+++ b/fuzzer/corpus/ef876ed45ad7c879018480241dd5ba5f7778f462
Binary files differ
diff --git a/fuzzer/corpus/efbd22c13892a1ea4752b6cfee6b3159c3d5ac9d b/fuzzer/corpus/efbd22c13892a1ea4752b6cfee6b3159c3d5ac9d
new file mode 100644
index 0000000..a5e0ddb
--- /dev/null
+++ b/fuzzer/corpus/efbd22c13892a1ea4752b6cfee6b3159c3d5ac9d
Binary files differ
diff --git a/fuzzer/corpus/efda9a2eab8bbb01e62ac01625b8cf4909a1198d b/fuzzer/corpus/efda9a2eab8bbb01e62ac01625b8cf4909a1198d
new file mode 100644
index 0000000..3a304f0
--- /dev/null
+++ b/fuzzer/corpus/efda9a2eab8bbb01e62ac01625b8cf4909a1198d
Binary files differ
diff --git a/fuzzer/corpus/eff1b9d15d4bd60e4842fde37d048c90661d6121 b/fuzzer/corpus/eff1b9d15d4bd60e4842fde37d048c90661d6121
new file mode 100644
index 0000000..7a5ce0b
--- /dev/null
+++ b/fuzzer/corpus/eff1b9d15d4bd60e4842fde37d048c90661d6121
Binary files differ
diff --git a/fuzzer/corpus/f003ebe145288bc911d8840d4780a0d4ddc55373 b/fuzzer/corpus/f003ebe145288bc911d8840d4780a0d4ddc55373
new file mode 100644
index 0000000..6a902d5
--- /dev/null
+++ b/fuzzer/corpus/f003ebe145288bc911d8840d4780a0d4ddc55373
Binary files differ
diff --git a/fuzzer/corpus/f0052c8d2126b9b7ba5c26369b78b36ef25fe0f7 b/fuzzer/corpus/f0052c8d2126b9b7ba5c26369b78b36ef25fe0f7
new file mode 100644
index 0000000..0fbf4ce
--- /dev/null
+++ b/fuzzer/corpus/f0052c8d2126b9b7ba5c26369b78b36ef25fe0f7
Binary files differ
diff --git a/fuzzer/corpus/f008b22f42c5f61ed903270d859bcff244c389cc b/fuzzer/corpus/f008b22f42c5f61ed903270d859bcff244c389cc
new file mode 100644
index 0000000..23d27ec
--- /dev/null
+++ b/fuzzer/corpus/f008b22f42c5f61ed903270d859bcff244c389cc
Binary files differ
diff --git a/fuzzer/corpus/f06191d918adb094a1463bc1d3203cec72aaa384 b/fuzzer/corpus/f06191d918adb094a1463bc1d3203cec72aaa384
new file mode 100644
index 0000000..0829912
--- /dev/null
+++ b/fuzzer/corpus/f06191d918adb094a1463bc1d3203cec72aaa384
Binary files differ
diff --git a/fuzzer/corpus/f08e173307472c01ab182293fcd7d5bb9c9d305a b/fuzzer/corpus/f08e173307472c01ab182293fcd7d5bb9c9d305a
new file mode 100644
index 0000000..566e36f
--- /dev/null
+++ b/fuzzer/corpus/f08e173307472c01ab182293fcd7d5bb9c9d305a
Binary files differ
diff --git a/fuzzer/corpus/f090460188c02c587bdfa1063474c824d9894dcc b/fuzzer/corpus/f090460188c02c587bdfa1063474c824d9894dcc
new file mode 100644
index 0000000..748e236
--- /dev/null
+++ b/fuzzer/corpus/f090460188c02c587bdfa1063474c824d9894dcc
Binary files differ
diff --git a/fuzzer/corpus/f09b1112d054e3b2aae1a7964279716bbeca47b4 b/fuzzer/corpus/f09b1112d054e3b2aae1a7964279716bbeca47b4
new file mode 100644
index 0000000..e8cc83b
--- /dev/null
+++ b/fuzzer/corpus/f09b1112d054e3b2aae1a7964279716bbeca47b4
Binary files differ
diff --git a/fuzzer/corpus/f0a0ffc1468ea117395a807dfebda2452d16c499 b/fuzzer/corpus/f0a0ffc1468ea117395a807dfebda2452d16c499
new file mode 100644
index 0000000..f5760d5
--- /dev/null
+++ b/fuzzer/corpus/f0a0ffc1468ea117395a807dfebda2452d16c499
Binary files differ
diff --git a/fuzzer/corpus/f0b8ef27c8ee16b81872b1157ee461b96c8b7f45 b/fuzzer/corpus/f0b8ef27c8ee16b81872b1157ee461b96c8b7f45
new file mode 100644
index 0000000..886d46e
--- /dev/null
+++ b/fuzzer/corpus/f0b8ef27c8ee16b81872b1157ee461b96c8b7f45
Binary files differ
diff --git a/fuzzer/corpus/f0ccba58f670dc2fd99df17c149496c0649707fa b/fuzzer/corpus/f0ccba58f670dc2fd99df17c149496c0649707fa
new file mode 100644
index 0000000..774d786
--- /dev/null
+++ b/fuzzer/corpus/f0ccba58f670dc2fd99df17c149496c0649707fa
Binary files differ
diff --git a/fuzzer/corpus/f0d303aa6beb3c3f4c55158bdaeabdfa635c27f1 b/fuzzer/corpus/f0d303aa6beb3c3f4c55158bdaeabdfa635c27f1
new file mode 100644
index 0000000..3b731b8
--- /dev/null
+++ b/fuzzer/corpus/f0d303aa6beb3c3f4c55158bdaeabdfa635c27f1
Binary files differ
diff --git a/fuzzer/corpus/f12678cf2e168188494f2e7aab6b070eb439d2c2 b/fuzzer/corpus/f12678cf2e168188494f2e7aab6b070eb439d2c2
new file mode 100644
index 0000000..69a1cb3
--- /dev/null
+++ b/fuzzer/corpus/f12678cf2e168188494f2e7aab6b070eb439d2c2
Binary files differ
diff --git a/fuzzer/corpus/f12c261d98893669a7215333f8923b0d2ea1a81f b/fuzzer/corpus/f12c261d98893669a7215333f8923b0d2ea1a81f
new file mode 100644
index 0000000..7f3d6db
--- /dev/null
+++ b/fuzzer/corpus/f12c261d98893669a7215333f8923b0d2ea1a81f
Binary files differ
diff --git a/fuzzer/corpus/f1610db081c181b291201ff4cde6fdc1893952cc b/fuzzer/corpus/f1610db081c181b291201ff4cde6fdc1893952cc
new file mode 100644
index 0000000..fbc5b09
--- /dev/null
+++ b/fuzzer/corpus/f1610db081c181b291201ff4cde6fdc1893952cc
Binary files differ
diff --git a/fuzzer/corpus/f1a4b29cfff5569fb9b9daa65b0e3440b039615d b/fuzzer/corpus/f1a4b29cfff5569fb9b9daa65b0e3440b039615d
new file mode 100644
index 0000000..e677be7
--- /dev/null
+++ b/fuzzer/corpus/f1a4b29cfff5569fb9b9daa65b0e3440b039615d
Binary files differ
diff --git a/fuzzer/corpus/f1a631ef4173d800f78500a86921102ff19ec5f4 b/fuzzer/corpus/f1a631ef4173d800f78500a86921102ff19ec5f4
new file mode 100644
index 0000000..526b967
--- /dev/null
+++ b/fuzzer/corpus/f1a631ef4173d800f78500a86921102ff19ec5f4
Binary files differ
diff --git a/fuzzer/corpus/f23ca8c2db08c83d86b7aa9a7bc044d0d5368629 b/fuzzer/corpus/f23ca8c2db08c83d86b7aa9a7bc044d0d5368629
new file mode 100644
index 0000000..8da29b6
--- /dev/null
+++ b/fuzzer/corpus/f23ca8c2db08c83d86b7aa9a7bc044d0d5368629
Binary files differ
diff --git a/fuzzer/corpus/f24000f05837427008fc2903033e3aa91bd24e4b b/fuzzer/corpus/f24000f05837427008fc2903033e3aa91bd24e4b
new file mode 100644
index 0000000..2c7bd2e
--- /dev/null
+++ b/fuzzer/corpus/f24000f05837427008fc2903033e3aa91bd24e4b
Binary files differ
diff --git a/fuzzer/corpus/f274eda5fd5ad1ee69b55fbdfbf40dcc532b0842 b/fuzzer/corpus/f274eda5fd5ad1ee69b55fbdfbf40dcc532b0842
new file mode 100644
index 0000000..0fd0988
--- /dev/null
+++ b/fuzzer/corpus/f274eda5fd5ad1ee69b55fbdfbf40dcc532b0842
Binary files differ
diff --git a/fuzzer/corpus/f2a8a2e95b355b99543d2c166d3371eb64b65d72 b/fuzzer/corpus/f2a8a2e95b355b99543d2c166d3371eb64b65d72
new file mode 100644
index 0000000..ee383a5
--- /dev/null
+++ b/fuzzer/corpus/f2a8a2e95b355b99543d2c166d3371eb64b65d72
Binary files differ
diff --git a/fuzzer/corpus/f2ac90d7e62eac0fa3ac34fc4439f63b01333f4f b/fuzzer/corpus/f2ac90d7e62eac0fa3ac34fc4439f63b01333f4f
new file mode 100644
index 0000000..8748ec7
--- /dev/null
+++ b/fuzzer/corpus/f2ac90d7e62eac0fa3ac34fc4439f63b01333f4f
Binary files differ
diff --git a/fuzzer/corpus/f2c1f02048e8ecbfca4799527fcdc2497b8b7aed b/fuzzer/corpus/f2c1f02048e8ecbfca4799527fcdc2497b8b7aed
new file mode 100644
index 0000000..291f4fa
--- /dev/null
+++ b/fuzzer/corpus/f2c1f02048e8ecbfca4799527fcdc2497b8b7aed
Binary files differ
diff --git a/fuzzer/corpus/f2c774553dde8a7d49a9ede22e745a3d65d6494a b/fuzzer/corpus/f2c774553dde8a7d49a9ede22e745a3d65d6494a
new file mode 100644
index 0000000..b570190
--- /dev/null
+++ b/fuzzer/corpus/f2c774553dde8a7d49a9ede22e745a3d65d6494a
Binary files differ
diff --git a/fuzzer/corpus/f2e7b8bcdf840a826ecfffb21ed558e67ddb2102 b/fuzzer/corpus/f2e7b8bcdf840a826ecfffb21ed558e67ddb2102
new file mode 100644
index 0000000..3338ba8
--- /dev/null
+++ b/fuzzer/corpus/f2e7b8bcdf840a826ecfffb21ed558e67ddb2102
Binary files differ
diff --git a/fuzzer/corpus/f2e810e500e5137a530f663b285ce84db75430f9 b/fuzzer/corpus/f2e810e500e5137a530f663b285ce84db75430f9
new file mode 100644
index 0000000..d78a778
--- /dev/null
+++ b/fuzzer/corpus/f2e810e500e5137a530f663b285ce84db75430f9
Binary files differ
diff --git a/fuzzer/corpus/f2f0737ea6641610a694ddbec3209073963601d8 b/fuzzer/corpus/f2f0737ea6641610a694ddbec3209073963601d8
new file mode 100644
index 0000000..f75cf9a
--- /dev/null
+++ b/fuzzer/corpus/f2f0737ea6641610a694ddbec3209073963601d8
Binary files differ
diff --git a/fuzzer/corpus/f2f210d434056dce3861223e3b7024dd6584526a b/fuzzer/corpus/f2f210d434056dce3861223e3b7024dd6584526a
new file mode 100644
index 0000000..8b75580
--- /dev/null
+++ b/fuzzer/corpus/f2f210d434056dce3861223e3b7024dd6584526a
Binary files differ
diff --git a/fuzzer/corpus/f3a82e8b38f954c0be2247de3b6eb3910839f63d b/fuzzer/corpus/f3a82e8b38f954c0be2247de3b6eb3910839f63d
new file mode 100644
index 0000000..fb40bea
--- /dev/null
+++ b/fuzzer/corpus/f3a82e8b38f954c0be2247de3b6eb3910839f63d
Binary files differ
diff --git a/fuzzer/corpus/f3bcae440cb075f0afc3e3b40cd493d7af5a31ca b/fuzzer/corpus/f3bcae440cb075f0afc3e3b40cd493d7af5a31ca
new file mode 100644
index 0000000..0bbb80d
--- /dev/null
+++ b/fuzzer/corpus/f3bcae440cb075f0afc3e3b40cd493d7af5a31ca
Binary files differ
diff --git a/fuzzer/corpus/f409da789abb07a47457bfd12537acdd27b4d2fb b/fuzzer/corpus/f409da789abb07a47457bfd12537acdd27b4d2fb
new file mode 100644
index 0000000..00121c4
--- /dev/null
+++ b/fuzzer/corpus/f409da789abb07a47457bfd12537acdd27b4d2fb
Binary files differ
diff --git a/fuzzer/corpus/f40e3a584166733e7c1f702690fc18a9b6d8bddf b/fuzzer/corpus/f40e3a584166733e7c1f702690fc18a9b6d8bddf
new file mode 100644
index 0000000..de2f3e9
--- /dev/null
+++ b/fuzzer/corpus/f40e3a584166733e7c1f702690fc18a9b6d8bddf
Binary files differ
diff --git a/fuzzer/corpus/f4108aeafd06233e7a3f4fe63d557368c8ceb528 b/fuzzer/corpus/f4108aeafd06233e7a3f4fe63d557368c8ceb528
new file mode 100644
index 0000000..454cb1b
--- /dev/null
+++ b/fuzzer/corpus/f4108aeafd06233e7a3f4fe63d557368c8ceb528
Binary files differ
diff --git a/fuzzer/corpus/f42560134cb6af8dfdfb8a9570c93eead6b7ac31 b/fuzzer/corpus/f42560134cb6af8dfdfb8a9570c93eead6b7ac31
new file mode 100644
index 0000000..b92c760
--- /dev/null
+++ b/fuzzer/corpus/f42560134cb6af8dfdfb8a9570c93eead6b7ac31
Binary files differ
diff --git a/fuzzer/corpus/f429817dc2960e7da1db52681ccdd784ad1dab1c b/fuzzer/corpus/f429817dc2960e7da1db52681ccdd784ad1dab1c
new file mode 100644
index 0000000..a41fffb
--- /dev/null
+++ b/fuzzer/corpus/f429817dc2960e7da1db52681ccdd784ad1dab1c
Binary files differ
diff --git a/fuzzer/corpus/f441070d3702c9dfd3745c6b2187104333103504 b/fuzzer/corpus/f441070d3702c9dfd3745c6b2187104333103504
new file mode 100644
index 0000000..31d0b19
--- /dev/null
+++ b/fuzzer/corpus/f441070d3702c9dfd3745c6b2187104333103504
Binary files differ
diff --git a/fuzzer/corpus/f444c8a3e366fcbcc5cdbc0511dc3c3d3f3b5089 b/fuzzer/corpus/f444c8a3e366fcbcc5cdbc0511dc3c3d3f3b5089
new file mode 100644
index 0000000..c35c300
--- /dev/null
+++ b/fuzzer/corpus/f444c8a3e366fcbcc5cdbc0511dc3c3d3f3b5089
Binary files differ
diff --git a/fuzzer/corpus/f459917db3554315251ee96735392fbf89713064 b/fuzzer/corpus/f459917db3554315251ee96735392fbf89713064
new file mode 100644
index 0000000..6af8d28
--- /dev/null
+++ b/fuzzer/corpus/f459917db3554315251ee96735392fbf89713064
Binary files differ
diff --git a/fuzzer/corpus/f471537f0f8cf6e4b73e737f3b18ea5fd6eab702 b/fuzzer/corpus/f471537f0f8cf6e4b73e737f3b18ea5fd6eab702
new file mode 100644
index 0000000..c803e3d
--- /dev/null
+++ b/fuzzer/corpus/f471537f0f8cf6e4b73e737f3b18ea5fd6eab702
Binary files differ
diff --git a/fuzzer/corpus/f47cb523f7a32f4306a1b9f78486018299f518f5 b/fuzzer/corpus/f47cb523f7a32f4306a1b9f78486018299f518f5
new file mode 100644
index 0000000..e54786f
--- /dev/null
+++ b/fuzzer/corpus/f47cb523f7a32f4306a1b9f78486018299f518f5
Binary files differ
diff --git a/fuzzer/corpus/f48bca386983cd42be106864d164cfcab53aceb7 b/fuzzer/corpus/f48bca386983cd42be106864d164cfcab53aceb7
new file mode 100644
index 0000000..232fd58
--- /dev/null
+++ b/fuzzer/corpus/f48bca386983cd42be106864d164cfcab53aceb7
Binary files differ
diff --git a/fuzzer/corpus/f496134873c83f1aaa70cf1c31759d03bbe9c495 b/fuzzer/corpus/f496134873c83f1aaa70cf1c31759d03bbe9c495
new file mode 100644
index 0000000..c2ddee7
--- /dev/null
+++ b/fuzzer/corpus/f496134873c83f1aaa70cf1c31759d03bbe9c495
Binary files differ
diff --git a/fuzzer/corpus/f49a32dd866a767b9ca2c06451f49d926d958d95 b/fuzzer/corpus/f49a32dd866a767b9ca2c06451f49d926d958d95
new file mode 100644
index 0000000..55f9b22
--- /dev/null
+++ b/fuzzer/corpus/f49a32dd866a767b9ca2c06451f49d926d958d95
Binary files differ
diff --git a/fuzzer/corpus/f4a8fb7ec792c5e016d1b1756d9e62cc25c4e1a6 b/fuzzer/corpus/f4a8fb7ec792c5e016d1b1756d9e62cc25c4e1a6
new file mode 100644
index 0000000..96e3452
--- /dev/null
+++ b/fuzzer/corpus/f4a8fb7ec792c5e016d1b1756d9e62cc25c4e1a6
Binary files differ
diff --git a/fuzzer/corpus/f4c3ae6c1b149fece719a25b64f0ffcfa0ef4f70 b/fuzzer/corpus/f4c3ae6c1b149fece719a25b64f0ffcfa0ef4f70
new file mode 100644
index 0000000..e221daa
--- /dev/null
+++ b/fuzzer/corpus/f4c3ae6c1b149fece719a25b64f0ffcfa0ef4f70
Binary files differ
diff --git a/fuzzer/corpus/f4d4b58bdca492a6ed003c2b49a26f3f4ea683fe b/fuzzer/corpus/f4d4b58bdca492a6ed003c2b49a26f3f4ea683fe
new file mode 100644
index 0000000..e857507
--- /dev/null
+++ b/fuzzer/corpus/f4d4b58bdca492a6ed003c2b49a26f3f4ea683fe
Binary files differ
diff --git a/fuzzer/corpus/f4d850a491224739a870c57d7ccd32e22f2ecb23 b/fuzzer/corpus/f4d850a491224739a870c57d7ccd32e22f2ecb23
new file mode 100644
index 0000000..5726d20
--- /dev/null
+++ b/fuzzer/corpus/f4d850a491224739a870c57d7ccd32e22f2ecb23
Binary files differ
diff --git a/fuzzer/corpus/f522843f0e11b6c483a57c8e52ec0d97eda68175 b/fuzzer/corpus/f522843f0e11b6c483a57c8e52ec0d97eda68175
new file mode 100644
index 0000000..e1978f2
--- /dev/null
+++ b/fuzzer/corpus/f522843f0e11b6c483a57c8e52ec0d97eda68175
Binary files differ
diff --git a/fuzzer/corpus/f5a854f1bad59930b2e80e5f6f6350989ff442f8 b/fuzzer/corpus/f5a854f1bad59930b2e80e5f6f6350989ff442f8
new file mode 100644
index 0000000..483fb6c
--- /dev/null
+++ b/fuzzer/corpus/f5a854f1bad59930b2e80e5f6f6350989ff442f8
Binary files differ
diff --git a/fuzzer/corpus/f5c39076cd888160da91d78058137a409fed02e2 b/fuzzer/corpus/f5c39076cd888160da91d78058137a409fed02e2
new file mode 100644
index 0000000..558e0ef
--- /dev/null
+++ b/fuzzer/corpus/f5c39076cd888160da91d78058137a409fed02e2
Binary files differ
diff --git a/fuzzer/corpus/f5e91076d0dca3b53d4f85dd565f346ce7dba322 b/fuzzer/corpus/f5e91076d0dca3b53d4f85dd565f346ce7dba322
new file mode 100644
index 0000000..0c121c6
--- /dev/null
+++ b/fuzzer/corpus/f5e91076d0dca3b53d4f85dd565f346ce7dba322
Binary files differ
diff --git a/fuzzer/corpus/f5f9014f5d4a8e28d939e313aaee1445720046e0 b/fuzzer/corpus/f5f9014f5d4a8e28d939e313aaee1445720046e0
new file mode 100644
index 0000000..339109f
--- /dev/null
+++ b/fuzzer/corpus/f5f9014f5d4a8e28d939e313aaee1445720046e0
Binary files differ
diff --git a/fuzzer/corpus/f63987ba8506c3fadc251e002eab9bd18aacf83f b/fuzzer/corpus/f63987ba8506c3fadc251e002eab9bd18aacf83f
new file mode 100644
index 0000000..2f3777b
--- /dev/null
+++ b/fuzzer/corpus/f63987ba8506c3fadc251e002eab9bd18aacf83f
Binary files differ
diff --git a/fuzzer/corpus/f65819da779e1a0f50a0349ede6d6a3491c3e2ad b/fuzzer/corpus/f65819da779e1a0f50a0349ede6d6a3491c3e2ad
new file mode 100644
index 0000000..902118f
--- /dev/null
+++ b/fuzzer/corpus/f65819da779e1a0f50a0349ede6d6a3491c3e2ad
Binary files differ
diff --git a/fuzzer/corpus/f6a64c4d5720bb5c6d1dbbbb2be77a7db7655168 b/fuzzer/corpus/f6a64c4d5720bb5c6d1dbbbb2be77a7db7655168
new file mode 100644
index 0000000..5c1f0c3
--- /dev/null
+++ b/fuzzer/corpus/f6a64c4d5720bb5c6d1dbbbb2be77a7db7655168
Binary files differ
diff --git a/fuzzer/corpus/f6c0228a7564ad9da25b7f8ae4842103391eb320 b/fuzzer/corpus/f6c0228a7564ad9da25b7f8ae4842103391eb320
new file mode 100644
index 0000000..aa6aee3
--- /dev/null
+++ b/fuzzer/corpus/f6c0228a7564ad9da25b7f8ae4842103391eb320
Binary files differ
diff --git a/fuzzer/corpus/f75716a052feb47e47958491f6631cddd7418dce b/fuzzer/corpus/f75716a052feb47e47958491f6631cddd7418dce
new file mode 100644
index 0000000..e5fbd88
--- /dev/null
+++ b/fuzzer/corpus/f75716a052feb47e47958491f6631cddd7418dce
Binary files differ
diff --git a/fuzzer/corpus/f760e7458959d1d4e64e12a7fe42552531972bc9 b/fuzzer/corpus/f760e7458959d1d4e64e12a7fe42552531972bc9
new file mode 100644
index 0000000..47577a1
--- /dev/null
+++ b/fuzzer/corpus/f760e7458959d1d4e64e12a7fe42552531972bc9
Binary files differ
diff --git a/fuzzer/corpus/f791d55d9d4b2462fa15af44cd00122f7c79de36 b/fuzzer/corpus/f791d55d9d4b2462fa15af44cd00122f7c79de36
new file mode 100644
index 0000000..c0b4a3f
--- /dev/null
+++ b/fuzzer/corpus/f791d55d9d4b2462fa15af44cd00122f7c79de36
Binary files differ
diff --git a/fuzzer/corpus/f7bbb2eb13e2ed81078bac10f3d05fdc3f05a6dd b/fuzzer/corpus/f7bbb2eb13e2ed81078bac10f3d05fdc3f05a6dd
new file mode 100644
index 0000000..33bd012
--- /dev/null
+++ b/fuzzer/corpus/f7bbb2eb13e2ed81078bac10f3d05fdc3f05a6dd
Binary files differ
diff --git a/fuzzer/corpus/f80664228f35f70394d0563a1eefaf3ada8bf013 b/fuzzer/corpus/f80664228f35f70394d0563a1eefaf3ada8bf013
new file mode 100644
index 0000000..537d828
--- /dev/null
+++ b/fuzzer/corpus/f80664228f35f70394d0563a1eefaf3ada8bf013
Binary files differ
diff --git a/fuzzer/corpus/f806c722b19ae6f4fecec4a46b19fdbb14068333 b/fuzzer/corpus/f806c722b19ae6f4fecec4a46b19fdbb14068333
new file mode 100644
index 0000000..177b795
--- /dev/null
+++ b/fuzzer/corpus/f806c722b19ae6f4fecec4a46b19fdbb14068333
Binary files differ
diff --git a/fuzzer/corpus/f8119ba7ca78c66051715f981c97e0513d9c3827 b/fuzzer/corpus/f8119ba7ca78c66051715f981c97e0513d9c3827
new file mode 100644
index 0000000..560cce4
--- /dev/null
+++ b/fuzzer/corpus/f8119ba7ca78c66051715f981c97e0513d9c3827
Binary files differ
diff --git a/fuzzer/corpus/f82a03f4cfaf60f998c09fc3e65d6849eb15672f b/fuzzer/corpus/f82a03f4cfaf60f998c09fc3e65d6849eb15672f
new file mode 100644
index 0000000..258c1d8
--- /dev/null
+++ b/fuzzer/corpus/f82a03f4cfaf60f998c09fc3e65d6849eb15672f
Binary files differ
diff --git a/fuzzer/corpus/f846135da0396f61035a2ae12d0b71319f5da4f0 b/fuzzer/corpus/f846135da0396f61035a2ae12d0b71319f5da4f0
new file mode 100644
index 0000000..baf12bf
--- /dev/null
+++ b/fuzzer/corpus/f846135da0396f61035a2ae12d0b71319f5da4f0
Binary files differ
diff --git a/fuzzer/corpus/f8551d2355baacbc81a177b68a09257d003a1d63 b/fuzzer/corpus/f8551d2355baacbc81a177b68a09257d003a1d63
new file mode 100644
index 0000000..09a511b
--- /dev/null
+++ b/fuzzer/corpus/f8551d2355baacbc81a177b68a09257d003a1d63
Binary files differ
diff --git a/fuzzer/corpus/f892a5308895f5d40d0ed79af766e4165589c197 b/fuzzer/corpus/f892a5308895f5d40d0ed79af766e4165589c197
new file mode 100644
index 0000000..6cdd4df
--- /dev/null
+++ b/fuzzer/corpus/f892a5308895f5d40d0ed79af766e4165589c197
Binary files differ
diff --git a/fuzzer/corpus/f8b655a75c4437875b27560ba941e232dc793934 b/fuzzer/corpus/f8b655a75c4437875b27560ba941e232dc793934
new file mode 100644
index 0000000..4ba19b7
--- /dev/null
+++ b/fuzzer/corpus/f8b655a75c4437875b27560ba941e232dc793934
Binary files differ
diff --git a/fuzzer/corpus/f8c0c300df603d18373e8a710c98cfa027910bba b/fuzzer/corpus/f8c0c300df603d18373e8a710c98cfa027910bba
new file mode 100644
index 0000000..8929fc8
--- /dev/null
+++ b/fuzzer/corpus/f8c0c300df603d18373e8a710c98cfa027910bba
Binary files differ
diff --git a/fuzzer/corpus/f8c50fa227f6b1dde618168d159caebb91cae54d b/fuzzer/corpus/f8c50fa227f6b1dde618168d159caebb91cae54d
new file mode 100644
index 0000000..8692cfe
--- /dev/null
+++ b/fuzzer/corpus/f8c50fa227f6b1dde618168d159caebb91cae54d
Binary files differ
diff --git a/fuzzer/corpus/f8d354179c10d219127b53273ff471644e782176 b/fuzzer/corpus/f8d354179c10d219127b53273ff471644e782176
new file mode 100644
index 0000000..75c2878
--- /dev/null
+++ b/fuzzer/corpus/f8d354179c10d219127b53273ff471644e782176
Binary files differ
diff --git a/fuzzer/corpus/f8f7a802aa67780f3d70b686b01498462a015329 b/fuzzer/corpus/f8f7a802aa67780f3d70b686b01498462a015329
new file mode 100644
index 0000000..b15448e
--- /dev/null
+++ b/fuzzer/corpus/f8f7a802aa67780f3d70b686b01498462a015329
Binary files differ
diff --git a/fuzzer/corpus/f8fbf0f30aa1f2081c158a5e5d027bb540e344ab b/fuzzer/corpus/f8fbf0f30aa1f2081c158a5e5d027bb540e344ab
new file mode 100644
index 0000000..fa7de34
--- /dev/null
+++ b/fuzzer/corpus/f8fbf0f30aa1f2081c158a5e5d027bb540e344ab
Binary files differ
diff --git a/fuzzer/corpus/f8fc30c4cce63d22fb41139e708b4f98d7f38ece b/fuzzer/corpus/f8fc30c4cce63d22fb41139e708b4f98d7f38ece
new file mode 100644
index 0000000..5f042d5
--- /dev/null
+++ b/fuzzer/corpus/f8fc30c4cce63d22fb41139e708b4f98d7f38ece
Binary files differ
diff --git a/fuzzer/corpus/f90d5451a12269e8741ca300409625a4777a1154 b/fuzzer/corpus/f90d5451a12269e8741ca300409625a4777a1154
new file mode 100644
index 0000000..9149d92
--- /dev/null
+++ b/fuzzer/corpus/f90d5451a12269e8741ca300409625a4777a1154
Binary files differ
diff --git a/fuzzer/corpus/f947a74b759dd42139105ae61530e963ef820a73 b/fuzzer/corpus/f947a74b759dd42139105ae61530e963ef820a73
new file mode 100644
index 0000000..0edd39f
--- /dev/null
+++ b/fuzzer/corpus/f947a74b759dd42139105ae61530e963ef820a73
Binary files differ
diff --git a/fuzzer/corpus/f94e071cda73362ae8c284c132b05f4c32b2f12a b/fuzzer/corpus/f94e071cda73362ae8c284c132b05f4c32b2f12a
new file mode 100644
index 0000000..bdb1030
--- /dev/null
+++ b/fuzzer/corpus/f94e071cda73362ae8c284c132b05f4c32b2f12a
Binary files differ
diff --git a/fuzzer/corpus/f9959c016e9fbfffb053f7e7903e91b1abf6a158 b/fuzzer/corpus/f9959c016e9fbfffb053f7e7903e91b1abf6a158
new file mode 100644
index 0000000..e876689
--- /dev/null
+++ b/fuzzer/corpus/f9959c016e9fbfffb053f7e7903e91b1abf6a158
Binary files differ
diff --git a/fuzzer/corpus/f9f58b28c95cab0f2dacdf70e2f05f64850feeba b/fuzzer/corpus/f9f58b28c95cab0f2dacdf70e2f05f64850feeba
new file mode 100644
index 0000000..641f266
--- /dev/null
+++ b/fuzzer/corpus/f9f58b28c95cab0f2dacdf70e2f05f64850feeba
Binary files differ
diff --git a/fuzzer/corpus/fa62977bddda089217691293964db3bd5ca6bec8 b/fuzzer/corpus/fa62977bddda089217691293964db3bd5ca6bec8
new file mode 100644
index 0000000..0b40d82
--- /dev/null
+++ b/fuzzer/corpus/fa62977bddda089217691293964db3bd5ca6bec8
Binary files differ
diff --git a/fuzzer/corpus/fa681fedd2c6fa734ce1bd9d7d8fef7138fea1da b/fuzzer/corpus/fa681fedd2c6fa734ce1bd9d7d8fef7138fea1da
new file mode 100644
index 0000000..a3fdfbc
--- /dev/null
+++ b/fuzzer/corpus/fa681fedd2c6fa734ce1bd9d7d8fef7138fea1da
Binary files differ
diff --git a/fuzzer/corpus/fa8c4015a7c03bd2b1af712b148fb6a46976ac30 b/fuzzer/corpus/fa8c4015a7c03bd2b1af712b148fb6a46976ac30
new file mode 100644
index 0000000..d42e27a
--- /dev/null
+++ b/fuzzer/corpus/fa8c4015a7c03bd2b1af712b148fb6a46976ac30
Binary files differ
diff --git a/fuzzer/corpus/fabb1d677b8be9d34302f327370d1a069d5cd732 b/fuzzer/corpus/fabb1d677b8be9d34302f327370d1a069d5cd732
new file mode 100644
index 0000000..bac9c17
--- /dev/null
+++ b/fuzzer/corpus/fabb1d677b8be9d34302f327370d1a069d5cd732
Binary files differ
diff --git a/fuzzer/corpus/faf91d41b88e0ebfdbe16c133f8aec4f54643867 b/fuzzer/corpus/faf91d41b88e0ebfdbe16c133f8aec4f54643867
new file mode 100644
index 0000000..0f413f1
--- /dev/null
+++ b/fuzzer/corpus/faf91d41b88e0ebfdbe16c133f8aec4f54643867
Binary files differ
diff --git a/fuzzer/corpus/fb05ad8533dbea37b825c735a8f275747d3c3d65 b/fuzzer/corpus/fb05ad8533dbea37b825c735a8f275747d3c3d65
new file mode 100644
index 0000000..5d194b6
--- /dev/null
+++ b/fuzzer/corpus/fb05ad8533dbea37b825c735a8f275747d3c3d65
Binary files differ
diff --git a/fuzzer/corpus/fb265cb36d03f402dd09a1d8743bfcfb52948b1b b/fuzzer/corpus/fb265cb36d03f402dd09a1d8743bfcfb52948b1b
new file mode 100644
index 0000000..8a16d32
--- /dev/null
+++ b/fuzzer/corpus/fb265cb36d03f402dd09a1d8743bfcfb52948b1b
Binary files differ
diff --git a/fuzzer/corpus/fb3e9f119af88a194e4cc46a07d0980e0d08472d b/fuzzer/corpus/fb3e9f119af88a194e4cc46a07d0980e0d08472d
new file mode 100644
index 0000000..5327452
--- /dev/null
+++ b/fuzzer/corpus/fb3e9f119af88a194e4cc46a07d0980e0d08472d
Binary files differ
diff --git a/fuzzer/corpus/fb70ffd57de084a797500e21986f07f185aa56a2 b/fuzzer/corpus/fb70ffd57de084a797500e21986f07f185aa56a2
new file mode 100644
index 0000000..d95aae2
--- /dev/null
+++ b/fuzzer/corpus/fb70ffd57de084a797500e21986f07f185aa56a2
Binary files differ
diff --git a/fuzzer/corpus/fba421b338b3eb9f7752d8cc1eeda8c7b28f8eb8 b/fuzzer/corpus/fba421b338b3eb9f7752d8cc1eeda8c7b28f8eb8
new file mode 100644
index 0000000..93c3f4c
--- /dev/null
+++ b/fuzzer/corpus/fba421b338b3eb9f7752d8cc1eeda8c7b28f8eb8
Binary files differ
diff --git a/fuzzer/corpus/fbb77700114cb0c0bb6584fdb3c6b90525fb3c69 b/fuzzer/corpus/fbb77700114cb0c0bb6584fdb3c6b90525fb3c69
new file mode 100644
index 0000000..541632d
--- /dev/null
+++ b/fuzzer/corpus/fbb77700114cb0c0bb6584fdb3c6b90525fb3c69
Binary files differ
diff --git a/fuzzer/corpus/fbbb4a8e282ecccbb507e979c4d5b25a1474a432 b/fuzzer/corpus/fbbb4a8e282ecccbb507e979c4d5b25a1474a432
new file mode 100644
index 0000000..ef23de1
--- /dev/null
+++ b/fuzzer/corpus/fbbb4a8e282ecccbb507e979c4d5b25a1474a432
Binary files differ
diff --git a/fuzzer/corpus/fbc0ed074c7a4e9701c7dd5fb3f22faae83b72dc b/fuzzer/corpus/fbc0ed074c7a4e9701c7dd5fb3f22faae83b72dc
new file mode 100644
index 0000000..330a61d
--- /dev/null
+++ b/fuzzer/corpus/fbc0ed074c7a4e9701c7dd5fb3f22faae83b72dc
Binary files differ
diff --git a/fuzzer/corpus/fbd727f72b075dfd8b65a063d25616d88bc55a58 b/fuzzer/corpus/fbd727f72b075dfd8b65a063d25616d88bc55a58
new file mode 100644
index 0000000..5621f8f
--- /dev/null
+++ b/fuzzer/corpus/fbd727f72b075dfd8b65a063d25616d88bc55a58
Binary files differ
diff --git a/fuzzer/corpus/fbd744c74addd2446bc3421ee255782745944912 b/fuzzer/corpus/fbd744c74addd2446bc3421ee255782745944912
new file mode 100644
index 0000000..8689778
--- /dev/null
+++ b/fuzzer/corpus/fbd744c74addd2446bc3421ee255782745944912
Binary files differ
diff --git a/fuzzer/corpus/fbe7d2fe74ec76c7315b1436a8eb1ef2bd71790d b/fuzzer/corpus/fbe7d2fe74ec76c7315b1436a8eb1ef2bd71790d
new file mode 100644
index 0000000..ddc6b25
--- /dev/null
+++ b/fuzzer/corpus/fbe7d2fe74ec76c7315b1436a8eb1ef2bd71790d
Binary files differ
diff --git a/fuzzer/corpus/fc0784659f2f2db14675c08091a72748e8bf0653 b/fuzzer/corpus/fc0784659f2f2db14675c08091a72748e8bf0653
new file mode 100644
index 0000000..a8b3083
--- /dev/null
+++ b/fuzzer/corpus/fc0784659f2f2db14675c08091a72748e8bf0653
Binary files differ
diff --git a/fuzzer/corpus/fc72627e1e118b27d857ecc821d7230a4a3e19ea b/fuzzer/corpus/fc72627e1e118b27d857ecc821d7230a4a3e19ea
new file mode 100644
index 0000000..a376192
--- /dev/null
+++ b/fuzzer/corpus/fc72627e1e118b27d857ecc821d7230a4a3e19ea
Binary files differ
diff --git a/fuzzer/corpus/fcbaa80ef465b04a9b23aed5fdeeb9bbae8a2be3 b/fuzzer/corpus/fcbaa80ef465b04a9b23aed5fdeeb9bbae8a2be3
new file mode 100644
index 0000000..f483148
--- /dev/null
+++ b/fuzzer/corpus/fcbaa80ef465b04a9b23aed5fdeeb9bbae8a2be3
Binary files differ
diff --git a/fuzzer/corpus/fcbfcc14b7ce95f3d4c79d3f0d013e26fbb3f90e b/fuzzer/corpus/fcbfcc14b7ce95f3d4c79d3f0d013e26fbb3f90e
new file mode 100644
index 0000000..6aec9c1
--- /dev/null
+++ b/fuzzer/corpus/fcbfcc14b7ce95f3d4c79d3f0d013e26fbb3f90e
Binary files differ
diff --git a/fuzzer/corpus/fcdec31a3bcb5e05058749746edf9ec860b54a85 b/fuzzer/corpus/fcdec31a3bcb5e05058749746edf9ec860b54a85
new file mode 100644
index 0000000..7ce214c
--- /dev/null
+++ b/fuzzer/corpus/fcdec31a3bcb5e05058749746edf9ec860b54a85
Binary files differ
diff --git a/fuzzer/corpus/fcf94887dc792d14601a0b1edf7bf2bc29ef8725 b/fuzzer/corpus/fcf94887dc792d14601a0b1edf7bf2bc29ef8725
new file mode 100644
index 0000000..7babf74
--- /dev/null
+++ b/fuzzer/corpus/fcf94887dc792d14601a0b1edf7bf2bc29ef8725
Binary files differ
diff --git a/fuzzer/corpus/fd567783b8f89ff8fff4b368e827cbc1ce4718db b/fuzzer/corpus/fd567783b8f89ff8fff4b368e827cbc1ce4718db
new file mode 100644
index 0000000..278c712
--- /dev/null
+++ b/fuzzer/corpus/fd567783b8f89ff8fff4b368e827cbc1ce4718db
Binary files differ
diff --git a/fuzzer/corpus/fd59c04966e702e69c1d1590444fc12cf512dac1 b/fuzzer/corpus/fd59c04966e702e69c1d1590444fc12cf512dac1
new file mode 100644
index 0000000..0d8d900
--- /dev/null
+++ b/fuzzer/corpus/fd59c04966e702e69c1d1590444fc12cf512dac1
Binary files differ
diff --git a/fuzzer/corpus/fd657ccaaca06d0a4ac30d7965c41cc2bee6978e b/fuzzer/corpus/fd657ccaaca06d0a4ac30d7965c41cc2bee6978e
new file mode 100644
index 0000000..096d2b8
--- /dev/null
+++ b/fuzzer/corpus/fd657ccaaca06d0a4ac30d7965c41cc2bee6978e
Binary files differ
diff --git a/fuzzer/corpus/fd7695c4e2aed317cb86e9c1074aeb8a989fda29 b/fuzzer/corpus/fd7695c4e2aed317cb86e9c1074aeb8a989fda29
new file mode 100644
index 0000000..fa1a57c
--- /dev/null
+++ b/fuzzer/corpus/fd7695c4e2aed317cb86e9c1074aeb8a989fda29
Binary files differ
diff --git a/fuzzer/corpus/fd95d937d82debbb85ad308e34c0b1756cab756b b/fuzzer/corpus/fd95d937d82debbb85ad308e34c0b1756cab756b
new file mode 100644
index 0000000..a6a7cad
--- /dev/null
+++ b/fuzzer/corpus/fd95d937d82debbb85ad308e34c0b1756cab756b
Binary files differ
diff --git a/fuzzer/corpus/fdd6a808066a675e9984542ba69ed74a95f478eb b/fuzzer/corpus/fdd6a808066a675e9984542ba69ed74a95f478eb
new file mode 100644
index 0000000..df19522
--- /dev/null
+++ b/fuzzer/corpus/fdd6a808066a675e9984542ba69ed74a95f478eb
Binary files differ
diff --git a/fuzzer/corpus/fe15945925e89be8249db3b968ef6b8bcfd762f4 b/fuzzer/corpus/fe15945925e89be8249db3b968ef6b8bcfd762f4
new file mode 100644
index 0000000..7160e14
--- /dev/null
+++ b/fuzzer/corpus/fe15945925e89be8249db3b968ef6b8bcfd762f4
Binary files differ
diff --git a/fuzzer/corpus/fe1f98b8e9556ab3ed1d1a43c981b52f6dfa6bb4 b/fuzzer/corpus/fe1f98b8e9556ab3ed1d1a43c981b52f6dfa6bb4
new file mode 100644
index 0000000..cc287af
--- /dev/null
+++ b/fuzzer/corpus/fe1f98b8e9556ab3ed1d1a43c981b52f6dfa6bb4
Binary files differ
diff --git a/fuzzer/corpus/fe63f261780d7277153370152ead17700d939b68 b/fuzzer/corpus/fe63f261780d7277153370152ead17700d939b68
new file mode 100644
index 0000000..2e0fec9
--- /dev/null
+++ b/fuzzer/corpus/fe63f261780d7277153370152ead17700d939b68
Binary files differ
diff --git a/fuzzer/corpus/fe73188af7332dbd41e13f0d6eb68813cfe666dd b/fuzzer/corpus/fe73188af7332dbd41e13f0d6eb68813cfe666dd
new file mode 100644
index 0000000..c1ceb98
--- /dev/null
+++ b/fuzzer/corpus/fe73188af7332dbd41e13f0d6eb68813cfe666dd
Binary files differ
diff --git a/fuzzer/corpus/fe9fb4a8ee8df6455e2f58dd5e0fa18d258c8767 b/fuzzer/corpus/fe9fb4a8ee8df6455e2f58dd5e0fa18d258c8767
new file mode 100644
index 0000000..edd6624
--- /dev/null
+++ b/fuzzer/corpus/fe9fb4a8ee8df6455e2f58dd5e0fa18d258c8767
Binary files differ
diff --git a/fuzzer/corpus/fef53990a9dfa6829c236f68a51dd273054184fd b/fuzzer/corpus/fef53990a9dfa6829c236f68a51dd273054184fd
new file mode 100644
index 0000000..ee4fa08
--- /dev/null
+++ b/fuzzer/corpus/fef53990a9dfa6829c236f68a51dd273054184fd
Binary files differ
diff --git a/fuzzer/corpus/ff2df20321ac2b49b512ef4736fffd5e3d68ac1c b/fuzzer/corpus/ff2df20321ac2b49b512ef4736fffd5e3d68ac1c
new file mode 100644
index 0000000..3b3c5a4
--- /dev/null
+++ b/fuzzer/corpus/ff2df20321ac2b49b512ef4736fffd5e3d68ac1c
Binary files differ
diff --git a/fuzzer/corpus/ff58579901a8a58274becfa93bc44365a321d22b b/fuzzer/corpus/ff58579901a8a58274becfa93bc44365a321d22b
new file mode 100644
index 0000000..95d9df4
--- /dev/null
+++ b/fuzzer/corpus/ff58579901a8a58274becfa93bc44365a321d22b
Binary files differ
diff --git a/fuzzer/corpus/ffd4a31dc7415d314324661df7153aa31640af99 b/fuzzer/corpus/ffd4a31dc7415d314324661df7153aa31640af99
new file mode 100644
index 0000000..a24770f
--- /dev/null
+++ b/fuzzer/corpus/ffd4a31dc7415d314324661df7153aa31640af99
Binary files differ
diff --git a/fuzzer/corpus/ffedcc07b024a76f6e6b859d61c87cc035012201 b/fuzzer/corpus/ffedcc07b024a76f6e6b859d61c87cc035012201
new file mode 100644
index 0000000..4322932
--- /dev/null
+++ b/fuzzer/corpus/ffedcc07b024a76f6e6b859d61c87cc035012201
Binary files differ
diff --git a/fuzzer/corpus/ffef8bebf9bb707a5cb7d9bb55eb1b3d8f54d702 b/fuzzer/corpus/ffef8bebf9bb707a5cb7d9bb55eb1b3d8f54d702
new file mode 100644
index 0000000..abf5857
--- /dev/null
+++ b/fuzzer/corpus/ffef8bebf9bb707a5cb7d9bb55eb1b3d8f54d702
Binary files differ
diff --git a/fuzzer/corpus/fff73fea62e77e16da2a1773de25945f4860a991 b/fuzzer/corpus/fff73fea62e77e16da2a1773de25945f4860a991
new file mode 100644
index 0000000..fcfe4e4
--- /dev/null
+++ b/fuzzer/corpus/fff73fea62e77e16da2a1773de25945f4860a991
Binary files differ
diff --git a/fuzzer/corpus/fffa69b8781b3df9711059a17d365670c037b419 b/fuzzer/corpus/fffa69b8781b3df9711059a17d365670c037b419
new file mode 100644
index 0000000..50d95bd
--- /dev/null
+++ b/fuzzer/corpus/fffa69b8781b3df9711059a17d365670c037b419
Binary files differ
diff --git a/fuzzer/fuzzer.c b/fuzzer/fuzzer.c
new file mode 100644
index 0000000..1863e34
--- /dev/null
+++ b/fuzzer/fuzzer.c
@@ -0,0 +1,936 @@
+/* By Guido Vranken <guidovranken@gmail.com> --
+ * https://guidovranken.wordpress.com/ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <limits.h>
+#include "srtp.h"
+#include "srtp_priv.h"
+#include "ekt.h"
+#include "fuzzer.h"
+#include "mt19937.h"
+#include "testmem.h"
+
+/* Global variables */
+static bool g_no_align = false; /* Can be enabled with --no_align */
+static bool g_post_init =
+    false; /* Set to true once past initialization phase */
+static bool g_write_input = false;
+
+#ifdef FUZZ_32BIT
+#include <sys/mman.h>
+static bool g_no_mmap = false; /* Can be enabled with --no_mmap */
+static void *g_mmap_allocation =
+    NULL; /* Keeps current mmap() allocation address */
+static size_t g_mmap_allocation_size =
+    0; /* Keeps current mmap() allocation size */
+#endif
+
+/* Custom allocator functions */
+
+static void *fuzz_alloc(const size_t size, const bool do_zero)
+{
+    void *ret = NULL;
+#ifdef FUZZ_32BIT
+    bool do_malloc = true;
+#endif
+    bool do_mmap, mmap_high = true;
+
+    if (size == 0) {
+        size_t ret;
+        /* Allocations of size 0 are not illegal, but are a bad practice, since
+         * writing just a single byte to this region constitutes undefined
+         * behavior per the C spec. glibc will return a small, valid memory
+         * region
+         * whereas OpenBSD will crash upon writing to it.
+         * Intentionally return a pointer to an invalid page to detect
+         * unsound code efficiently.
+         * fuzz_free is aware of this pointer range and will not attempt
+         * to free()/munmap() it.
+         */
+        ret = 0x01 + (fuzz_mt19937_get() % 1024);
+        return (void *)ret;
+    }
+
+    /* Don't do mmap()-based allocations during initialization */
+    if (g_post_init == true) {
+        /* Even extract these values if --no_mmap is specified.
+         * This keeps the PRNG output stream consistent across
+         * fuzzer configurations.
+         */
+        do_mmap = (fuzz_mt19937_get() % 64) == 0 ? true : false;
+        if (do_mmap == true) {
+            mmap_high = (fuzz_mt19937_get() % 2) == 0 ? true : false;
+        }
+    } else {
+        do_mmap = false;
+    }
+
+#ifdef FUZZ_32BIT
+    /* g_mmap_allocation must be NULL because we only support a single
+     * concurrent mmap allocation at a time
+     */
+    if (g_mmap_allocation == NULL && g_no_mmap == false && do_mmap == true) {
+        void *mmap_address;
+        if (mmap_high == true) {
+            mmap_address = (void *)0xFFFF0000;
+        } else {
+            mmap_address = (void *)0x00010000;
+        }
+        g_mmap_allocation_size = size;
+
+        ret = mmap(mmap_address, g_mmap_allocation_size, PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+        if (ret == MAP_FAILED) {
+            /* That's okay -- just return NULL to the caller */
+
+            ret = NULL;
+
+            /* Reset this for the sake of cleanliness */
+            g_mmap_allocation_size = 0;
+        }
+        /* ret not being MAP_FAILED does not mean that ret is the requested
+         * address (mmap_address). That's okay. We're not going to perform
+         * a munmap() on it and call malloc() instead. It won't gain us
+         * anything.
+         */
+
+        g_mmap_allocation = ret;
+        do_malloc = false;
+    }
+
+    if (do_malloc == true)
+#endif
+    {
+        ret = malloc(size);
+    }
+
+    /* Mimic calloc() if so requested */
+    if (ret != NULL && do_zero) {
+        memset(ret, 0, size);
+    }
+
+    return ret;
+}
+
+/* Internal allocations by this fuzzer must on one hand (sometimes)
+ * receive memory from mmap(), but on the other hand these requests for
+ * memory may not fail. By calling this function, the allocation is
+ * guaranteed to succeed; it first tries with fuzz_alloc(), which may
+ * fail if it uses mmap(), and if that is the case, memory is allocated
+ * via the libc allocator (malloc, calloc) which should always succeed */
+static void *fuzz_alloc_succeed(const size_t size, const bool do_zero)
+{
+    void *ret = fuzz_alloc(size, do_zero);
+    if (ret == NULL) {
+        if (do_zero == false) {
+            ret = malloc(size);
+        } else {
+            ret = calloc(1, size);
+        }
+    }
+
+    return ret;
+}
+
+void *fuzz_calloc(const size_t nmemb, const size_t size)
+{
+    /* We must be past srtp_init() to prevent that that function fails */
+    if (g_post_init == true) {
+        /* Fail 1 in 64 allocations on average to test whether the library
+         * can deal with this properly.
+         */
+        if ((fuzz_mt19937_get() % 64) == 0) {
+            return NULL;
+        }
+    }
+
+    return fuzz_alloc(nmemb * size, true);
+}
+
+static bool fuzz_is_special_pointer(void *ptr)
+{
+    /* Special, invalid pointers introduced when code attempted
+     * to do size = 0 allocations.
+     */
+    if ((size_t)ptr >= 0x01 && (size_t)ptr < (0x01 + 1024)) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+void fuzz_free(void *ptr)
+{
+    if (fuzz_is_special_pointer(ptr) == true) {
+        return;
+    }
+
+#ifdef FUZZ_32BIT
+    if (g_post_init == true && ptr != NULL && ptr == g_mmap_allocation) {
+        if (munmap(g_mmap_allocation, g_mmap_allocation_size) == -1) {
+            /* Shouldn't happen */
+            abort();
+        }
+        g_mmap_allocation = NULL;
+    } else
+#endif
+    {
+        free(ptr);
+    }
+}
+
+static srtp_err_status_t fuzz_srtp_protect(srtp_t srtp_sender,
+                                           void *hdr,
+                                           int *len,
+                                           uint8_t use_mki,
+                                           unsigned int mki)
+{
+    return srtp_protect(srtp_sender, hdr, len);
+}
+
+static srtp_err_status_t fuzz_srtp_unprotect(srtp_t srtp_sender,
+                                             void *hdr,
+                                             int *len,
+                                             uint8_t use_mki,
+                                             unsigned int mki)
+{
+    return srtp_unprotect(srtp_sender, hdr, len);
+}
+
+static srtp_err_status_t fuzz_srtp_protect_rtcp(srtp_t srtp_sender,
+                                                void *hdr,
+                                                int *len,
+                                                uint8_t use_mki,
+                                                unsigned int mki)
+{
+    return srtp_protect_rtcp(srtp_sender, hdr, len);
+}
+
+static srtp_err_status_t fuzz_srtp_unprotect_rtcp(srtp_t srtp_sender,
+                                                  void *hdr,
+                                                  int *len,
+                                                  uint8_t use_mki,
+                                                  unsigned int mki)
+{
+    return srtp_unprotect_rtcp(srtp_sender, hdr, len);
+}
+
+static srtp_err_status_t fuzz_srtp_protect_mki(srtp_t srtp_sender,
+                                               void *hdr,
+                                               int *len,
+                                               uint8_t use_mki,
+                                               unsigned int mki)
+{
+    return srtp_protect_mki(srtp_sender, hdr, len, use_mki, mki);
+}
+
+static srtp_err_status_t fuzz_srtp_protect_rtcp_mki(srtp_t srtp_sender,
+                                                    void *hdr,
+                                                    int *len,
+                                                    uint8_t use_mki,
+                                                    unsigned int mki)
+{
+    return srtp_protect_rtcp_mki(srtp_sender, hdr, len, use_mki, mki);
+}
+
+static srtp_err_status_t fuzz_srtp_unprotect_mki(srtp_t srtp_sender,
+                                                 void *hdr,
+                                                 int *len,
+                                                 uint8_t use_mki,
+                                                 unsigned int mki)
+{
+    return srtp_unprotect_mki(srtp_sender, hdr, len, use_mki);
+}
+
+static srtp_err_status_t fuzz_srtp_unprotect_rtcp_mki(srtp_t srtp_sender,
+                                                      void *hdr,
+                                                      int *len,
+                                                      uint8_t use_mki,
+                                                      unsigned int mki)
+{
+    return srtp_unprotect_rtcp_mki(srtp_sender, hdr, len, use_mki);
+}
+
+/* Get protect length functions */
+
+static srtp_err_status_t fuzz_srtp_get_protect_length(const srtp_t srtp_ctx,
+                                                      uint8_t use_mki,
+                                                      unsigned int mki,
+                                                      uint32_t *length)
+{
+    return srtp_get_protect_trailer_length(srtp_ctx, 0, 0, length);
+}
+
+static srtp_err_status_t fuzz_srtp_get_protect_rtcp_length(
+    const srtp_t srtp_ctx,
+    uint8_t use_mki,
+    unsigned int mki,
+    uint32_t *length)
+{
+    return srtp_get_protect_rtcp_trailer_length(srtp_ctx, 0, 0, length);
+}
+
+static srtp_err_status_t fuzz_srtp_get_protect_mki_length(const srtp_t srtp_ctx,
+                                                          uint8_t use_mki,
+                                                          unsigned int mki,
+                                                          uint32_t *length)
+{
+    return srtp_get_protect_trailer_length(srtp_ctx, use_mki, mki, length);
+}
+
+static srtp_err_status_t fuzz_srtp_get_protect_rtcp_mki_length(
+    const srtp_t srtp_ctx,
+    uint8_t use_mki,
+    unsigned int mki,
+    uint32_t *length)
+{
+    return srtp_get_protect_rtcp_trailer_length(srtp_ctx, use_mki, mki, length);
+}
+
+static uint8_t *extract_key(const uint8_t **data,
+                            size_t *size,
+                            const size_t key_size)
+{
+    uint8_t *ret;
+    if (*size < key_size) {
+        return NULL;
+    }
+
+    ret = fuzz_alloc_succeed(key_size, false);
+    EXTRACT(ret, *data, *size, key_size);
+
+    return ret;
+}
+
+static srtp_master_key_t *extract_master_key(const uint8_t **data,
+                                             size_t *size,
+                                             const size_t key_size,
+                                             bool simulate,
+                                             bool *success)
+{
+    srtp_master_key_t *ret = NULL;
+    uint16_t mki_id_size;
+
+    if (simulate == true) {
+        *success = false;
+    }
+
+    EXTRACT_IF(&mki_id_size, *data, *size, sizeof(mki_id_size));
+
+    if (*size < key_size + mki_id_size) {
+        goto end;
+    }
+
+    if (simulate == true) {
+        *data += key_size + mki_id_size;
+        *size -= key_size + mki_id_size;
+        *success = true;
+        goto end;
+    }
+
+    ret = fuzz_alloc_succeed(sizeof(srtp_master_key_t), false);
+    ret->key = fuzz_alloc_succeed(key_size, false);
+
+    ret->mki_id = fuzz_alloc_succeed(mki_id_size, false);
+
+    EXTRACT(ret->key, *data, *size, key_size);
+    EXTRACT(ret->mki_id, *data, *size, mki_id_size);
+    ret->mki_size = mki_id_size;
+end:
+    return ret;
+}
+
+static srtp_master_key_t **extract_master_keys(const uint8_t **data,
+                                               size_t *size,
+                                               const size_t key_size,
+                                               unsigned long *num_master_keys)
+{
+    const uint8_t *data_orig = *data;
+    size_t size_orig = *size;
+    size_t i = 0;
+
+    srtp_master_key_t **ret = NULL;
+
+    *num_master_keys = 0;
+
+    /* First pass -- dry run, determine how many keys we want and can extract */
+    while (1) {
+        uint8_t do_extract_master_key;
+        bool success;
+        if (*size < sizeof(do_extract_master_key)) {
+            goto next;
+        }
+        EXTRACT(&do_extract_master_key, *data, *size,
+                sizeof(do_extract_master_key));
+
+        /* Decide whether to extract another key */
+        if ((do_extract_master_key % 2) == 0) {
+            break;
+        }
+
+        extract_master_key(data, size, key_size, true, &success);
+
+        if (success == false) {
+            break;
+        }
+
+        (*num_master_keys)++;
+    }
+
+next:
+    *data = data_orig;
+    *size = size_orig;
+
+    /* Allocate array of pointers */
+    ret = fuzz_alloc_succeed(*num_master_keys * sizeof(srtp_master_key_t *),
+                             false);
+
+    /* Second pass -- perform the actual extractions */
+    for (i = 0; i < *num_master_keys; i++) {
+        uint8_t do_extract_master_key;
+        EXTRACT_IF(&do_extract_master_key, *data, *size,
+                   sizeof(do_extract_master_key));
+
+        if ((do_extract_master_key % 2) == 0) {
+            break;
+        }
+
+        ret[i] = extract_master_key(data, size, key_size, false, NULL);
+
+        if (ret[i] == NULL) {
+            /* Shouldn't happen */
+            abort();
+        }
+    }
+
+end:
+    return ret;
+}
+
+static srtp_ekt_policy_t extract_ekt_policy(const uint8_t **data, size_t *size)
+{
+    srtp_ekt_policy_t ret = NULL;
+    struct {
+        srtp_ekt_spi_t spi;
+        uint8_t key[16];
+
+    } params;
+
+    EXTRACT_IF(&params, *data, *size, sizeof(params));
+
+    ret = fuzz_alloc_succeed(sizeof(struct srtp_ekt_policy_ctx_t), false);
+
+    ret->spi = params.spi;
+
+    /* The only supported cipher type */
+    ret->ekt_cipher_type = SRTP_EKT_CIPHER_AES_128_ECB;
+
+    ret->ekt_key = fuzz_alloc_succeed(sizeof(params.key), false);
+    memcpy(ret->ekt_key, params.key, sizeof(params.key));
+
+    ret->next_ekt_policy = NULL;
+
+end:
+    return ret;
+}
+
+static srtp_policy_t *extract_policy(const uint8_t **data, size_t *size)
+{
+    srtp_policy_t *policy = NULL;
+    struct {
+        uint8_t srtp_crypto_policy_func;
+        uint64_t window_size;
+        uint8_t allow_repeat_tx;
+        uint8_t ssrc_type;
+        uint32_t ssrc_value;
+        uint8_t num_xtn_hdr;
+        uint8_t with_ekt;
+        srtp_ekt_spi_t ekt_spi;
+        uint8_t do_extract_key;
+        uint8_t do_extract_master_keys;
+    } params;
+
+    EXTRACT_IF(&params, *data, *size, sizeof(params));
+
+    params.srtp_crypto_policy_func %= sizeof(fuzz_srtp_crypto_policies) /
+                                      sizeof(fuzz_srtp_crypto_policies[0]);
+    params.allow_repeat_tx %= 2;
+    params.ssrc_type %=
+        sizeof(fuzz_ssrc_type_map) / sizeof(fuzz_ssrc_type_map[0]);
+    params.with_ekt %= 2;
+
+    policy = fuzz_alloc_succeed(sizeof(*policy), true);
+
+    fuzz_srtp_crypto_policies[params.srtp_crypto_policy_func]
+        .crypto_policy_func(&policy->rtp);
+    fuzz_srtp_crypto_policies[params.srtp_crypto_policy_func]
+        .crypto_policy_func(&policy->rtcp);
+
+    if (policy->rtp.cipher_key_len > MAX_KEY_LEN) {
+        /* Shouldn't happen */
+        abort();
+    }
+
+    policy->ssrc.type = fuzz_ssrc_type_map[params.ssrc_type].srtp_ssrc_type;
+    policy->ssrc.value = params.ssrc_value;
+
+    if ((params.do_extract_key % 2) == 0) {
+        policy->key = extract_key(data, size, policy->rtp.cipher_key_len);
+
+        if (policy->key == NULL) {
+            fuzz_free(policy);
+            return NULL;
+        }
+    }
+
+    if (params.num_xtn_hdr != 0) {
+        const size_t xtn_hdr_size = params.num_xtn_hdr * sizeof(int);
+        if (*size < xtn_hdr_size) {
+            fuzz_free(policy->key);
+            fuzz_free(policy);
+            return NULL;
+        }
+        policy->enc_xtn_hdr = fuzz_alloc_succeed(xtn_hdr_size, false);
+        EXTRACT(policy->enc_xtn_hdr, *data, *size, xtn_hdr_size);
+        policy->enc_xtn_hdr_count = params.num_xtn_hdr;
+    }
+
+    if ((params.do_extract_master_keys % 2) == 0) {
+        policy->keys = extract_master_keys(
+            data, size, policy->rtp.cipher_key_len, &policy->num_master_keys);
+        if (policy->keys == NULL) {
+            fuzz_free(policy->key);
+            fuzz_free(policy->enc_xtn_hdr);
+            fuzz_free(policy);
+            return NULL;
+        }
+    }
+
+    if (params.with_ekt) {
+        policy->ekt = extract_ekt_policy(data, size);
+    }
+
+    policy->window_size = params.window_size;
+    policy->allow_repeat_tx = params.allow_repeat_tx;
+    policy->next = NULL;
+
+end:
+    return policy;
+}
+
+static srtp_policy_t *extract_policies(const uint8_t **data, size_t *size)
+{
+    srtp_policy_t *curpolicy = NULL, *policy_chain = NULL;
+
+    curpolicy = extract_policy(data, size);
+    if (curpolicy == NULL) {
+        return NULL;
+    }
+
+    policy_chain = curpolicy;
+
+    while (1) {
+        uint8_t do_extract_policy;
+        EXTRACT_IF(&do_extract_policy, *data, *size, sizeof(do_extract_policy));
+
+        /* Decide whether to extract another policy */
+        if ((do_extract_policy % 2) == 0) {
+            break;
+        }
+
+        curpolicy->next = extract_policy(data, size);
+        if (curpolicy->next == NULL) {
+            break;
+        }
+        curpolicy = curpolicy->next;
+    }
+
+end:
+    return policy_chain;
+}
+
+static uint32_t *extract_remove_stream_ssrc(const uint8_t **data,
+                                            size_t *size,
+                                            uint8_t *num_remove_stream)
+{
+    uint32_t *ret = NULL;
+    uint8_t _num_remove_stream;
+    size_t total_size;
+
+    *num_remove_stream = 0;
+
+    EXTRACT_IF(&_num_remove_stream, *data, *size, sizeof(_num_remove_stream));
+
+    if (_num_remove_stream == 0) {
+        goto end;
+    }
+
+    total_size = _num_remove_stream * sizeof(uint32_t);
+
+    if (*size < total_size) {
+        goto end;
+    }
+
+    ret = fuzz_alloc_succeed(total_size, false);
+    EXTRACT(ret, *data, *size, total_size);
+
+    *num_remove_stream = _num_remove_stream;
+
+end:
+    return ret;
+}
+
+static uint32_t *extract_set_roc(const uint8_t **data,
+                                 size_t *size,
+                                 uint8_t *num_set_roc)
+{
+    uint32_t *ret = NULL;
+    uint8_t _num_set_roc;
+    size_t total_size;
+
+    *num_set_roc = 0;
+    EXTRACT_IF(&_num_set_roc, *data, *size, sizeof(_num_set_roc));
+    if (_num_set_roc == 0) {
+        goto end;
+    }
+
+    /* Tuples of 2 uint32_t's */
+    total_size = _num_set_roc * sizeof(uint32_t) * 2;
+
+    if (*size < total_size) {
+        goto end;
+    }
+
+    ret = fuzz_alloc_succeed(total_size, false);
+    EXTRACT(ret, *data, *size, total_size);
+
+    *num_set_roc = _num_set_roc;
+
+end:
+    return ret;
+}
+
+static void free_policies(srtp_policy_t *curpolicy)
+{
+    size_t i;
+    while (curpolicy) {
+        srtp_policy_t *next = curpolicy->next;
+
+        fuzz_free(curpolicy->key);
+
+        for (i = 0; i < curpolicy->num_master_keys; i++) {
+            fuzz_free(curpolicy->keys[i]->key);
+            fuzz_free(curpolicy->keys[i]->mki_id);
+            fuzz_free(curpolicy->keys[i]);
+        }
+
+        fuzz_free(curpolicy->keys);
+        fuzz_free(curpolicy->enc_xtn_hdr);
+
+        if (curpolicy->ekt) {
+            fuzz_free(curpolicy->ekt->ekt_key);
+            fuzz_free(curpolicy->ekt);
+        }
+
+        fuzz_free(curpolicy);
+
+        curpolicy = next;
+    }
+}
+
+static uint8_t *run_srtp_func(const srtp_t srtp_ctx,
+                              const uint8_t **data,
+                              size_t *size)
+{
+    uint8_t *ret = NULL;
+    uint8_t *copy = NULL, *copy_2 = NULL;
+
+    struct {
+        uint16_t size;
+        uint8_t srtp_func;
+        uint8_t use_mki;
+        uint32_t mki;
+        uint8_t stretch;
+    } params_1;
+
+    struct {
+        uint8_t srtp_func;
+        uint8_t use_mki;
+        uint32_t mki;
+    } params_2;
+    int ret_size;
+
+    EXTRACT_IF(&params_1, *data, *size, sizeof(params_1));
+    params_1.srtp_func %= sizeof(srtp_funcs) / sizeof(srtp_funcs[0]);
+    params_1.use_mki %= 2;
+
+    if (*size < params_1.size) {
+        goto end;
+    }
+
+    /* Enforce 4 byte alignment */
+    if (g_no_align == false) {
+        params_1.size -= params_1.size % 4;
+    }
+
+    if (params_1.size == 0) {
+        goto end;
+    }
+
+    ret_size = params_1.size;
+    if (srtp_funcs[params_1.srtp_func].protect == true) {
+        /* Intentionally not initialized to trigger MemorySanitizer, if
+         * applicable */
+        uint32_t alloc_size;
+
+        if (srtp_funcs[params_1.srtp_func].get_length(
+                srtp_ctx, params_1.use_mki, params_1.mki, &alloc_size) !=
+            srtp_err_status_ok) {
+            goto end;
+        }
+
+        copy = fuzz_alloc_succeed(ret_size + alloc_size, false);
+    } else {
+        copy = fuzz_alloc_succeed(ret_size, false);
+    }
+
+    EXTRACT(copy, *data, *size, params_1.size);
+
+    if (srtp_funcs[params_1.srtp_func].srtp_func(
+            srtp_ctx, copy, &ret_size, params_1.use_mki, params_1.mki) !=
+        srtp_err_status_ok) {
+        fuzz_free(copy);
+        goto end;
+    }
+    // fuzz_free(copy);
+
+    fuzz_testmem(copy, ret_size);
+
+    ret = copy;
+
+    EXTRACT_IF(&params_2, *data, *size, sizeof(params_2));
+    params_2.srtp_func %= sizeof(srtp_funcs) / sizeof(srtp_funcs[0]);
+    params_2.use_mki %= 2;
+
+    if (ret_size == 0) {
+        goto end;
+    }
+
+    if (srtp_funcs[params_2.srtp_func].protect == true) {
+        /* Intentionally not initialized to trigger MemorySanitizer, if
+         * applicable */
+        uint32_t alloc_size;
+
+        if (srtp_funcs[params_2.srtp_func].get_length(
+                srtp_ctx, params_2.use_mki, params_2.mki, &alloc_size) !=
+            srtp_err_status_ok) {
+            goto end;
+        }
+
+        copy_2 = fuzz_alloc_succeed(ret_size + alloc_size, false);
+    } else {
+        copy_2 = fuzz_alloc_succeed(ret_size, false);
+    }
+
+    memcpy(copy_2, copy, ret_size);
+    fuzz_free(copy);
+    copy = copy_2;
+
+    if (srtp_funcs[params_2.srtp_func].srtp_func(
+            srtp_ctx, copy, &ret_size, params_2.use_mki, params_2.mki) !=
+        srtp_err_status_ok) {
+        fuzz_free(copy);
+        ret = NULL;
+        goto end;
+    }
+
+    fuzz_testmem(copy, ret_size);
+
+    ret = copy;
+
+end:
+    return ret;
+}
+
+void fuzz_srtp_event_handler(srtp_event_data_t *data)
+{
+    fuzz_testmem(data, sizeof(srtp_event_data_t));
+    if (data->session != NULL) {
+        fuzz_testmem(data->session, sizeof(*data->session));
+    }
+}
+
+static void fuzz_write_input(const uint8_t *data, size_t size)
+{
+    FILE *fp = fopen("input.bin", "wb");
+
+    if (fp == NULL) {
+        /* Shouldn't happen */
+        abort();
+    }
+
+    if (size != 0 && fwrite(data, size, 1, fp) != 1) {
+        printf("Cannot write\n");
+        /* Shouldn't happen */
+        abort();
+    }
+
+    fclose(fp);
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+    char **_argv = *argv;
+    int i;
+    bool no_custom_event_handler = false;
+
+    if (srtp_init() != srtp_err_status_ok) {
+        /* Shouldn't happen */
+        abort();
+    }
+
+    for (i = 0; i < *argc; i++) {
+        if (strcmp("--no_align", _argv[i]) == 0) {
+            g_no_align = true;
+        } else if (strcmp("--no_custom_event_handler", _argv[i]) == 0) {
+            no_custom_event_handler = true;
+        } else if (strcmp("--write_input", _argv[i]) == 0) {
+            g_write_input = true;
+        }
+#ifdef FUZZ_32BIT
+        else if (strcmp("--no_mmap", _argv[i]) == 0) {
+            g_no_mmap = true;
+        }
+#endif
+        else if (strncmp("--", _argv[i], 2) == 0) {
+            printf("Invalid argument: %s\n", _argv[i]);
+            exit(0);
+        }
+    }
+
+    if (no_custom_event_handler == false) {
+        if (srtp_install_event_handler(fuzz_srtp_event_handler) !=
+            srtp_err_status_ok) {
+            /* Shouldn't happen */
+            abort();
+        }
+    }
+
+    /* Fully initialized -- past this point, simulated allocation failures
+     * are allowed to occur */
+    g_post_init = true;
+
+    return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    uint8_t num_remove_stream;
+    uint32_t *remove_stream_ssrc = NULL;
+    uint8_t num_set_roc;
+    uint32_t *set_roc = NULL;
+    srtp_t srtp_ctx = NULL;
+    srtp_policy_t *policy_chain = NULL, *policy_chain_2 = NULL;
+    uint32_t randseed;
+    static bool firstrun = true;
+
+    if (firstrun == true) {
+        /* TODO version check etc and send it to MSAN */
+    }
+
+#ifdef FUZZ_32BIT
+    /* Free the mmap allocation made during the previous iteration, if
+     * applicable */
+    fuzz_free(g_mmap_allocation);
+#endif
+
+    if (g_write_input == true) {
+        fuzz_write_input(data, size);
+    }
+
+    EXTRACT_IF(&randseed, data, size, sizeof(randseed));
+    fuzz_mt19937_init(randseed);
+    srand(randseed);
+
+    /* policy_chain is used to initialize the srtp context with */
+    if ((policy_chain = extract_policies(&data, &size)) == NULL) {
+        goto end;
+    }
+    /* policy_chain_2 is used as an argument to srtp_update later on */
+    if ((policy_chain_2 = extract_policies(&data, &size)) == NULL) {
+        goto end;
+    }
+
+    /* Create context */
+    if (srtp_create(&srtp_ctx, policy_chain) != srtp_err_status_ok) {
+        goto end;
+    }
+
+    // free_policies(policy_chain);
+    // policy_chain = NULL;
+
+    /* Don't check for NULL result -- no extractions is fine */
+    remove_stream_ssrc =
+        extract_remove_stream_ssrc(&data, &size, &num_remove_stream);
+
+    /* Don't check for NULL result -- no extractions is fine */
+    set_roc = extract_set_roc(&data, &size, &num_set_roc);
+
+    {
+        uint8_t *ret;
+        int i = 0, j = 0;
+
+        while ((ret = run_srtp_func(srtp_ctx, &data, &size)) != NULL) {
+            fuzz_free(ret);
+
+            /* Keep removing streams until the set of SSRCs extracted from the
+             * fuzzer input is exhausted */
+            if (i < num_remove_stream) {
+                if (srtp_remove_stream(srtp_ctx, remove_stream_ssrc[i]) !=
+                    srtp_err_status_ok) {
+                    goto end;
+                }
+                i++;
+            }
+
+            /* Keep setting and getting ROCs until the set of SSRC/ROC tuples
+             * extracted from the fuzzer input is exhausted */
+            if (j < num_set_roc * 2) {
+                uint32_t roc;
+                if (srtp_set_stream_roc(srtp_ctx, set_roc[j], set_roc[j + 1]) !=
+                    srtp_err_status_ok) {
+                    goto end;
+                }
+                if (srtp_get_stream_roc(srtp_ctx, set_roc[j + 1], &roc) !=
+                    srtp_err_status_ok) {
+                    goto end;
+                }
+                j += 2;
+            }
+
+            if (policy_chain_2 != NULL) {
+                /* TODO srtp_update(srtp_ctx, policy_chain_2); */
+
+                /* Discard after using once */
+                free_policies(policy_chain_2);
+                policy_chain_2 = NULL;
+            }
+        }
+    }
+
+end:
+    free_policies(policy_chain);
+    free_policies(policy_chain_2);
+    fuzz_free(remove_stream_ssrc);
+    fuzz_free(set_roc);
+    if (srtp_ctx != NULL) {
+        srtp_dealloc(srtp_ctx);
+    }
+    fuzz_mt19937_destroy();
+
+    return 0;
+}
diff --git a/fuzzer/fuzzer.h b/fuzzer/fuzzer.h
new file mode 100644
index 0000000..ce1f8d6
--- /dev/null
+++ b/fuzzer/fuzzer.h
@@ -0,0 +1,176 @@
+#define MAX_KEY_LEN 46
+#define EXTRACT(dest, src, srcsize, copysize)                                  \
+    {                                                                          \
+        memcpy((dest), (src), (copysize));                                     \
+        (src) += (copysize);                                                   \
+        (srcsize) -= (copysize);                                               \
+    }
+
+/* Extract data if src contains sufficient bytes, otherwise go to end */
+#define EXTRACT_IF(dest, src, srcsize, copysize)                               \
+    {                                                                          \
+        if ((srcsize) < (copysize)) {                                          \
+            goto end;                                                          \
+        } else {                                                               \
+            EXTRACT((dest), (src), (srcsize), (copysize));                     \
+        }                                                                      \
+    }
+#include <stdint.h>
+#if UINTPTR_MAX == 0xffffffff
+#define FUZZ_32BIT
+#elif UINTPTR_MAX == 0xffffffffffffffff
+#else
+#error "Cannot detect word size"
+#endif
+
+typedef srtp_err_status_t (
+    *fuzz_srtp_func)(srtp_t, void *, int *, uint8_t, unsigned int);
+typedef void (*fuzz_srtp_crypto_policy_func)(srtp_crypto_policy_t *);
+typedef srtp_err_status_t (*fuzz_srtp_get_length_func)(const srtp_t,
+                                                       uint8_t,
+                                                       unsigned int,
+                                                       uint32_t *);
+
+struct fuzz_srtp_params {
+    uint8_t srtp_func;
+    uint8_t srtp_crypto_policy_func;
+    uint16_t window_size;
+    uint8_t allow_repeat_tx;
+    uint8_t ssrc_type;
+    unsigned int ssrc_value;
+    uint8_t key[MAX_KEY_LEN];
+    uint8_t mki;
+};
+
+static srtp_err_status_t fuzz_srtp_protect(srtp_t srtp_sender,
+                                           void *hdr,
+                                           int *len,
+                                           uint8_t use_mki,
+                                           unsigned int mki);
+static srtp_err_status_t fuzz_srtp_unprotect(srtp_t srtp_sender,
+                                             void *hdr,
+                                             int *len,
+                                             uint8_t use_mki,
+                                             unsigned int mki);
+static srtp_err_status_t fuzz_srtp_protect_rtcp(srtp_t srtp_sender,
+                                                void *hdr,
+                                                int *len,
+                                                uint8_t use_mki,
+                                                unsigned int mki);
+static srtp_err_status_t fuzz_srtp_unprotect_rtcp(srtp_t srtp_sender,
+                                                  void *hdr,
+                                                  int *len,
+                                                  uint8_t use_mki,
+                                                  unsigned int mki);
+static srtp_err_status_t fuzz_srtp_protect_mki(srtp_t srtp_sender,
+                                               void *hdr,
+                                               int *len,
+                                               uint8_t use_mki,
+                                               unsigned int mki);
+static srtp_err_status_t fuzz_srtp_protect_rtcp_mki(srtp_t srtp_sender,
+                                                    void *hdr,
+                                                    int *len,
+                                                    uint8_t use_mki,
+                                                    unsigned int mki);
+static srtp_err_status_t fuzz_srtp_unprotect_mki(srtp_t srtp_sender,
+                                                 void *hdr,
+                                                 int *len,
+                                                 uint8_t use_mki,
+                                                 unsigned int mki);
+static srtp_err_status_t fuzz_srtp_unprotect_rtcp_mki(srtp_t srtp_sender,
+                                                      void *hdr,
+                                                      int *len,
+                                                      uint8_t use_mki,
+                                                      unsigned int mki);
+
+static srtp_err_status_t fuzz_srtp_get_protect_length(const srtp_t srtp_ctx,
+                                                      uint8_t use_mki,
+                                                      unsigned int mki,
+                                                      uint32_t *length);
+static srtp_err_status_t fuzz_srtp_get_protect_mki_length(const srtp_t srtp_ctx,
+                                                          uint8_t use_mki,
+                                                          unsigned int mki,
+                                                          uint32_t *length);
+static srtp_err_status_t fuzz_srtp_get_protect_rtcp_length(
+    const srtp_t srtp_ctx,
+    uint8_t use_mki,
+    unsigned int mki,
+    uint32_t *length);
+static srtp_err_status_t fuzz_srtp_get_protect_rtcp_mki_length(
+    const srtp_t srtp_ctx,
+    uint8_t use_mki,
+    unsigned int mki,
+    uint32_t *length);
+
+struct fuzz_srtp_func_ext {
+    fuzz_srtp_func srtp_func;
+    bool protect;
+    fuzz_srtp_get_length_func get_length;
+};
+
+const struct fuzz_srtp_func_ext srtp_funcs[] = {
+    { fuzz_srtp_protect, true, fuzz_srtp_get_protect_length },
+    { fuzz_srtp_unprotect, false, NULL },
+    { fuzz_srtp_protect_rtcp, true, fuzz_srtp_get_protect_rtcp_length },
+    { fuzz_srtp_unprotect_rtcp, false, NULL },
+    { fuzz_srtp_protect_mki, true, fuzz_srtp_get_protect_mki_length },
+    { fuzz_srtp_unprotect_mki, false, NULL },
+    { fuzz_srtp_protect_rtcp_mki, true, fuzz_srtp_get_protect_rtcp_mki_length },
+    { fuzz_srtp_unprotect_rtcp_mki, false, NULL }
+};
+
+struct fuzz_srtp_crypto_policy_func_ext {
+    fuzz_srtp_crypto_policy_func crypto_policy_func;
+    const char *name;
+};
+
+const struct fuzz_srtp_crypto_policy_func_ext fuzz_srtp_crypto_policies[] = {
+    { srtp_crypto_policy_set_rtp_default, "" },
+    { srtp_crypto_policy_set_rtcp_default, "" },
+    { srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32,
+      "srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32" },
+    { srtp_crypto_policy_set_aes_cm_128_null_auth,
+      "srtp_crypto_policy_set_aes_cm_128_null_auth" },
+    { srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32,
+      "srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32" },
+    { srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80,
+      "srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80" },
+    { srtp_crypto_policy_set_aes_cm_256_null_auth,
+      "srtp_crypto_policy_set_aes_cm_256_null_auth" },
+    { srtp_crypto_policy_set_null_cipher_hmac_null,
+      "srtp_crypto_policy_set_null_cipher_hmac_null" },
+    { srtp_crypto_policy_set_null_cipher_hmac_sha1_80,
+      "srtp_crypto_policy_set_null_cipher_hmac_sha1_80" },
+#ifdef OPENSSL
+    { srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32,
+      "srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32" },
+    { srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80,
+      "srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80" },
+    { srtp_crypto_policy_set_aes_cm_192_null_auth,
+      "srtp_crypto_policy_set_aes_cm_192_null_auth" },
+    { srtp_crypto_policy_set_aes_gcm_128_16_auth,
+      "srtp_crypto_policy_set_aes_gcm_128_16_auth" },
+    { srtp_crypto_policy_set_aes_gcm_128_8_auth,
+      "srtp_crypto_policy_set_aes_gcm_128_8_auth" },
+    { srtp_crypto_policy_set_aes_gcm_128_8_only_auth,
+      "srtp_crypto_policy_set_aes_gcm_128_8_only_auth" },
+    { srtp_crypto_policy_set_aes_gcm_256_16_auth,
+      "srtp_crypto_policy_set_aes_gcm_256_16_auth" },
+    { srtp_crypto_policy_set_aes_gcm_256_8_auth,
+      "srtp_crypto_policy_set_aes_gcm_256_8_auth" },
+    { srtp_crypto_policy_set_aes_gcm_256_8_only_auth,
+      "srtp_crypto_policy_set_aes_gcm_256_8_only_auth" },
+#endif
+};
+
+struct fuzz_srtp_ssrc_type_ext {
+    srtp_ssrc_type_t srtp_ssrc_type;
+    const char *name;
+};
+
+const struct fuzz_srtp_ssrc_type_ext fuzz_ssrc_type_map[] = {
+    { ssrc_undefined, "ssrc_undefined" },
+    { ssrc_specific, "ssrc_specific" },
+    { ssrc_any_inbound, "ssrc_any_inbound" },
+    { ssrc_any_outbound, "ssrc_any_outbound" },
+};
diff --git a/fuzzer/mt19937.cpp b/fuzzer/mt19937.cpp
new file mode 100644
index 0000000..984f1fb
--- /dev/null
+++ b/fuzzer/mt19937.cpp
@@ -0,0 +1,17 @@
+#include <random>
+#include <cstdint>
+
+std::mt19937* mt_rand = NULL;
+
+extern "C" void fuzz_mt19937_init(uint32_t seed) {
+    mt_rand = new std::mt19937(seed);
+}
+
+extern "C" uint32_t fuzz_mt19937_get(void) {
+    return (*mt_rand)();
+}
+
+extern "C" void fuzz_mt19937_destroy(void) {
+    delete mt_rand;
+    mt_rand = NULL;
+}
diff --git a/fuzzer/mt19937.h b/fuzzer/mt19937.h
new file mode 100644
index 0000000..cda1181
--- /dev/null
+++ b/fuzzer/mt19937.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+void fuzz_mt19937_init(uint32_t seed);
+uint32_t fuzz_mt19937_get(void);
+void fuzz_mt19937_destroy(void);
diff --git a/fuzzer/testmem.c b/fuzzer/testmem.c
new file mode 100644
index 0000000..52370a4
--- /dev/null
+++ b/fuzzer/testmem.c
@@ -0,0 +1,25 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef FUZZ_MSAN
+#include <stdio.h>
+static void fuzz_testmem_msan(void *data, size_t size)
+{
+    /* This is a trick to force MemorySanitizer to evaluate the data at hand */
+    FILE *fp = fopen("/dev/null", "wb");
+    fwrite(data, size, 1, fp);
+    fclose(fp);
+}
+#endif
+
+void fuzz_testmem(void *data, size_t size)
+{
+#ifdef FUZZ_MSAN
+    fuzz_testmem_msan(data, size);
+#endif
+    uint8_t *copy = malloc(size);
+    memcpy(copy, data, size);
+    free(copy);
+}
diff --git a/fuzzer/testmem.h b/fuzzer/testmem.h
new file mode 100644
index 0000000..b00f309
--- /dev/null
+++ b/fuzzer/testmem.h
@@ -0,0 +1,3 @@
+#include <stdint.h>
+#include <stddef.h>
+void fuzz_testmem(void *data, size_t size);
diff --git a/include/ekt.h b/include/ekt.h
new file mode 100644
index 0000000..a289a53
--- /dev/null
+++ b/include/ekt.h
@@ -0,0 +1,181 @@
+/*
+ * ekt.h
+ *
+ * interface to Encrypted Key Transport for SRTP
+ *
+ * David McGrew
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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
+ *
+ * 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
+ *
+ * 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 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
+
+#define SRTP_EKT_CIPHER_DEFAULT 1
+#define SRTP_EKT_CIPHER_AES_128_ECB 1
+#define SRTP_EKT_CIPHER_AES_192_KEY_WRAP 2
+#define SRTP_EKT_CIPHER_AES_256_KEY_WRAP 3
+
+typedef uint16_t srtp_ekt_spi_t;
+
+unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt);
+
+/*
+ * an srtp_policy_t structure can contain a pointer to an
+ * 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 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 srtp_ekt_data_t structure holds the data corresponding to an ekt key,
+ * spi, and so on
+ */
+
+typedef struct srtp_ekt_data_t {
+    srtp_ekt_spi_t spi;
+    uint8_t ekt_cipher_type;
+    srtp_aes_expanded_key_t ekt_enc_key;
+    srtp_aes_expanded_key_t ekt_dec_key;
+    struct ekt_data_t *next_ekt_data;
+} srtp_ekt_data_t;
+
+/*
+ * an srtp_stream_ctx_t can contain an srtp_ekt_stream_ctx_t
+ *
+ * an srtp_ekt_stream_ctx_t structure holds all of the EKT information for
+ * a specific SRTP stream
+ */
+
+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;
+
+srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data,
+                                 srtp_ekt_policy_t policy);
+
+srtp_err_status_t srtp_ekt_stream_init(srtp_ekt_stream_t e,
+                                       srtp_ekt_spi_t spi,
+                                       void *ekt_key,
+                                       unsigned ekt_cipher_type);
+
+srtp_err_status_t srtp_ekt_stream_init_from_policy(srtp_ekt_stream_t e,
+                                                   srtp_ekt_policy_t p);
+
+srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
+                                            const void *srtcp_hdr,
+                                            unsigned pkt_octet_len);
+
+void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
+                         uint8_t *base_tag,
+                         unsigned base_tag_len,
+                         int *packet_len,
+                         srtp_xtd_seq_num_t pkt_index);
+
+/*
+ * 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
+ */
+srtp_err_status_t srtp_ekt_tag_verification_preproces(uint8_t *pkt_tag,
+                                                      uint8_t *pkt_tag_copy,
+                                                      unsigned tag_len);
+
+srtp_err_status_t srtp_ekt_tag_verification_postproces(uint8_t *pkt_tag,
+                                                       uint8_t *pkt_tag_copy,
+                                                       unsigned tag_len);
+
+/*
+ * @brief EKT pre-processing for srtcp tag generation
+ *
+ * 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.
+ *
+ */
+srtp_err_status_t srtp_stream_srtcp_auth_tag_generation_preprocess(
+    const srtp_stream_t *s,
+    uint8_t *pkt_tag,
+    unsigned pkt_octet_len);
+
+/* it's not clear that a tag_generation_postprocess function is needed */
+srtp_err_status_t srtcp_auth_tag_generation_postprocess(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_EKT_H */
diff --git a/include/err.h b/include/err.h
deleted file mode 100644
index b8d46fb..0000000
--- a/include/err.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * err.h
- * 
- * error status codes
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef ERR_H
-#define ERR_H
-
-#include "config.h"             /* check for ERR_REPORTING_SYSLOG */
-
-#ifdef ERR_REPORTING_FILE
-#include <stdio.h>
-#endif
-
-#include <stdarg.h>
-
-/**
- * @defgroup Error Error Codes
- * 
- * Error status codes are represented by the enumeration 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_t;
-
-/**
- * @}
- */
-
-#if (ERR_REPORTING_SYSLOG) 
-
-#include <syslog.h>
-
-typedef enum {
-  err_level_emergency = LOG_EMERG,
-  err_level_alert     = LOG_ALERT,  
-  err_level_critical  = LOG_CRIT,  
-  err_level_error     = LOG_ERR,  
-  err_level_warning   = LOG_WARNING,
-  err_level_notice    = LOG_NOTICE,  
-  err_level_info      = LOG_INFO,  
-  err_level_debug     = LOG_DEBUG,  
-  err_level_none
-} err_reporting_level_t;
-
-#else
-
-typedef enum {
-  err_level_emergency, 
-  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;
-
-#endif
-
-/*
- * 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);
-  
-/*
- * 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.
- *
- */
-
-void
-err_report(int priority, char *format, ...);
-
-
-/*
- * debug_module_t defines a debug module 
- */
-
-typedef struct { 
-  unsigned int   on;          /* 1 if debugging is on, 0 if it is off */
-  unsigned char *name;        /* printable name for debug module      */
-} debug_module_t;
-
-#if ENABLE_DEBUGGING 
-
-#define debug_on(mod)  (mod).on = 1
-
-#define debug_off(mod) (mod).on = 0
-
-/* use err_report() to report debug message */
-#define debug_print(mod, format, arg)                  \
-  if (mod.on) err_report(err_level_debug, ("%s: " format), mod.name, arg)
-
-#else
-
-/* define macros to do nothing */
-#define debug_print(mod, format, arg) 
-
-#define debug_on(mod)  
-
-#define debug_off(mod) 
-
-#endif
-
-#endif /* ERR_H */
diff --git a/include/getopt_s.h b/include/getopt_s.h
new file mode 100644
index 0000000..53fb25b
--- /dev/null
+++ b/include/getopt_s.h
@@ -0,0 +1,67 @@
+/*
+ * 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-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 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);
+
+extern char *optarg_s; /* defined in getopt.c */
+
+extern int optind_s; /* defined in getopt.c */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GETOPT_S_H */
diff --git a/include/rdb.h b/include/rdb.h
deleted file mode 100644
index 5a26c5e..0000000
--- a/include/rdb.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * replay-database.h
- *
- * interface for a replay database for packet security
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-
-#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 */
-
-/*
- * 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;
-
-#define rdb_bits_in_bitmask (8*sizeof(v128_t))   
-
-/*
- * rdb init
- *
- * initalizes rdb
- *
- * returns err_status_ok on success, err_status_t_fail otherwise
- */
-
-err_status_t
-rdb_init(rdb_t *rdb);
-
-
-/*
- * 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
- */
-
-err_status_t
-rdb_check(const rdb_t *rdb, uint32_t index);  
-
-/*
- * rdb_add_index
- *
- * adds index to rdb_t (and does *not* check if index appears in db)
- *
- * returns err_status_ok on success, err_status_fail otherwise
- *
- */
-
-err_status_t
-rdb_add_index(rdb_t *rdb, uint32_t 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 
- * not too high
- *
- * return values:
- * 
- *    err_status_ok            no problem
- *    err_status_key_expired   sequence number too high
- *
- */
-err_status_t
-rdb_increment(rdb_t *rdb);
-
-/*
- * rdb_get_value(db) returns the current sequence number of db
- */
-
-uint32_t
-rdb_get_value(const rdb_t *rdb);
-
-
-#endif /* REPLAY_DB_H */ 
diff --git a/include/rdbx.h b/include/rdbx.h
deleted file mode 100644
index bf0b655..0000000
--- a/include/rdbx.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * rdbx.h
- *
- * replay database with extended packet indices, using a rollover counter
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- *
- */
-
-#ifndef RDBX_H
-#define RDBX_H
-
-#include "datatypes.h"
-#include "err.h"
-
-/* #define ROC_TEST */  
-
-#ifndef ROC_TEST
-
-typedef unsigned short int sequence_number_t;   /* 16 bit sequence number  */
-typedef unsigned long int rollover_counter_t;   /* 32 bit rollover counter */
-
-#else  /* use small seq_num and roc datatypes for testing purposes */
-
-typedef unsigned char sequence_number_t;         /* 8 bit sequence number   */
-typedef unsigned short int 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)))
-
-/*
- * An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'
- * sequence number.  
- */
-
-typedef uint64_t xtd_seq_num_t;
-
-
-/*
- * An 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;
-  v128_t bitmask;
-} rdbx_t;
-
-
-/*
- * rdbx_init(rdbx_ptr)
- *
- * initializes the rdbx pointed to by its argument, setting the
- * rollover counter and sequence number to zero
- */
-
-err_status_t
-rdbx_init(rdbx_t *rdbx);
-
-
-/*
- * 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
- */
-
-inline int
-rdbx_estimate_index(const rdbx_t *rdbx,
-		    xtd_seq_num_t *guess,
-		    sequence_number_t s);
-
-/*
- * rdbx_check(rdbx, delta);
- *
- * rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
- * which is at rdbx->window_start + delta is in the rdb
- *
- */
-
-inline err_status_t
-rdbx_check(const rdbx_t *rdbx, int difference);
-
-/*
- * replay_add_index(rdbx, delta)
- * 
- * adds the 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.
- */
-
-inline err_status_t
-rdbx_add_index(rdbx_t *rdbx, int delta);
-
-/*
- * 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!
- */
-
-
-/* index_init(&pi) initializes a packet index pi (sets it to zero) */
-
-void
-index_init(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);
-
-
-/*
- * index_guess(local, guess, s)
- * 
- * given a 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
- */
-
-int
-index_guess(const xtd_seq_num_t *local,
-		   xtd_seq_num_t *guess,
-		   sequence_number_t s);
-
-
-#endif /* RDBX_H */
-
-
-
-
-
-
-
-
-
diff --git a/include/rtp.h b/include/rtp.h
deleted file mode 100644
index 78ed3d6..0000000
--- a/include/rtp.h
+++ /dev/null
@@ -1,119 +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-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef RTP_H
-#define RTP_H
-
-#include "srtp.h"    
-
-#define rtp_header_len 12
-
-typedef srtp_hdr_t rtp_hdr_t;
-
-#define RTP_MAX_BUF_LEN 16384
-
-typedef struct {
-  srtp_hdr_t header;        
-  char body[RTP_MAX_BUF_LEN];  
-} rtp_msg_t;
-
-typedef struct {
-  rtp_msg_t message;         
-  int socket;
-  srtp_ctx_t *srtp_ctx;
-  struct sockaddr_in addr;   /* reciever's address */
-} rtp_sender_t;
-
-typedef struct {
-  rtp_msg_t message;
-  int socket;
-  srtp_ctx_t *srtp_ctx;
-  struct sockaddr_in addr;   /* receiver's address */
-} rtp_receiver_t;
-
-
-ssize_t
-rtp_sendto(rtp_sender_t *sender, const void* msg, int len);
-
-ssize_t
-rtp_recvfrom(rtp_receiver_t *receiver, void *msg, int *len);
-
-int
-rtp_receiver_init(rtp_receiver_t *rcvr, int socket, 
-		  struct sockaddr_in addr, uint32_t ssrc);
-
-int
-rtp_sender_init(rtp_sender_t *sender, int socket, 
-		struct sockaddr_in addr, uint32_t 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  */
-		   );
-
-
-#endif /* RTP_H */
diff --git a/include/srtp.h b/include/srtp.h
index 2ccb553..c86b9ee 100644
--- a/include/srtp.h
+++ b/include/srtp.h
@@ -7,26 +7,26 @@
  * 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
@@ -42,14 +42,14 @@
  *
  */
 
+#ifndef SRTP_SRTP_H
+#define SRTP_SRTP_H
 
-#ifndef SRTP_H
-#define SRTP_H
+#include <stdint.h>
 
-#include "crypto_kernel.h"
-#include "rdbx.h"
-#include "rdb.h"
-#include "integers.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /**
  * @defgroup SRTP Secure RTP
@@ -69,106 +69,231 @@
 /*
  * 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 
-
-/* 
- * 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_MAX_TRAILER_LEN (SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN)
 
 /**
- * @brief sec_serv_t describes a set of security services. 
+ * SRTP_MAX_NUM_MASTER_KEYS is the maximum number of Master keys for
+ * MKI supported by libSRTP.
  *
- * 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).  
  */
+#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)
+
+#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 srtp_err_status_t defines error codes.
+ *
+ * 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 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
- * @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 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;
 
 /**
- * @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 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())             */
+} srtp_ssrc_type_t;
+
+/**
+ * @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 {
+    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;
 
-typedef struct { 
-  ssrc_type_t type;   /**< The type of this particular SSRC */
-  uint32_t value;     /**< The value of this SSRC, if it is not a wildcard */
-} ssrc_t;
+/**
+ * @brief points to an EKT policy
+ */
+typedef struct srtp_ekt_policy_ctx_t *srtp_ekt_policy_t;
 
+/**
+ * @brief points to EKT stream data
+ */
+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
@@ -177,7 +302,7 @@
  * 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
@@ -188,33 +313,44 @@
  * 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.                 */
-  octet_t *key;                /**< Pointer to the SRTP master key for
-				*    this stream.                        */
-  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
@@ -222,47 +358,34 @@
  * 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.
  */
+srtp_err_status_t srtp_init(void);
 
-err_status_t
-srtp_init();
+/**
+ * @brief srtp_shutdown() de-initializes the srtp library.
+ *
+ * @warning No srtp functions may be called after calling this function.
+ */
+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.
@@ -272,6 +395,11 @@
  * 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
@@ -279,18 +407,70 @@
  *
  * @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 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
+ * @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);
 
-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 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 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 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);
+
 /**
  * @brief srtp_unprotect() is the Secure RTP receiver-side packet
  * processing function.
@@ -298,93 +478,134 @@
  * 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.  The final element of the list @b must have its `next'
- * field set to zero.
- * 
+ * 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.
@@ -392,70 +613,544 @@
  * @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.
  *
  */
-
-err_status_t
-srtp_remove_stream(srtp_t session, uint32_t ssrc);
+srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc);
 
 /**
- * @brief crypto_policy_set_rtp_default() sets a crypto policy
+ * @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 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 strucutre to be set to the
- * default policy.
- * 
- * The function call crypto_policy_set_rtp_default(&p) sets the
- * crypto_policy_t at location p to the SRTP default policy for RTP
+ * @param p is a pointer to the policy structure to be set
+ *
+ * The function call srtp_crypto_policy_set_rtp_default(&p) sets the
+ * srtp_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.
- * 
+ * elements in the srtp_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 strucutre to be set to the
- * default policy.
- * 
- * 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 srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p);
 
-void
-crypto_policy_set_rtcp_default(crypto_policy_t *p);
+/**
+ * @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 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 srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(p)                      \
+    srtp_crypto_policy_set_rtp_default(p)
+
+/**
+ * @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 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 srtp_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 srtp_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 srtp_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 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_192_hmac_sha1_32(srtp_crypto_policy_t *p);
+
+/**
+ * @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 srtp_crypto_policy_set_aes_cm_192_null_auth(&p) sets
+ * the srtp_crypto_policy_t at location p to use the SRTP default cipher
+ * (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 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_192_null_auth(srtp_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 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.
+ *
+ * @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 srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p);
+
+/**
+ * @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
+ *
+ * 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 srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p);
+
+/**
+ * @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
+ *
+ * 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 srtp_crypto_policy_t datatype.
+ *
+ * @return void.
+ *
+ */
+void srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_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
@@ -464,71 +1159,116 @@
  * @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.
  */
+srtp_err_status_t srtp_dealloc(srtp_t s);
 
-err_status_t
-srtp_dealloc(srtp_t s);
+/*
+ * @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 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_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 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 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 srtp_crypto_policy_t datatype.
+ *
+ * @return values
+ *     - srtp_err_status_ok         no problems were encountered
+ *     - srtp_err_status_bad_param  the profile is not supported
+ *
+ */
+srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp(
+    srtp_crypto_policy_t *policy,
+    srtp_profile_t profile);
 
+/**
+ * @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 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 srtp_crypto_policy_t datatype.
+ *
+ * @return values
+ *     - srtp_err_status_ok         no problems were encountered
+ *     - srtp_err_status_bad_param  the profile is not supported
+ *
+ */
+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);
+
+/**
+ * @brief returns the master salt length for a given SRTP profile
+ */
+unsigned int srtp_profile_get_master_salt_length(srtp_profile_t profile);
+
+/**
+ * @brief appends the salt to the key
+ *
+ * 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.
+ *
+ * @warning There must be at least bytes_in_salt + bytes_in_key bytes
+ *          available at the location pointed to by key.
+ *
+ */
+void srtp_append_salt_to_key(unsigned char *key,
+                             unsigned int bytes_in_key,
+                             unsigned char *salt,
+                             unsigned int bytes_in_salt);
 
 /**
  * @}
  */
 
-
-
-
-
-/*
- * 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;
-  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;
-
-
-
 /**
  * @defgroup SRTCP Secure RTCP
- * @ingroup  SRTP 
+ * @ingroup  SRTP
  *
  * @brief Secure RTCP functions are used to protect RTCP traffic.
  *
@@ -536,31 +1276,36 @@
  * 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
@@ -568,19 +1313,69 @@
  *
  * @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
@@ -589,11 +1384,11 @@
  * 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.
  *
@@ -602,27 +1397,122 @@
  *
  * @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 
+ * @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.
- *    - err_status_replay_fail if the SRTCP packet is a replay (e.g. has
+ *    - 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);
 
-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 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.
+ *
+ * @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);
+
+/**
+ * @}
+ */
+
+/**
+ * @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);
 
 /**
  * @}
@@ -632,10 +1522,10 @@
  * @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
@@ -656,47 +1546,41 @@
  * @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;
 
 /**
@@ -709,12 +1593,11 @@
  * 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
@@ -724,134 +1607,153 @@
  *             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);
 
 /**
  * @}
  */
 
-/*
- * 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 
- * 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);                    \
-}   
-
-/*
- * an srtp_hdr_t represents the srtp header
- *
- * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
- * 
- * (note that this definition follows that of RFC 1889 Appendix A, but
- * is not identical)
- */
- 
-#if (WORDS_BIGENDIAN == 0) /* assume LITTLE_ENDIAN */
-
-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 */
-} 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 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 */
-} srtp_hdr_xtnd_t;
-
-
-/*
- * srtcp_hdr_t represents a secure rtcp header 
- *
- * in this implementation, an srtcp header is assumed to be 32-bit
- * alinged
- */
-
-#if (WORDS_BIGENDIAN == 0) /* assume LITTLE_ENDIAN */
-
-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 */
-} srtcp_hdr_t;
-
-typedef struct {
-  unsigned int index:31;    /* srtcp packet index in network order! */
-  unsigned int e:1;         /* encrypted? 1=yes */
-  /* optional mikey/etc go here */
-  /* and then the variable-length auth tag */
-} srtcp_trailer_t;
-
-
-#else /*  BIG_ENDIAN */
-
-typedef struct {
-  unsigned 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 */
-} srtcp_trailer_t;
-
-#endif
-
 /* 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
 
-#endif /* SRTP_H */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_SRTP_H */
diff --git a/include/srtp_priv.h b/include/srtp_priv.h
new file mode 100644
index 0000000..988efc4
--- /dev/null
+++ b/include/srtp_priv.h
@@ -0,0 +1,280 @@
+/*
+ * srtp_priv.h
+ *
+ * private internal data structures and functions 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.
+ *
+ */
+
+#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);
+
+/*
+ * 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
+ *
+ * note that the keys might not actually be unique, in which case the
+ * srtp_cipher_t and srtp_auth_t pointers will point to the same structures
+ */
+typedef struct srtp_stream_ctx_t_ {
+    uint32_t ssrc;
+    srtp_session_keys_t *session_keys;
+    unsigned int num_master_keys;
+    srtp_rdbx_t rtp_rdbx;
+    srtp_sec_serv_t rtp_services;
+    srtp_rdb_t rtcp_rdb;
+    srtp_sec_serv_t rtcp_services;
+    direction_t direction;
+    int allow_repeat_tx;
+    srtp_ekt_stream_t ekt;
+    int *enc_xtn_hdr;
+    int enc_xtn_hdr_count;
+    uint32_t pending_roc;
+    struct srtp_stream_ctx_t_ *next; /* linked list of streams */
+} 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
+ * "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 */
+} 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 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 */
+} srtp_hdr_xtnd_t;
+
+/*
+ * srtcp_hdr_t represents a secure rtcp header
+ *
+ * in this implementation, an srtcp header is assumed to be 32-bit
+ * alinged
+ */
+
+#ifndef WORDS_BIGENDIAN
+
+typedef struct {
+    unsigned 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 */
+} 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 */
+} srtcp_hdr_t;
+
+typedef struct {
+    unsigned int e : 1;      /* encrypted? 1=yes                      */
+    unsigned int index : 31; /* srtcp packet index                    */
+                             /* optional mikey/etc go here            */
+                             /* and then the variable-length auth tag */
+} srtcp_trailer_t;
+
+#endif
+
+/*
+ * 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
+ * an internal-only function.
+ */
+
+#define srtp_handle_event(srtp, strm, evnt)                                    \
+    if (srtp_event_handler) {                                                  \
+        srtp_event_data_t data;                                                \
+        data.session = srtp;                                                   \
+        data.ssrc = ntohl(strm->ssrc);                                         \
+        data.event = evnt;                                                     \
+        srtp_event_handler(&data);                                             \
+    }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SRTP_PRIV_H */
diff --git a/include/srtp_ust.h b/include/srtp_ust.h
deleted file mode 100644
index fc92183..0000000
--- a/include/srtp_ust.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * srtp.h
- *
- * interface to libsrtp
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef SRTP_H
-#define SRTP_H
-
-#include "crypto_kernel.h"
-#include "rdbx.h"
-#include "integers.h"
-
-/* a sec_serv_t describes a set of security services */
-
-typedef enum {
-  sec_serv_none          = 0,
-  sec_serv_conf          = 1,
-  sec_serv_auth          = 2,
-  sec_serv_conf_and_auth = 3
-} sec_serv_t;
-
-/* srtp_ctx_t stores all of the state needed for an srtp session */
-
-#include "ust.h"
-
-typedef struct {
-  ust_ctx_t  ust;
-  sec_serv_t services;
-  uint32_t   ssrc;
-} srtp_ctx_t;
-
-
-/*
- * an srtp_hdr_t represents the srtp header
- *
- * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
- * 
- * (note that this definition follows that of RFC 1889 Appendix A, but
- * is not identical)
- */
-
-#if (WORDS_BIGENDIAN == 0) /* assume LITTLE_ENDIAN */
-
-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 */
-} 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 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 */
-} srtp_hdr_xtnd_t;
-
-
-
-/*
- * an srtp_t is a pointer to an srtp_ctx_t - we define this to 
- * improve encapsualtion
- *
- */
-
-typedef srtp_ctx_t *srtp_t;
-
-
-/*
- * srtp_protect(ctx, pkt, len) applies secure rtp protection to the
- * packet pkt (which has length *len) using the srtp context ctx.  this
- * is the srtp sender-side packet processing function.
- * 
- *    nota bene: this function assumes that it can write the auth tag
- *    to the end of the packet
- *
- * ctx is a pointer to the srtp_ctx_t which applies to
- * the particular packet
- *
- * pkt is a pointer to the rtp packet (before the call); after
- * the function returns, it points to the srtp packet
- *
- * 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
- *
- * return values:
- *
- *    err_status_ok            no problems
- *    err_status_replay_fail   rtp sequence number was non-increasing
- *    <other>                  failure in cryptographic mechanisms
- */
-
-err_status_t
-srtp_protect(srtp_t ctx, srtp_hdr_t *pkt, int *pkt_octet_len);
-	     
-/*
- * srtp_unprotect(ctx, pkt, len) applies secure rtp protection to the
- * srtp packet pointed to by pkt (which has length *len), using the
- * srtp contet pointed to by ctx.  this is the secure rtp receiver-side
- * packet processing function.
- *
- * ctx is a pointer to the srtp_ctx_t which applies to
- * the particular packet
- *
- * pkt is a pointer to 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 the data to which it points is
- * undefined.
- *
- * pkt_octet_len 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.
- * otherwise, the value of the data to which it points is undefined.
- *
- * return values:
- * 
- *    err_status_ok           the rtp packet is valid
- *    err_status_auth_fail    the srtp packet failed message authentication
- *    err_status_replay_fail  the srtp packet is a replay (this packet has
- *                            already been processed)
- *    <other>                 failure in cryptographic mechanisms
- * 
- * if err_status_ok is returned, then pkt points to the RTP packet
- * and pkt_octet_len is the number of octets in that packet;  otherwise,
- * no assumptions should be made about either data elements.
- */
-
-err_status_t
-srtp_unprotect(srtp_t ctx, srtp_hdr_t *pkt, int *pkt_octet_len);
-
-/*
- * srtp_alloc(ctx, ...) allocates a secure rtp context (srtp_ctx_t) and 
- * sets ctx to point to that value..  the other arguments are the parameter
- * values for the srtp context; see the comments in the declaration.
- * 
- * after an srtp_ctx_t is allocated, it must be initialized by calling
- * the srtp_init_aes_128_prf(...) function (see below).  an
- * alternative but unrecommended method is to initialize the cipher_t
- * and auth_t using the cipher and auth apis.
- *
- * return values:
- * 
- *   err_status_ok            no problems
- *   err_status_alloc_fail    a memory allocation failure occured
- */
-
-err_status_t
-srtp_alloc(srtp_t *ctx,                /* srtp context                */
-	   cipher_type_id_t c_id,      /* cipher type                 */
-	   int cipher_key_len,         /* cipher key length in octets */
-	   auth_type_id_t a_id,        /* authentication func type    */
-	   int auth_key_len,           /* auth key length in octets   */
-	   int auth_tag_len,           /* auth tag length in octets   */
-	   sec_serv_t sec_serv         /* security services flag      */
-	   ); 
-
-
-/*
- * srtp_dealloc(ctx) deallocates storage for an srtp_ctx_t.  this
- * function should be called exactly once to deallocate the storage
- * allocated by the function call srtp_alloc(ctx).
- *
- * return values:
- *
- *    err_status_ok             no problems
- *    err_status_dealloc_fail   a memory deallocation failure occured
- */
-
-err_status_t
-srtp_dealloc(srtp_t ctx);
-
-/*
- * srtp_init_aes_128_prf(ctx, key, salt) initializes an srtp_ctx_t
- * with a given master key and master salt.
- * 
- * the key MUST be sixteen octets long
- * 
- * the salt MUST be fourteen octets long
- *
- * The PRF used for key derivation here is that defined in the secure
- * rtp specification, though in theory other PRFs can be used.  The
- * cipher is hardwired to AES-128 Counter Mode with 112 bits of salt.
- *
- */
-
-err_status_t
-srtp_init_aes_128_prf(srtp_t srtp, const octet_t key[16]);
-
-
-
-/*
- * 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_ctx_t (i.e. between initializations).
- */
-
-int
-srtp_get_trailer_length(const srtp_t a);
-
-
-/*
- * functions below are internal to libsrtp, and are not part of the
- * documented external api - caveat emptor!
- */
-
-/* for debugging only - srtp_print_packet dumps lots of info to stdout */
-
-void
-srtp_print_packet(srtp_hdr_t *hdr, int pkt_octet_len);
-
-
-/*
- * srtp_set_rollover_counter(ctx, r)
- *
- * sets the rollover_counter in ctx to r.  fails and returns
- * err_status_err if r is less than the current rollover
- * counter value; otherwise, returns err_status_ok
- *
- * this function should *only* be called if trustworthy external
- * information is available, e.g. from RTCP
- *
- * future versions of this implementation may get rid of this function
- * and instead read the correct rollover counter value directly from
- * the rtcp packets immediately after they have been authenticated
- *
- */
-
-err_status_t
-srtp_set_rollover_counter(srtp_t ctx, rollover_counter_t r);
-
-
-#endif /* SRTP_H */
diff --git a/include/stat.h b/include/stat.h
deleted file mode 100644
index 6d5e4a4..0000000
--- a/include/stat.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * stats.h
- * 
- * interface to statistical test functions
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright(c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef STAT_H
-#define STAT_H
-
-#include "datatypes.h"       /* for octet_t                       */
-#include "err.h"             /* for err_status_t                  */
-#include "rand_source.h"     /* for rand_source_func_t definition */
-
-err_status_t
-stat_test_monobit(octet_t *data);
-
-err_status_t
-stat_test_poker(octet_t *data);
-
-err_status_t
-stat_test_runs(octet_t *data);
-
-err_status_t
-stat_test_rand_source(rand_source_func_t rs);
-
-#endif /* STAT_H */
diff --git a/include/ut_sim.h b/include/ut_sim.h
index 40dc4e2..e678b5f 100644
--- a/include/ut_sim.h
+++ b/include/ut_sim.h
@@ -9,26 +9,26 @@
  */
 
 /*
- *	
- * 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
@@ -44,38 +44,40 @@
  *
  */
 
-
-
 #ifndef UT_SIM_H
 #define UT_SIM_H
 
-#include "integers.h"  /* for uint32_t */
-#include <stdlib.h>   /* for random() */
+#include "integers.h" /* for uint32_t */
 
-#define UT_BUF 4      /* 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 */
diff --git a/install-sh b/install-sh
index e9de238..0b0fdcb 100755
--- a/install-sh
+++ b/install-sh
@@ -1,251 +1,501 @@
 #!/bin/sh
-#
 # install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
 #
-# Copyright 1991 by the Massachusetts Institute of Technology
+# Copyright (C) 1994 X Consortium
 #
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
+# 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
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
 # when there is no Makefile.
 #
 # This script is compatible with the BSD install script, but was written
-# from scratch.  It can only install one file at a time, a restriction
-# shared with many OS's install programs.
+# from scratch.
 
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-	-c) instcmd="$cpprog"
-	    shift
-	    continue;;
-
-	-d) dir_arg=true
-	    shift
-	    continue;;
-
-	-m) chmodcmd="$chmodprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-o) chowncmd="$chownprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-g) chgrpcmd="$chgrpprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-s) stripcmd="$stripprog"
-	    shift
-	    continue;;
-
-	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
-	    shift
-	    continue;;
-
-	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-	    shift
-	    continue;;
-
-	*)  if [ x"$src" = x ]
-	    then
-		src=$1
-	    else
-		# this colon is to work around a 386BSD /bin/sh bug
-		:
-		dst=$1
-	    fi
-	    shift
-	    continue;;
-    esac
-done
-
-if [ x"$src" = x ]
-then
-	echo "install:	no input file specified"
-	exit 1
-else
-	true
-fi
-
-if [ x"$dir_arg" != x ]; then
-	dst=$src
-	src=""
-	
-	if [ -d $dst ]; then
-		instcmd=:
-		chmodcmd=""
-	else
-		instcmd=mkdir
-	fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-	if [ -f $src -o -d $src ]
-	then
-		true
-	else
-		echo "install:  $src does not exist"
-		exit 1
-	fi
-	
-	if [ x"$dst" = x ]
-	then
-		echo "install:	no destination specified"
-		exit 1
-	else
-		true
-	fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-	if [ -d $dst ]
-	then
-		dst="$dst"/`basename $src`
-	else
-		true
-	fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='	
+tab='	'
+nl='
 '
-IFS="${IFS-${defaultIFS}}"
+IFS=" $tab$nl"
 
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
+# Set DOITPROG to "echo" to test this script.
 
-pathcomp=''
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
 
-while [ $# -ne 0 ] ; do
-	pathcomp="${pathcomp}${1}"
-	shift
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
 
-	if [ ! -d "${pathcomp}" ] ;
-        then
-		$mkdirprog "${pathcomp}"
-	else
-		true
-	fi
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
 
-	pathcomp="${pathcomp}/"
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
+
+    -o) chowncmd="$chownprog $2"
+        shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
+
+    -T) is_target_a_directory=never;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --) shift
+        break;;
+
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
+
+    *)  break;;
+  esac
+  shift
 done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
 fi
 
-if [ x"$dir_arg" != x ]
-then
-	$doit $instcmd $dst &&
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
 
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
 
-# If we're going to rename the final executable, determine the name now.
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
 
-	if [ x"$transformarg" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		dstfile=`basename $dst $transformbasename | 
-			sed $transformarg`$transformbasename
-	fi
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
 
-# don't allow the sed command to completely eliminate the filename
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
 
-	if [ x"$dstfile" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		true
-	fi
+    *[0-7])
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
 
-# Make a temp file name in the proper directory.
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
 
-	dsttmp=$dstdir/#inst.$$#
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
 
-# Move or copy the file name to the temp name
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
 
-	$doit $instcmd $src $dsttmp &&
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
 
-	trap "rm -f ${dsttmp}" 0 &&
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      dstdir=`dirname "$dst"`
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
 
-# and set any options; do chmod last to preserve setuid bits
+  obsolete_mkdir_used=false
 
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+        # Create intermediate dirs using mode 755 as modified by the umask.
+        # This is like FreeBSD 'install' as of 1997-10-28.
+        umask=`umask`
+        case $stripcmd.$umask in
+          # Optimize common cases.
+          *[2367][2367]) mkdir_umask=$umask;;
+          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
 
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+          *[0-7])
+            mkdir_umask=`expr $umask + 22 \
+              - $umask % 100 % 40 + $umask % 20 \
+              - $umask % 10 % 4 + $umask % 2
+            `;;
+          *) mkdir_umask=$umask,go-w;;
+        esac
 
-# Now rename the file to the real destination.
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
 
-	$doit $rmcmd -f $dstdir/$dstfile &&
-	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+        posix_mkdir=false
+        case $umask in
+          *[123567][0-7][0-7])
+            # POSIX mkdir -p sets u+wx bits regardless of umask, which
+            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+            ;;
+          *)
+            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
 
-fi &&
+            if (umask $mkdir_umask &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+            then
+              if test -z "$dir_arg" || {
+                   # Check for POSIX incompatibilities with -m.
+                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                   # other-writable bit of parent directory when it shouldn't.
+                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                   case $ls_ld_tmpdir in
+                     d????-?r-*) different_mode=700;;
+                     d????-?--*) different_mode=755;;
+                     *) false;;
+                   esac &&
+                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                   }
+                 }
+              then posix_mkdir=:
+              fi
+              rmdir "$tmpdir/d" "$tmpdir"
+            else
+              # Remove any dirs left behind by ancient mkdir implementations.
+              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+            fi
+            trap '' 0;;
+        esac;;
+    esac
 
+    if
+      $posix_mkdir && (
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
 
-exit 0
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      set -f
+      set fnord $dstdir
+      shift
+      set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask=$mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/install-win.bat b/install-win.bat
new file mode 100644
index 0000000..a4fc0eb
--- /dev/null
+++ b/install-win.bat
@@ -0,0 +1,35 @@
+:: Installs from srtp windows build directory to directory specified on
+:: command line
+
+
+@if "%1"=="" (
+	echo "Usage: %~nx0 destdir"
+	exit /b 1
+) else (
+	set destdir=%1
+)
+
+@if not exist %destdir% (
+   echo %destdir% not found
+   exit /b 1
+)
+
+@for %%d in (include\srtp.h crypto\include\cipher.h Debug\srtp2.lib Release\srtp2.lib x64\Debug\srtp2.lib x64\Release\srtp2.lib) do (
+	if not exist "%%d" (
+	   echo "%%d not found: are you in the right directory?"
+	   exit /b 1
+	)
+)
+
+mkdir %destdir%\include
+mkdir %destdir%\include\srtp2
+mkdir %destdir%\lib
+mkdir %destdir%\lib\x64
+
+@for %%d in (include\srtp.h include\ekt.h crypto\include\cipher.h crypto\include\auth.h crypto\include\crypto_types.h) do (
+	 copy %%d %destdir%\include\srtp2
+)
+copy Release\srtp2.lib %destdir%\lib\srtp2.lib
+copy Debug\srtp2.lib %destdir%\lib\srtp2d.lib
+copy x64\Release\srtp2.lib %destdir%\lib\x64\srtp2.lib
+copy x64\Debug\srtp2.lib %destdir%\lib\x64\srtp2d.lib
diff --git a/libsrtp2.pc.in b/libsrtp2.pc.in
new file mode 100644
index 0000000..fcb8652
--- /dev/null
+++ b/libsrtp2.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Description: Library for SRTP (Secure Realtime Transport Protocol)
+
+Libs: -L${libdir} -lsrtp2 @LIBS@
+Cflags: -I${includedir}
diff --git a/srtp.def b/srtp.def
new file mode 100644
index 0000000..d418b14
--- /dev/null
+++ b/srtp.def
@@ -0,0 +1,75 @@
+EXPORTS
+srtp_init
+srtp_shutdown
+srtp_protect
+srtp_protect_mki
+srtp_unprotect
+srtp_unprotect_mki
+srtp_create
+srtp_add_stream
+srtp_remove_stream
+srtp_update
+srtp_update_stream
+srtp_get_stream
+srtp_crypto_policy_set_rtp_default
+srtp_crypto_policy_set_rtcp_default
+srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32
+srtp_crypto_policy_set_aes_cm_128_null_auth
+srtp_crypto_policy_set_null_cipher_hmac_sha1_80
+srtp_crypto_policy_set_null_cipher_hmac_null
+srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80
+srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32
+srtp_crypto_policy_set_aes_cm_256_null_auth
+srtp_crypto_policy_set_aes_gcm_128_8_auth
+srtp_crypto_policy_set_aes_gcm_256_8_auth
+srtp_crypto_policy_set_aes_gcm_128_8_only_auth
+srtp_crypto_policy_set_aes_gcm_256_8_only_auth
+srtp_crypto_policy_set_aes_gcm_128_16_auth
+srtp_crypto_policy_set_aes_gcm_256_16_auth
+srtp_dealloc
+srtp_crypto_policy_set_from_profile_for_rtp
+srtp_crypto_policy_set_from_profile_for_rtcp
+srtp_profile_get_master_key_length
+srtp_profile_get_master_salt_length
+srtp_append_salt_to_key
+srtp_get_protect_trailer_length
+srtp_get_protect_rtcp_trailer_length
+srtp_protect_rtcp
+srtp_protect_rtcp_mki
+srtp_unprotect_rtcp
+srtp_unprotect_rtcp_mki
+srtp_set_stream_roc
+srtp_set_user_data
+srtp_get_stream_roc
+srtp_get_user_data
+srtp_install_event_handler
+srtp_get_version_string
+srtp_get_version
+srtp_set_debug_module
+srtp_list_debug_modules
+srtp_install_log_handler
+srtp_err_report
+srtp_crypto_kernel_load_debug_module
+srtp_cipher_get_key_length
+srtp_cipher_type_self_test
+srtp_cipher_type_test
+srtp_cipher_bits_per_second
+srtp_cipher_type_alloc
+srtp_cipher_dealloc
+srtp_cipher_init
+srtp_cipher_set_iv
+srtp_cipher_output
+srtp_cipher_encrypt
+srtp_cipher_decrypt
+srtp_cipher_get_tag
+srtp_cipher_set_aad
+srtp_replace_cipher_type
+srtp_auth_get_key_length
+srtp_auth_get_tag_length
+srtp_auth_get_prefix_length
+srtp_auth_type_self_test
+srtp_auth_type_test
+srtp_replace_auth_type
+srtp_octet_string_hex_string
+srtp_octet_string_is_eq
+srtp_rdbx_get_window_size
diff --git a/srtp.sln b/srtp.sln
new file mode 100644
index 0000000..23dd6d3
--- /dev/null
+++ b/srtp.sln
@@ -0,0 +1,40 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 14 for Windows Desktop
+VisualStudioVersion = 14.0.25123.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtp2", "srtp2.vcxproj", "{EEF031CB-FED8-451E-A471-91EC8D4F6750}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug Dll|Win32 = Debug Dll|Win32
+		Debug Dll|x64 = Debug Dll|x64
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release Dll|Win32 = Release Dll|Win32
+		Release Dll|x64 = Release Dll|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|Win32.ActiveCfg = Debug Dll|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|Win32.Build.0 = Debug Dll|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|x64.ActiveCfg = Debug Dll|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug Dll|x64.Build.0 = Debug Dll|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|Win32.Build.0 = Debug|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|x64.ActiveCfg = Debug|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Debug|x64.Build.0 = Debug|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|Win32.ActiveCfg = Release Dll|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|Win32.Build.0 = Release Dll|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|x64.ActiveCfg = Release Dll|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release Dll|x64.Build.0 = Release Dll|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.ActiveCfg = Release|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|Win32.Build.0 = Release|Win32
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|x64.ActiveCfg = Release|x64
+		{EEF031CB-FED8-451E-A471-91EC8D4F6750}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/srtp/ekt.c b/srtp/ekt.c
new file mode 100644
index 0000000..f09dc58
--- /dev/null
+++ b/srtp/ekt.c
@@ -0,0 +1,281 @@
+/*
+ * ekt.c
+ *
+ * Encrypted Key Transport for SRTP
+ *
+ * David McGrew
+ * Cisco Systems, Inc.
+ */
+/*
+ *
+ * Copyright (c) 2001-2017 Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ *   Neither the name of the Cisco Systems, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * 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 "ekt.h"
+
+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
+
+unsigned srtp_ekt_octets_after_base_tag(srtp_ekt_stream_t ekt)
+{
+    /*
+     * if the pointer ekt is NULL, then EKT is not in effect, so we
+     * indicate this by returning zero
+     */
+    if (!ekt)
+        return 0;
+
+    switch (ekt->data->ekt_cipher_type) {
+    case SRTP_EKT_CIPHER_AES_128_ECB:
+        return 16 + EKT_OCTETS_AFTER_EMK;
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+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 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);
+
+    return location;
+}
+
+srtp_err_status_t srtp_ekt_alloc(srtp_ekt_stream_t *stream_data,
+                                 srtp_ekt_policy_t policy)
+{
+    /*
+     * if the policy pointer is NULL, then EKT is not in use
+     * so we just set the EKT stream data pointer to NULL
+     */
+    if (!policy) {
+        *stream_data = NULL;
+        return srtp_err_status_ok;
+    }
+
+    /* TODO */
+    *stream_data = NULL;
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_ekt_stream_init_from_policy(
+    srtp_ekt_stream_t stream_data,
+    srtp_ekt_policy_t policy)
+{
+    if (!stream_data)
+        return srtp_err_status_ok;
+
+    return srtp_err_status_ok;
+}
+
+void aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len)
+{
+#ifndef GCM
+    // FIXME: need to get this working through the crypto module interface
+    srtp_aes_expanded_key_t expanded_key;
+
+    srtp_aes_expand_decryption_key(key, key_len, &expanded_key);
+    srtp_aes_decrypt(ciphertext, &expanded_key);
+#endif
+}
+
+/*
+ * The function srtp_stream_init_from_ekt() initializes a stream using
+ * the EKT data from an SRTCP trailer.
+ */
+
+srtp_err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream,
+                                            const void *srtcp_hdr,
+                                            unsigned pkt_octet_len)
+{
+    srtp_err_status_t err;
+    const uint8_t *master_key;
+    srtp_policy_t srtp_policy;
+    uint32_t roc;
+
+    /*
+     * 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;
+
+    /* decrypt the Encrypted Master Key field */
+    master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
+    /* FIX!? This decrypts the master key in-place, and never uses it */
+    /* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
+     * to a function which expects a raw (unexpanded) key */
+    aes_decrypt_with_raw_key((void *)master_key,
+                             &stream->ekt->data->ekt_dec_key, 16);
+
+    /* set the SRTP ROC */
+    roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
+    err = srtp_rdbx_set_roc(&stream->rtp_rdbx, roc);
+    if (err)
+        return err;
+
+    err = srtp_stream_init(stream, &srtp_policy);
+    if (err)
+        return err;
+
+    return srtp_err_status_ok;
+}
+
+void srtp_ekt_write_data(srtp_ekt_stream_t ekt,
+                         uint8_t *base_tag,
+                         unsigned base_tag_len,
+                         int *packet_len,
+                         srtp_xtd_seq_num_t pkt_index)
+{
+    uint32_t roc;
+    uint16_t isn;
+    unsigned emk_len;
+    uint8_t *packet;
+
+    /* 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;
+
+    /* copy encrypted master key into packet */
+    emk_len = srtp_ekt_octets_after_base_tag(ekt);
+    memcpy(packet, ekt->encrypted_master_key, emk_len);
+    debug_print(mod_srtp, "writing EKT EMK: %s,",
+                srtp_octet_string_hex_string(packet, emk_len));
+    packet += emk_len;
+
+    /* copy ROC into packet */
+    roc = (uint32_t)(pkt_index >> 16);
+    *((uint32_t *)packet) = be32_to_cpu(roc);
+    debug_print(mod_srtp, "writing EKT ROC: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(roc)));
+    packet += sizeof(roc);
+
+    /* copy ISN into packet */
+    isn = (uint16_t)pkt_index;
+    *((uint16_t *)packet) = htons(isn);
+    debug_print(mod_srtp, "writing EKT ISN: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(isn)));
+    packet += sizeof(isn);
+
+    /* copy SPI into packet */
+    *((uint16_t *)packet) = htons(ekt->data->spi);
+    debug_print(mod_srtp, "writing EKT SPI: %s,",
+                srtp_octet_string_hex_string(packet, sizeof(ekt->data->spi)));
+
+    /* 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
+ */
+
+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 */
+}
diff --git a/srtp/srtp.c b/srtp/srtp.c
index 8b05f6f..bd33a4d 100644
--- a/srtp/srtp.c
+++ b/srtp/srtp.c
@@ -7,26 +7,26 @@
  * 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
@@ -42,1052 +42,2721 @@
  *
  */
 
+// Leave this as the top level import. Ensures the existence of defines
+#include "config.h"
 
-#include "srtp.h"
-#include "aes_icm.h"         /* aes_icm is used in the KDF  */
-#include "alloc.h"           /* for crypto_alloc()          */
-#include "limits.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() */
 
-extern cipher_type_t aes_icm;
-extern auth_type_t   tmmhv2;
+#ifdef GCM
+#include "aes_gcm.h" /* for AES GCM mode */
+#endif
+
+#ifdef OPENSSL_KDF
+#include <openssl/kdf.h>
+#include "aes_icm_ext.h"
+#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
+#define octets_in_rtp_extn_hdr 4
 
-/*
- * the following declarations are libSRTP internal functions 
- */
+static srtp_err_status_t srtp_validate_rtp_header(void *rtp_hdr,
+                                                  int *pkt_octet_len)
+{
+    srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr;
+    int rtp_header_len;
 
-/*
- * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
- * to ssrc, or NULL if no stream exists for that ssrc
- */
+    if (*pkt_octet_len < octets_in_rtp_header)
+        return srtp_err_status_bad_param;
 
-srtp_stream_t 
-srtp_get_stream(srtp_t srtp, uint32_t ssrc);
+    /* Check RTP header length */
+    rtp_header_len = octets_in_rtp_header + 4 * hdr->cc;
+    if (hdr->x == 1)
+        rtp_header_len += octets_in_rtp_extn_hdr;
 
-err_status_t
-srtp_session_alloc(srtp_t *ctx_ptr, const crypto_policy_t *p);
+    if (*pkt_octet_len < rtp_header_len)
+        return srtp_err_status_bad_param;
 
-
-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 = 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;
-  }  
-
-  return err_status_ok;
+    /* 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;
 }
 
-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);
-    if (status)
-      return status;
-  }
-
-  /* if the key usage limit strucutre is present, deallocate it */
-  if (stream->limit != NULL
-      && (session->stream_template == NULL || stream->next == NULL))
-    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;
-  }
-  
-  /* deallocate srtp stream context */
-  crypto_free(stream);
-
-  return 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;
+}
+
+srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream,
+                                      const 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
+     */
+    if (stream->session_keys) {
+        for (i = 0; i < stream->num_master_keys; i++) {
+            session_keys = &stream->session_keys[i];
+
+            if (stream_template &&
+                stream->num_master_keys == stream_template->num_master_keys) {
+                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 if (session_keys->rtp_cipher) {
+                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 if (session_keys->rtp_auth) {
+                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 if (session_keys->rtcp_cipher) {
+                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 if (session_keys->rtcp_auth) {
+                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 if (session_keys->limit) {
+                srtp_crypto_free(session_keys->limit);
+            }
+        }
+        srtp_crypto_free(stream->session_keys);
+    }
+
+    status = srtp_rdbx_dealloc(&stream->rtp_rdbx);
+    if (status)
+        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_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_dealloc(str, NULL);
+        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_dealloc(str, NULL);
+            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_dealloc(str, NULL);
+            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_dealloc(str, NULL);
+            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_dealloc(str, NULL);
+            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_dealloc(str, NULL);
+            return srtp_err_status_alloc_fail;
+        }
+    }
+
+    /* allocate ekt data associated with stream */
+    stat = srtp_ekt_alloc(&str->ekt, p->ekt);
+    if (stat) {
+        srtp_stream_dealloc(str, NULL);
+        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_dealloc(str, NULL);
+            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_dealloc(str, NULL);
+                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_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;
+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)", ssrc);
+    debug_print(mod_srtp, "cloning stream (SSRC: 0x%08x)", ntohl(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;  
+    /* 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;
 
-  /* 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;
+    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);
 
-  /* set key limit to point to that of the template */
-  status = key_limit_clone(stream_template->limit, &str->limit);
-  if (status) 
-    return status;
+    if (str->session_keys == NULL) {
+        srtp_stream_dealloc(*str_ptr, stream_template);
+        *str_ptr = NULL;
+        return srtp_err_status_alloc_fail;
+    }
 
-  /* initialize replay databases */
-  rdbx_init(&str->rtp_rdbx);
-  rdb_init(&str->rtcp_rdb);
-  
-  /* set ssrc to that provided */
-  str->ssrc = ssrc;
+    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 direction and security services */
-  str->direction     = stream_template->direction;
-  str->rtp_services  = stream_template->rtp_services;
-  str->rtcp_services = stream_template->rtcp_services;
+        /* 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;
 
-  /* defensive coding */
-  str->next = NULL;
+        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);
 
-  return err_status_ok;
+            if (session_keys->mki_id == NULL) {
+                srtp_stream_dealloc(*str_ptr, stream_template);
+                *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_dealloc(*str_ptr, stream_template);
+            *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_dealloc(*str_ptr, stream_template);
+        *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, k) initializes kdf with the key k
- * 
+ * 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 the kdf state
+ * 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 { 
-  aes_icm_ctx_t c;    /* cipher used for key derivation  */  
+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;
 
-err_status_t
-srtp_kdf_init(srtp_kdf_t *kdf, const octet_t key[30]) {
+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));
 
-  aes_icm_context_init(&kdf->c, key);
+    /* The NULL cipher has zero key length */
+    if (key_len == 0)
+        return srtp_err_status_ok;
 
-  return 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;
 }
 
-err_status_t
-srtp_kdf_generate(srtp_kdf_t *kdf, srtp_prf_label label,
-		  octet_t *key, int length) {
+static srtp_err_status_t srtp_kdf_generate(srtp_kdf_t *kdf,
+                                           srtp_prf_label label,
+                                           uint8_t *key,
+                                           unsigned int length)
+{
+    int ret;
 
-  v128_t nonce;
-  
-  /* set eigth octet of nonce to <label>, set the rest of it to zero */
-  v128_set_to_zero(&nonce);
-  nonce.octet[7] = label;
- 
-  aes_icm_set_iv(&kdf->c, &nonce);  
-  
-  /* generate keystream output */
-  aes_icm_output(&kdf->c, key, length);
+    /* The NULL cipher will not have an EVP */
+    if (!kdf->evp)
+        return srtp_err_status_ok;
+    octet_string_set_to_zero(key, length);
 
-  return err_status_ok;
+    /*
+     * 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;
 }
 
-err_status_t
-srtp_kdf_clear(srtp_kdf_t *kdf) {
-  
-  /* zeroize aes context */
-  octet_string_set_to_zero((octet_t *)kdf, sizeof(srtp_kdf_t));
+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 err_status_ok;  
+    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 {
+    srtp_cipher_t *cipher; /* cipher used for key derivation  */
+} srtp_kdf_t;
+
+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;
+    srtp_err_status_t stat;
+
+    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;
+    }
+
+    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;
+}
+
+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;
+}
+
+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
+ */
+
+/* Get the base key length corresponding to a given combined key+salt
+ * length for the given cipher.
+ * TODO: key and salt lengths should be separate fields in the policy.  */
+static inline int base_key_length(const srtp_cipher_type_t *cipher,
+                                  int key_length)
+{
+    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;
+    }
+}
+
+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 NULL;
+        }
+        return &stream->session_keys[mki_index];
+    }
+
+    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);
+        }
+    }
+
+    return mki_size;
+}
+
+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)
+{
+    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;
+}
+
+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.
+    */
+    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;
 }
 
 /*
- *  end of key derivation functions 
+ * srtp_event_reporter is an event handler function that merely
+ * reports the events that are reported by the callbacks
  */
 
-#define MAX_SRTP_KEY_LEN 256
-
-
-
-err_status_t
-srtp_stream_init(srtp_stream_ctx_t *srtp, 
-		  const srtp_policy_t *p) {
-   err_status_t stat;
-   srtp_kdf_t kdf;
-   octet_t tmp_key[MAX_SRTP_KEY_LEN];
-   octet_t *key = p->key;
-
-   debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", 
-	       p->ssrc.value);
-
-   /* initialize replay database */
-   rdbx_init(&srtp->rtp_rdbx);
-
-   /* initialize key limit to maximum value */
-#ifdef NO_64BIT_MATH
+void srtp_event_reporter(srtp_event_data_t *data)
 {
-	uint64_t temp;
-	temp = make64(UINT_MAX,UINT_MAX);
-	key_limit_set(srtp->limit, temp);
-}
-#else
-   key_limit_set(srtp->limit, 0xffffffffffffLL);
-#endif
+    srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ",
+                    data->ssrc);
 
-   /* 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->direction = dir_unknown;
-
-   /* initialize KDF state     */
-   srtp_kdf_init(&kdf, key);
-
-   /* generate encryption key  */
-   srtp_kdf_generate(&kdf, label_rtp_encryption, 
-		     tmp_key, cipher_get_key_length(srtp->rtp_cipher));
-   /* 
-    * if the cipher in the srtp context is aes_icm, then we need
-    * to generate the salt value
-    */
-   if (srtp->rtp_cipher->type == &aes_icm) {
-	   /* FIX!!! this is really the cipher key length; rest is salt */
-     int base_key_len = 16;
-     int salt_len = cipher_get_key_length(srtp->rtp_cipher) - base_key_len;
-
-     debug_print(mod_srtp, "found aes_icm, generating salt", NULL);
-
-     /* generate encryption salt, put after encryption key */
-     srtp_kdf_generate(&kdf, label_rtp_salt, 
-		       tmp_key + base_key_len, salt_len);
-   }
-   debug_print(mod_srtp, "cipher key: %s", 
-	       octet_string_hex_string(tmp_key, 
-		    cipher_get_key_length(srtp->rtp_cipher)));  
-
-   /* 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 */
-   srtp_kdf_generate(&kdf, label_rtp_msg_auth,
-		     tmp_key, auth_get_key_length(srtp->rtp_auth));
-   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 RTCP-specific structures   
-    */
-
-   /* initialize replay database */
-   rdb_init(&srtp->rtcp_rdb);
-
-   /* DAM - no RTCP key limit at present */
-
-   /* generate encryption key  */
-   srtp_kdf_generate(&kdf, label_rtcp_encryption, 
-		     tmp_key, cipher_get_key_length(srtp->rtcp_cipher));
-   /* 
-    * if the cipher in the srtp context is aes_icm, then we need
-    * to generate the salt value
-    */
-   if (srtp->rtcp_cipher->type == &aes_icm) {
-	   /* FIX!!! this is really the cipher key length; rest is salt */
-     int base_key_len = 16;
-     int salt_len = cipher_get_key_length(srtp->rtcp_cipher) - base_key_len;
-
-     debug_print(mod_srtp, "found aes_icm, generating rtcp salt", NULL);
-
-     /* generate encryption salt, put after encryption key */
-     srtp_kdf_generate(&kdf, label_rtcp_salt, 
-		       tmp_key + base_key_len, salt_len);
-   }
-   debug_print(mod_srtp, "rtcp cipher key: %s", 
-	       octet_string_hex_string(tmp_key, 
-		    cipher_get_key_length(srtp->rtcp_cipher)));  
-
-   /* 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 */
-   srtp_kdf_generate(&kdf, label_rtcp_msg_auth,
-		     tmp_key, auth_get_key_length(srtp->rtcp_auth));
-   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 */
-   srtp_kdf_clear(&kdf);
-   octet_string_set_to_zero(tmp_key, MAX_SRTP_KEY_LEN);
-   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 = 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 */
-   octet_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, 
-				  ntohl(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) 
-       enc_start += ((srtp_hdr_xtnd_t *)enc_start)->length;
-     enc_octet_len = *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 = (octet_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)
-     return status;  /* we've been asked to reuse an index */
-   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);
-#endif
-
-   /* 
-    * if we're using rindael counter mode, set nonce and seq 
-    */
-   if (stream->rtp_cipher->type == &aes_icm) {
-     v128_t iv;
-
-     iv.v32[0] = 0;
-     iv.v32[1] = hdr->ssrc;
-#ifdef NO_64BIT_MATH
-     iv.v64[1] = bswap_64(make64((high32(est) << 16) | (low32(est) >> 16),
-			  low32(est) << 16));
-#else
-     iv.v64[1] = bswap_64(est << 16);
-#endif
-     status = cipher_set_iv(stream->rtp_cipher, &iv);
-
-   } else {  
-     v128_t iv;
-
-     /* otherwise, set the index to est */  
-#ifdef NO_64BIT_MATH
-     iv.v32[0] = 0;
-     iv.v32[1] = 0;
-#else
-     iv.v64[0] = 0;
-#endif
-     iv.v64[1] = bswap_64(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 = bswap_64(make64((high32(est) << 16) |
-						 (low32(est) >> 16),
-						 lo32(est) << 16));
-#else
-   est = bswap_64(est << 16);
-#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));
+    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");
     }
-  }
+}
 
-  /* if we're encrypting, exor keystream into the message */
-  if (enc_start) {
-    status = cipher_encrypt(stream->rtp_cipher, 
-			    (octet_t *)enc_start, &enc_octet_len);
-    if (status)
-      return err_status_cipher_fail;
-  }
+/*
+ * 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.
+ */
 
-  /*
-   *  if we're authenticating, run authentication function and put result
-   *  into the auth_tag 
-   */
-  if (auth_start) {        
+static srtp_event_handler_func_t *srtp_event_handler = srtp_event_reporter;
 
-    /* initialize auth func context */
-    status = auth_start(stream->rtp_auth);
-    if (status) return status;
+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
+     */
 
-    /* run auth func over packet */
-    status = auth_update(stream->rtp_auth, 
-			 (octet_t *)auth_start, *pkt_octet_len);
-    if (status) return status;
-    
-    /* run auth func over ROC, put result into auth_tag */
-    status = auth_compute(stream->rtp_auth, (octet_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;   
+    /* 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 (auth_tag) {
+    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
+    uint32_t local_roc = ((high32(*seq) << 16) | (low32(*seq) >> 16));
+    uint16_t local_seq = (uint16_t)(low32(*seq));
+#else
+    uint32_t local_roc = (uint32_t)(*seq >> 16);
+    uint16_t local_seq = (uint16_t)*seq;
+#endif
+
+    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 &&
+            stream->session_keys[i].mki_size <= base_mki_start_location) {
+            *mki_size = stream->session_keys[i].mki_size;
+            mki_start_location = base_mki_start_location - *mki_size;
+
+            if (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
+    uint32_t internal_pkt_idx_reduced;
+    uint32_t external_pkt_idx_reduced;
+    uint32_t internal_roc;
+    uint32_t roc_difference;
+#endif
+
+#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
+        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
+        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
+    }
+
+    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);
+    }
+    /* 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);
+#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;
 }
 
+/*
+ * 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;
 
-err_status_t
-srtp_unprotect(srtp_ctx_t *ctx, void *srtp_hdr, int *pkt_octet_len) {
-  srtp_hdr_t *hdr = srtp_hdr;
-  uint32_t *enc_start;      /* pointer to start of encrypted portion  */
-  uint32_t *auth_start;     /* pointer to start of auth. portion      */
-  uint32_t enc_octet_len = 0;/* number of octets in encrypted portion */
-  octet_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;
-  octet_t tmp_tag[SRTP_MAX_TAG_LEN];
-  int tag_len, prefix_len;
+    debug_print(mod_srtp, "function srtp_unprotect_aead", NULL);
 
-  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
-       */
 #ifdef NO_64BIT_MATH
-      est = (xtd_seq_num_t) make64(0,ntohs(hdr->seq));
-      delta = low32(est);
+    debug_print2(mod_srtp, "estimated u_packet index: %08x%08x", high32(est),
+                 low32(est));
 #else
-      est = (xtd_seq_num_t) ntohs(hdr->seq);
-      delta = est;
-#endif
-    } else {
-      
-      /*
-       * no stream corresponding to SSRC found, and we don't do
-       * key-sharing, so return an error
-       */
-      return err_status_no_ctx;
-    }
-  } 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;
-  }
-
-  debug_print(mod_srtp, "estimated packet index: %016llx", est);
-
-  /* 
-   * 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); 
-
-  /* 
-   * set the cipher's IV properly, depending on whatever cipher we
-   * happen to be using
-   */
-  if (stream->rtp_cipher->type == &aes_icm) {
-
-    /* aes counter mode */
-    iv.v32[0] = 0;
-    iv.v32[1] = hdr->ssrc;  /* still in network order */
-#ifdef NO_64BIT_MATH
-    iv.v64[1] = bswap_64(make64((high32(est) << 16) | (low32(est) >> 16),
-			         low32(est) << 16));
-#else
-    iv.v64[1] = bswap_64(est << 16);
-#endif
-    status = aes_icm_set_iv(stream->rtp_cipher->state, &iv);
-  } 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] = bswap_64(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 = bswap_64(make64((high32(est) << 16) |
-					    (low32(est) >> 16),
-					    low32(est) << 16));
-#else
-  est = bswap_64(est << 16);
+    debug_print(mod_srtp, "estimated u_packet index: %016llx", est);
 #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) 
-      enc_start += ((srtp_hdr_xtnd_t *)enc_start)->length;
-    enc_octet_len = *pkt_octet_len - tag_len
-      - ((enc_start - (uint32_t *)hdr) << 2);
-  } else {
-    enc_start = NULL;
-  }
+    /* get tag length from stream */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtp_auth);
 
-  /* 
-   * 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 = (octet_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, (octet_t *)auth_start,  
-			 *pkt_octet_len - tag_len);
-
-    /* run auth func over ROC, then write tmp tag */
-    status = auth_compute(stream->rtp_auth, (octet_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 (status)
-      return err_status_auth_fail;   
-
-    if (octet_string_is_eq(tmp_tag, auth_tag, tag_len))
-      return err_status_auth_fail;
-  }
-
-  /* if we're encrypting, add keystream into ciphertext */
-  if (enc_start) {
-    status = cipher_encrypt(stream->rtp_cipher, 
-			    (octet_t *)enc_start, &enc_octet_len);
-    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;
-    } 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
+    /*
+     * AEAD uses a new IV formation method
      */
-    status = srtp_stream_clone(ctx->stream_template, hdr->ssrc, &new_stream); 
+    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
+        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_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;
-    
-    /* 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);
+        return status;
 
-  /* decrease the packet length by the length of the auth tag */
-  *pkt_octet_len -= tag_len;
+    /* 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;
 
-  return err_status_ok;  
+    /*
+     * 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);
+
+    if (session_keys == NULL)
+        return srtp_err_status_bad_mki;
+
+    /*
+     * 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 {
+        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;
+    }
+
+    /*
+     * 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 packet index: %08x%08x", high32(est),
+                 low32(est));
+#else
+    debug_print(mod_srtp, "estimated packet index: %016llx", est);
+#endif
+
+    /*
+     * 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));
+#else
+        iv.v64[1] = 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) {
+            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;
+#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_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));
+#else
+    est = be64_to_cpu(est << 16);
+#endif
+
+    /*
+     * 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;
 }
 
-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_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 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 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 {
+        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 (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 (srtp_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.
+     */
+    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;
+
+    /* 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;
+}
+
+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;
+}
+
+/*
  * The following code is under consideration for removal.  See
- * SRTP_MAX_TRAILER_LEN 
+ * SRTP_MAX_TRAILER_LEN
  */
 #if 0
 
@@ -1099,7 +2768,7 @@
 
 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
@@ -1108,598 +2777,1953 @@
  * 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;
+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;
-}
-
-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);
-    if (status)
-      return status;
-    stream = next;
-  }
-  
-  /* deallocate stream template, if there is one */
-  if (session->stream_template != NULL) {
-    status = cipher_dealloc(session->stream_template->rtp_cipher); 
-    if (status) 
-      return status; 
-    status = auth_dealloc(session->stream_template->rtp_auth);
-    if (status)
-      return status;
-    crypto_free(session->stream_template);
-  }
-
-  /* deallocate session context */
-  crypto_free(session);
-
-  return 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;
-
-  /* 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);
-    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;
+    /* walk down list until ssrc is found */
+    stream = srtp->stream_list;
+    while (stream != NULL) {
+        if (stream->ssrc == ssrc)
+            return stream;
+        stream = stream->next;
     }
-    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;
+
+    /* 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;
     }
-    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;
+
+    /* 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;
 }
 
+srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy)
+{
+    srtp_err_status_t status;
+    srtp_stream_t tmp;
 
-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) || (policy == NULL) ||
+        (!srtp_validate_policy_master_keys(policy)))
+        return srtp_err_status_bad_param;
 
-  /* 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;
+    }
 
-  /* 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;
+    /* initialize stream  */
+    status = srtp_stream_init(tmp, policy);
+    if (status) {
+        srtp_stream_dealloc(tmp, NULL);
+        return status;
+    }
 
-  /* 
-   * 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) {    
+    /*
+     * 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_dealloc(tmp, NULL);
+            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_dealloc(tmp, NULL);
+            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_dealloc(tmp, NULL);
+        return srtp_err_status_bad_param;
+    }
 
-    stat = srtp_add_stream(ctx, policy);
-    if (stat) {
-      return stat;
-    }    
-
-    /* set policy to next item in list  */
-    policy = policy->next;
-  }
-
-  return err_status_ok;
+    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;
 
-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 srtp_err_status_bad_param;
 
-  /* 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;
+    /* 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;
 
-  /* remove stream from the list */
-  last_stream->next = stream->next;
+    /*
+     * 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;
+        }
 
-  /* deallocate the stream */
-  status = srtp_stream_dealloc(session, stream);
-  if (status)
+        /* 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;
+
+    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;
+}
+
+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;
-
-  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;
+}
+
+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;
+}
 
 /*
- * 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_128_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
-crypto_policy_set_rtcp_default(crypto_policy_t *p) {
-
-  p->cipher_type     = AES_128_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_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 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 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 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 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;
+}
+
+/*
+ * 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 */
+}
+
+/*
+ * 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;
+}
+
+/*
  * secure rtcp functions
  */
 
-err_status_t 
-srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len) {
-  srtcp_hdr_t *hdr = 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            */
-  uint32_t enc_octet_len = 0;/* number of octets in encrypted portion */
-  octet_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;
+/*
+ * 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;
 
-  /* 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_receiver;
-    } else {
-      srtp_handle_event(ctx, stream, event_ssrc_collision);
+    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;
     }
-  }  
+    in.v32[2] = htonl(seq_num);
 
-  /* get tag length from stream context */
-  tag_len = auth_get_tag_length(stream->rtcp_auth); 
+    debug_print(mod_srtp, "Pre-salted RTCP IV = %s\n", v128_hex_string(&in));
 
-  /*
-   * 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;
+    /*
+     * 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));
 
-  /* 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);
+    /*
+     * Finally, apply the SALT to the input
+     */
+    v128_xor(iv, &in, &salt);
 
-  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 = (octet_t *)hdr + *pkt_octet_len + sizeof(srtcp_trailer_t); 
-
-  /* 
-   * 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 == &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 = aes_icm_set_iv(stream->rtcp_cipher->state, &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, 
-			    (octet_t *)enc_start, &enc_octet_len);
-    if (status)
-      return err_status_cipher_fail;
-  }
-
-  /* initialize auth func context */
-  auth_start(stream->rtcp_auth);
-
-  /* per spec, do auth after encryption */
-  /* run auth func over packet, put result into auth_tag */
-  status = auth_compute(stream->rtcp_auth, 
-			(octet_t *)auth_start,  *pkt_octet_len, 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;  
+    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;
-  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            */
-  uint32_t enc_octet_len = 0;/* number of octets in encrypted portion */
-  octet_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  octet_t tmp_tag[SRTP_MAX_TAG_LEN];
-  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) {
-      stream = ctx->stream_template;
-      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_tag = (octet_t *)hdr + *pkt_octet_len - tag_len;
-
-  /* 
-   * check the sequence number for replays
-   */
-  /* this is easier than dealing with bitfield access */
-  seq_num = ntohl(*trailer) & SRTCP_INDEX_MASK;
-  status = rdb_check(&stream->rtcp_rdb, seq_num);
-  if (status)
-    return status;
-  debug_print(mod_srtp, "srtcp index: %x", seq_num);
-
-  /* 
-   * if we're using aes counter mode, set nonce and seq 
-   */
-  if (stream->rtcp_cipher->type == &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_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
+    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;
+    uint32_t tseq;
+    unsigned int mki_size = 0;
 
-    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 = aes_icm_set_iv(stream->rtcp_cipher->state, &iv);
+    /* get tag length from stream context */
+    tag_len = srtp_auth_get_tag_length(session_keys->rtcp_auth);
 
-  } 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, (octet_t *)auth_start,  
-			*pkt_octet_len - (tag_len + sizeof(srtcp_trailer_t)),
-			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_encrypt(stream->rtcp_cipher, 
-			    (octet_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));
-
-  /* 
-   * 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
+    /*
+     * set encryption start and encryption length - if we're not
+     * providing confidentiality, set enc_start to NULL
      */
-    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;
-  }
+    enc_start = (uint32_t *)hdr + uint32s_in_rtcp_header;
+    enc_octet_len = *pkt_octet_len - octets_in_rtcp_header;
 
-  /* 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;  
+    /* NOTE: hdr->length is not usable - it refers to only the first
+     * RTCP report in the compound packet!
+     */
+    trailer_p = (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 {
+        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 + 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);
+
+    memcpy(trailer_p, &trailer, sizeof(trailer));
+
+    /*
+     * 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
+     */
+    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;
+}
+
+/*
+ * 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.
+ */
+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_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
+    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 */
+    trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                             sizeof(srtcp_trailer_t) - mki_size);
+    memcpy(&trailer, trailer_p, sizeof(trailer));
+
+    /*
+     * 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_p) & 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);
+}
+
+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_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
+    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);
+
+    if (session_keys == NULL)
+        return srtp_err_status_bad_mki;
+
+    /*
+     * 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!
+     */
+    trailer_p = (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);
+
+    memcpy(trailer_p, &trailer, sizeof(trailer));
+
+    /*
+     * 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_p;            /* pointer to start of trailer            */
+    uint32_t trailer;               /* trailer value                          */
+    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 */
+    trailer_p = (uint32_t *)((char *)hdr + *pkt_octet_len -
+                             (tag_len + mki_size + sizeof(srtcp_trailer_t)));
+    memcpy(&trailer, trailer_p, sizeof(trailer));
+
+    e_bit_in_packet =
+        (*((unsigned char *)trailer_p) & 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 (srtp_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;
+#ifdef GCM
+    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;
+}
+
+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;
+#ifdef GCM
+    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);
+}
+
+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 */
+    }
+}
+
+srtp_err_status_t stream_get_protect_trailer_length(srtp_stream_ctx_t *stream,
+                                                    uint32_t is_rtp,
+                                                    uint32_t use_mki,
+                                                    uint32_t mki_index,
+                                                    uint32_t *length)
+{
+    srtp_session_keys_t *session_key;
+
+    *length = 0;
+
+    if (use_mki) {
+        if (mki_index >= stream->num_master_keys) {
+            return srtp_err_status_bad_mki;
+        }
+        session_key = &stream->session_keys[mki_index];
+
+        *length += session_key->mki_size;
+
+    } else {
+        session_key = &stream->session_keys[0];
+    }
+    if (is_rtp) {
+        *length += srtp_auth_get_tag_length(session_key->rtp_auth);
+    } else {
+        *length += srtp_auth_get_tag_length(session_key->rtcp_auth);
+        *length += sizeof(srtcp_trailer_t);
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t get_protect_trailer_length(srtp_t session,
+                                             uint32_t is_rtp,
+                                             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;
+    }
+
+    if (session->stream_template == NULL && session->stream_list == NULL) {
+        return srtp_err_status_bad_param;
+    }
+
+    *length = 0;
+
+    stream = session->stream_template;
+
+    if (stream != NULL) {
+        stream_get_protect_trailer_length(stream, is_rtp, use_mki, mki_index,
+                                          length);
+    }
+
+    stream = session->stream_list;
+
+    while (stream != NULL) {
+        uint32_t temp_length;
+        if (stream_get_protect_trailer_length(stream, is_rtp, use_mki,
+                                              mki_index, &temp_length) ==
+            srtp_err_status_ok) {
+            if (temp_length > *length) {
+                *length = temp_length;
+            }
+        }
+        stream = stream->next;
+    }
+
+    return srtp_err_status_ok;
+}
+
+srtp_err_status_t srtp_get_protect_trailer_length(srtp_t session,
+                                                  uint32_t use_mki,
+                                                  uint32_t mki_index,
+                                                  uint32_t *length)
+{
+    return get_protect_trailer_length(session, 1, use_mki, mki_index, length);
+}
+
+srtp_err_status_t srtp_get_protect_rtcp_trailer_length(srtp_t session,
+                                                       uint32_t use_mki,
+                                                       uint32_t mki_index,
+                                                       uint32_t *length)
+{
+    return get_protect_trailer_length(session, 0, use_mki, mki_index, length);
+}
+
+/*
+ * 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);
+}
+
+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;
 }
diff --git a/srtp/srtp_ust.c b/srtp/srtp_ust.c
deleted file mode 100644
index a5f0c57..0000000
--- a/srtp/srtp_ust.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * srtp.c
- *
- *  the secure real-time transport protocol
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "alloc.h"           /* for crypto_alloc() */
-#include "srtp.h"
-#include "rijndael-icm.h"    /* for rijndael_icm   */
-
-
-extern cipher_type_t rijndael_icm;
-extern auth_type_t   tmmhv2;
-
-/* the debug module for 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
-
-err_status_t
-srtp_alloc(srtp_ctx_t    **ctx_ptr,
-	    cipher_type_id_t c_id,
-	    int              cipher_key_len, 
-	    auth_type_id_t   a_id,
-	    int              auth_key_len,
-	    int              auth_tag_len,
-	    sec_serv_t       sec_serv) {
-
-  err_status_t stat;
-  srtp_ctx_t *ctx;
-
-  /* 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;
-  *ctx_ptr = ctx;
-
-  /* set security services flag */
-  ctx->services = sec_serv;
-
-  /* allocate ust context */
-  stat = ust_alloc(&ctx->ust,     /* ust context                       */
-		   c_id,          /* keystream generator identifier    */
-		   cipher_key_len,/* number of octets in cipher key    */
-		   a_id,          /* auth algorithm specification      */
-		   auth_key_len,  /* number of octets in the auth key  */
-		   auth_tag_len,  /* number of octets in the auth tag  */
-		   128            /* bits in replay window             */
-		   );
-  
-  if (stat) {
-    free(ctx);
-    return stat;
-  }
- 
-  return err_status_ok;
-}
-
-/*
- * srtp_init_aes_128_prf(ctx, key) initializes an srtp_ctx_t
- * with a given master key.  (The offset or salt value is assumed
- * to be the trailing octets of the key.)
- * 
- * the key MUST be 30 octets long
- *
- * The PRF used for key derivation here is that defined in the secure
- * rtp specification, though in theory, other PRFs can be used.  The
- * cipher is hardwired to AES-128 Counter Mode with 112 bits of salt.
- */
-
-typedef enum {
-  label_encryption             = 0x00,
-  label_message_authentication = 0x01,
-  label_salt                   = 0x02
-} srtp_prf_label;
-
-err_status_t
-srtp_init_aes_128_prf(srtp_ctx_t *srtp, const octet_t key[30]) {
-  err_status_t stat;
-  rijndael_icm_context c;
-  xtd_seq_num_t idx = 0;               /* for setting icm to zero-index   */   
-  octet_t *buffer;                     /* temporary storage for keystream */
-  octet_t *enc_key_buf, *enc_salt_buf, *auth_key_buf; 
-  int buffer_size;
-
-  rdbx_init(&srtp->ust.rdbx);
-
-  debug_print(mod_srtp, "srtp_init_aes_128_prf()", NULL);
-
-  /* allocate temporary storage, set pointers, and zeroize buffer */
-  buffer_size = cipher_get_key_length(srtp->ust.c)
-    + auth_get_key_length(srtp->ust.h);
-
-  /* if we're using rijndael_icm, we need to allocate room for the salt */
-  if (srtp->ust.c->type == &rijndael_icm)
-    buffer_size += 16;
-  buffer = crypto_alloc(buffer_size);
-  if (buffer == NULL)
-    return err_status_alloc_fail;
-  enc_key_buf = buffer;
-  enc_salt_buf = buffer + cipher_get_key_length(srtp->ust.c);
-  auth_key_buf = enc_salt_buf + 16;  /* DAM - this should depend on cipher! */
-  octet_string_set_to_zero(buffer, buffer_size);
-    
-  /* generate encryption key, putting it into enc_key_buf  */
-
-  /* note that we assume that index DIV t == 0 in this implementation */
-  
-  rijndael_icm_context_init(&c, key);
-
-  /* exor <label> into the eigth octet of the state */
-  rijndael_icm_set_div_param(&c, (uint64_t) label_encryption);
-  rijndael_icm_set_segment(&c, idx);
-
-  debug_print(mod_srtp, "master key: %s", 
-	      octet_string_hex_string((octet_t *)&c.expanded_key[0], 60));
-  debug_print(mod_srtp, "generating cipher key", NULL);
-  debug_print(mod_srtp, "cipher ctr: %s", 
-	      octet_string_hex_string((octet_t *)&c.counter, 32));  
-
-  rijndael_icm_encrypt(&c, enc_key_buf, 
-		       cipher_get_key_length(srtp->ust.c));
-
-  debug_print(mod_srtp, "cipher key: %s", 
-	      octet_string_hex_string(enc_key_buf, 32));  
-
-  /* generate encryption salt, putting it into enc_salt_buf */
-  rijndael_icm_context_init(&c, key);
-
-
-  /* 
-   * if the cipher in the srtp context is rijndael_icm, then we need
-   * to generate the salt value
-   */
-
-  if (srtp->ust.c->type == &rijndael_icm) {
-
-/*     printf("found rijndael_icm, generating salt\n"); */
-
-    /* exor <label> into the eigth octet of the state */
-    rijndael_icm_set_div_param(&c, (uint64_t) label_salt); 
-    rijndael_icm_set_segment(&c, idx);
-    
-    debug_print(mod_srtp, "generating cipher salt", NULL);
-    debug_print(mod_srtp, "cr slt ctr: %s", 
-		octet_string_hex_string((octet_t *)&c.counter, 32));  
-
-    rijndael_icm_encrypt(&c, enc_salt_buf, 14);
-
-    debug_print(mod_srtp, "cipher slt: %s", 
-		octet_string_hex_string(enc_salt_buf, 32));  
-
-    /*
-     * we don't yet know the ssrc of the sender, so we don't exor the
-     * ssrc value into the enc_salt_buf
-     */
-  }
-  
-  /* generate authentication key, putting it into auth_key_buf */
-
-  rijndael_icm_context_init(&c, key);
-
-  /* exor <label> into the eigth octet of the state */
-  rijndael_icm_set_div_param(&c, (uint64_t) label_message_authentication);
-  rijndael_icm_set_segment(&c, idx);
-
-  debug_print(mod_srtp, "generating auth key", NULL);
-  debug_print(mod_srtp, "auth ctr:   %s",
-	      octet_string_hex_string((octet_t *)&c.counter, 32));  
-
-  rijndael_icm_encrypt(&c, auth_key_buf,
-		       auth_get_key_length(srtp->ust.h));
-  
-  debug_print(mod_srtp, "auth key:   %s",
-	      octet_string_hex_string(auth_key_buf, 
-	          2*auth_get_key_length(srtp->ust.h))); 
-  
-  /* initialize ust context with keys */
-  stat = ust_init(&srtp->ust, enc_key_buf, auth_key_buf);  
-  if (stat) {
-    free(buffer);
-    return err_status_init_fail;
-  }  
-
-  /* free memory then return */
-  free(buffer);
-  return err_status_ok;  
-}
-
-
-err_status_t
-srtp_protect(srtp_ctx_t *ctx, srtp_hdr_t *hdr, int *pkt_octet_len) {
-  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  */
-  xtd_seq_num_t est;        /* estimated xtd_seq_num_t of *hdr        */
-  int delta;                /* delta of local pkt idx and that in hdr */
-  octet_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  err_status_t status;   
-  int tag_len = ust_get_tag_len(&ctx->ust); 
- 
-  /* if we're using rindael counter mode, exor the ssrc into the salt */
-  if (ctx->ust.c->type == &rijndael_icm) {
-    uint32_t ssrc = ntohl(hdr->ssrc);
-    rijndael_icm_context *cipher 
-      = (rijndael_icm_context *)ctx->ust.c->state;
-
-    /* exor the ssrc into bytes four through seven of the salt */
-    cipher->offset.octet[4] ^= (ssrc >> 24);
-    cipher->offset.octet[5] ^= (ssrc >> 16) & 0xff;
-    cipher->offset.octet[6] ^= (ssrc >> 8) & 0xff;
-    cipher->offset.octet[7] ^= ssrc & 0xff;
-  }
-
-  /*
-   * 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 (ctx->services & sec_serv_conf) {
-    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
-    if (hdr->x == 1) 
-      enc_start += ((srtp_hdr_xtnd_t *)enc_start)->length;
-    enc_octet_len = *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 (ctx->services & sec_serv_auth) {
-    auth_start = (uint32_t *)hdr;
-    auth_tag = (octet_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(&ctx->ust.rdbx, &est, ntohs(hdr->seq));
-  if (rdbx_check(&ctx->ust.rdbx, delta) != replay_check_ok)
-    return err_status_replay_fail;  /* we've been asked to reuse an index */
-  rdbx_add_index(&ctx->ust.rdbx, delta);
-
-  status = 
-  ust_xfm(&ctx->ust,           /* ust context                      */
-	  est,                 /* index                            */
-	  (octet_t *)enc_start,/* pointer to encryption start      */
-	  enc_octet_len,       /* number of octets to encrypt      */
-	  (octet_t *)hdr,      /* pointer to authentication start  */
-	  *pkt_octet_len,      /* number of octets to authenticate */
-	  auth_tag);           /* authentication tag               */
-	  
-#if 0  
-  status = 
-  ust_xfm_u16(&ctx->ust,           /* ust context                      */
-	      ntohs(hdr->seq),     /* index                            */
-	      (octet_t *)enc_start,/* pointer to encryption start      */
-	      enc_octet_len,       /* number of octets to encrypt      */
-	      (octet_t *)hdr,      /* pointer to authentication start  */
-	      *pkt_octet_len,      /* number of octets to authenticate */
-	      auth_tag);           /* authentication tag               */
-#endif
-  
-  /* increase the packet length by the length of the auth tag */
-  *pkt_octet_len += tag_len;
-    
-  return err_status_ok;  
-}
-
-
-err_status_t
-srtp_unprotect(srtp_ctx_t *ctx, srtp_hdr_t *hdr, int *pkt_octet_len) {
-  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  */
-  octet_t *auth_tag = NULL; /* location of auth_tag within packet     */
-  err_status_t status;   
-  int tag_len = ust_get_tag_len(&ctx->ust); 
-
-  /*
-   * 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
-   */
-#if 0
-  stream = srtp_stream_lookup(&ctx);
-  if (stream == NULL)
-    stream = temp_stream;
-#endif
-  /* 
-   * add ssrc into cipher context ("diversification") - note that if
-   * the cipher does not support this operation, it will silently
-   * fail, which is actually what we want here 
-   */
-  ust_set_diversifier(&ctx->ust, ntohl(hdr->ssrc));
-
-  /*
-   * 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 (ctx->services & sec_serv_conf) {
-    enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;  
-    if (hdr->x == 1) 
-      enc_start += ((srtp_hdr_xtnd_t *)enc_start)->length;
-    enc_octet_len = *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 (ctx->services & sec_serv_auth) {
-    auth_start = (uint32_t *)hdr;
-    auth_tag = (octet_t *)hdr + *pkt_octet_len - tag_len;
-  } else {
-    auth_start = NULL;
-    auth_tag = NULL;
-  }
-
-  /* at this point, the ust context should look into the stream */
-  status = 
-  ust_inv_xfm_u16(
-	      &ctx->ust,                /* ust context                 */
-	      ntohs(hdr->seq),          /* index                       */
-	      (octet_t *)enc_start,     /* pointer to encryption start */
-	      enc_octet_len,            /* number of octets to encrypt */
-	      (octet_t *)hdr,           /* pointer to auth start       */
-	      *pkt_octet_len - tag_len, /* num octets to authenticate  */
-	      auth_tag);                /* authentication tag          */
-
-  if (status)
-    return status;
-
-  /* decrease the packet length by the length of the auth tag */
-  *pkt_octet_len -= tag_len;
-    
-  return err_status_ok;  
-}
-
-
-/*
- * 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_ctx_t (i.e. between initializations).
- */
-
-int
-srtp_get_trailer_length(const srtp_t a) {
-  return ust_get_tag_len(&a->ust);
-}
-
-/* 
- * srtp_print_packet(...) is for debugging only 
- * it prints an RTP packet to the stdout
- */
-
-#include <stdio.h>
-
-void
-srtp_print_packet(srtp_hdr_t *hdr, int pkt_octet_len) {
-  octet_t *data = ((octet_t *)hdr)+octets_in_rtp_header;
-  int hex_len = 2*(pkt_octet_len-octets_in_rtp_header);
-
-  printf("rtp packet: {\n");
-  printf("   version:\t%d\n", hdr->version);
-  printf("   p:\t\t%d\n", hdr->p);
-  printf("   x:\t\t%d\n", hdr->x);
-  printf("   cc:\t\t%d\n", hdr->cc);
-  printf("   m:\t\t%d\n", hdr->m);
-  printf("   pt:\t\t%x\n", hdr->pt);
-  printf("   seq:\t\t%x\n", hdr->seq);
-  printf("   ts:\t\t%x\n", hdr->ts);
-  printf("   ssrc:\t%x\n", hdr->ssrc);
-  printf("   data:\t%s\n", octet_string_hex_string(data, hex_len));
-  printf("} (%d octets in data)\n", pkt_octet_len-octets_in_rtp_header);
-
-}
-
diff --git a/srtp2.vcxproj b/srtp2.vcxproj
new file mode 100644
index 0000000..a6ac642
--- /dev/null
+++ b/srtp2.vcxproj
@@ -0,0 +1,405 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug Dll|Win32">
+      <Configuration>Debug Dll</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug Dll|x64">
+      <Configuration>Debug Dll</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release Dll|Win32">
+      <Configuration>Release Dll</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release Dll|x64">
+      <Configuration>Release Dll</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{EEF031CB-FED8-451E-A471-91EC8D4F6750}</ProjectGuid>
+    <RootNamespace>srtp2</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'">
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+    <IntDir>$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message />
+      <Command />
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message />
+      <Command />
+    </CustomBuildStep>
+    <ClCompile>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <ClCompile>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message />
+      <Command />
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile>
+      <OptimizeReferences>false</OptimizeReferences>
+      <EnableCOMDATFolding>false</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration />
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile>
+      <OptimizeReferences>false</OptimizeReferences>
+      <EnableCOMDATFolding>false</EnableCOMDATFolding>
+      <LinkTimeCodeGeneration>
+      </LinkTimeCodeGeneration>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|Win32'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message />
+      <Command />
+    </CustomBuildStep>
+    <ClCompile>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader />
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Dll|x64'">
+    <PreBuildEvent>
+      <Message>Creating config.h from config.hw</Message>
+      <Command>copy /Y "$(ProjectDir)config.hw" "$(ProjectDir)crypto\include\config.h" &gt; NUL</Command>
+    </PreBuildEvent>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <ClCompile>
+      <AdditionalIncludeDirectories>crypto/include;include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <StructMemberAlignment>Default</StructMemberAlignment>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <ModuleDefinitionFile>srtp.def</ModuleDefinitionFile>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="crypto\cipher\aes.c">
+      <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">Default</InlineFunctionExpansion>
+      <InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">Default</InlineFunctionExpansion>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</IntrinsicFunctions>
+      <IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</IntrinsicFunctions>
+      <FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|Win32'">false</FunctionLevelLinking>
+      <FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Debug Dll|x64'">false</FunctionLevelLinking>
+    </ClCompile>
+    <ClCompile Include="crypto\cipher\aes_icm.c" />
+    <ClCompile Include="crypto\cipher\cipher.c" />
+    <ClCompile Include="crypto\cipher\null_cipher.c" />
+    <ClCompile Include="crypto\hash\auth.c" />
+    <ClCompile Include="crypto\hash\hmac.c" />
+    <ClCompile Include="crypto\hash\null_auth.c" />
+    <ClCompile Include="crypto\hash\sha1.c" />
+    <ClCompile Include="crypto\kernel\alloc.c" />
+    <ClCompile Include="crypto\kernel\crypto_kernel.c" />
+    <ClCompile Include="crypto\kernel\err.c" />
+    <ClCompile Include="crypto\kernel\key.c" />
+    <ClCompile Include="crypto\math\datatypes.c" />
+    <ClCompile Include="crypto\math\stat.c" />
+    <ClCompile Include="crypto\replay\rdb.c" />
+    <ClCompile Include="crypto\replay\rdbx.c" />
+    <ClCompile Include="crypto\replay\ut_sim.c" />
+    <ClCompile Include="srtp\ekt.c" />
+    <ClCompile Include="srtp\srtp.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="crypto\include\aes.h" />
+    <ClInclude Include="crypto\include\aes_cbc.h" />
+    <ClInclude Include="crypto\include\aes_icm.h" />
+    <ClInclude Include="crypto\include\alloc.h" />
+    <ClInclude Include="crypto\include\auth.h" />
+    <ClInclude Include="crypto\include\cipher.h" />
+    <ClInclude Include="crypto\include\cipher_types.h" />
+    <ClInclude Include="crypto\include\config.h" />
+    <ClInclude Include="crypto\include\crypto.h" />
+    <ClInclude Include="crypto\include\cryptoalg.h" />
+    <ClInclude Include="crypto\include\crypto_kernel.h" />
+    <ClInclude Include="crypto\include\crypto_types.h" />
+    <ClInclude Include="crypto\include\datatypes.h" />
+    <ClInclude Include="crypto\include\err.h" />
+    <ClInclude Include="crypto\include\gf2_8.h" />
+    <ClInclude Include="crypto\include\hmac.h" />
+    <ClInclude Include="crypto\include\integers.h" />
+    <ClInclude Include="crypto\include\key.h" />
+    <ClInclude Include="crypto\include\null_auth.h" />
+    <ClInclude Include="crypto\include\null_cipher.h" />
+    <ClInclude Include="crypto\include\prng.h" />
+    <ClInclude Include="crypto\include\rand_source.h" />
+    <ClInclude Include="crypto\include\rdb.h" />
+    <ClInclude Include="crypto\include\rdbx.h" />
+    <ClInclude Include="crypto\include\sha1.h" />
+    <ClInclude Include="crypto\include\stat.h" />
+    <ClInclude Include="include\ekt.h" />
+    <ClInclude Include="include\srtp.h" />
+    <ClInclude Include="include\srtp_priv.h" />
+    <ClInclude Include="include\ut_sim.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="config.hw" />
+    <None Include="srtp.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/srtp2.vcxproj.filters b/srtp2.vcxproj.filters
new file mode 100644
index 0000000..24e040f
--- /dev/null
+++ b/srtp2.vcxproj.filters
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Source Files\Kernel">
+      <UniqueIdentifier>{c23c2703-7a15-4b7e-be1c-0555b7d0f8e1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Ciphers">
+      <UniqueIdentifier>{43e45f3f-795e-4f2a-8801-3e19b7801d07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Hashes">
+      <UniqueIdentifier>{11a7bf2a-6706-4c35-8e91-f58bef0f8669}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Replay">
+      <UniqueIdentifier>{237501ce-7043-44c7-a895-df2ceae6c8cd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Math">
+      <UniqueIdentifier>{2a11592a-e474-4a50-bb3a-e4f039633257}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="srtp\ekt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="srtp\srtp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\kernel\alloc.c">
+      <Filter>Source Files\Kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\kernel\crypto_kernel.c">
+      <Filter>Source Files\Kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\kernel\err.c">
+      <Filter>Source Files\Kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\kernel\key.c">
+      <Filter>Source Files\Kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\cipher\aes.c">
+      <Filter>Source Files\Ciphers</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\cipher\aes_icm.c">
+      <Filter>Source Files\Ciphers</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\cipher\cipher.c">
+      <Filter>Source Files\Ciphers</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\cipher\null_cipher.c">
+      <Filter>Source Files\Ciphers</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\hash\auth.c">
+      <Filter>Source Files\Hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\hash\hmac.c">
+      <Filter>Source Files\Hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\hash\null_auth.c">
+      <Filter>Source Files\Hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\hash\sha1.c">
+      <Filter>Source Files\Hashes</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\replay\rdb.c">
+      <Filter>Source Files\Replay</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\replay\rdbx.c">
+      <Filter>Source Files\Replay</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\replay\ut_sim.c">
+      <Filter>Source Files\Replay</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\math\datatypes.c">
+      <Filter>Source Files\Math</Filter>
+    </ClCompile>
+    <ClCompile Include="crypto\math\stat.c">
+      <Filter>Source Files\Math</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="crypto\include\aes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\aes_cbc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\aes_icm.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\alloc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\auth.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\cipher.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\cipher_types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\config.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\crypto.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\crypto_kernel.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\crypto_types.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\cryptoalg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\datatypes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\ekt.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\err.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\gf2_8.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\hmac.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\integers.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\key.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\null_auth.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\null_cipher.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\prng.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\rand_source.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\rdb.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\rdbx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\sha1.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\srtp.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\srtp_priv.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="crypto\include\stat.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="include\ut_sim.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="config.hw" />
+    <None Include="srtp.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
+</Project>
diff --git a/tables/aes_tables.c b/tables/aes_tables.c
deleted file mode 100644
index cae1ae4..0000000
--- a/tables/aes_tables.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * aes_tables.c
- * 
- * generate tables for the AES cipher
- * 
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright(c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <stdio.h>
-#include "gf2_8.h"
-#include "math.h"
-
-
-unsigned char aes_sbox[256];
-
-unsigned char aes_inv_sbox[256];
-
-unsigned long T0[256], T1[256], T2[256], T3[256], T4[256]; 
-
-
-#define AES_INVERSE_TEST 0  /* set to 1 to test forward/backwards aes */
-
-/* functions for precomputing AES values */
-
-/*
- * A[] is the 8 x 8 binary matrix (represented as an array of columns,
- * where each column is an octet) which defines the affine
- * transformation used in the AES substitution table (Section
- * 4.2.1 of the spec).
- */
-
-octet_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 };
-
-/*
- * b is the 8 bit vector (represented as an octet) used in the affine
- * transform described above.
- */
-
-octet_t b = 99;
-
-
-void
-aes_init_sbox() {
-  unsigned int i;
-  octet_t x;
-  
-  for (i=0; i < 256; i++) {
-    x = gf2_8_compute_inverse((gf2_8)i);
-    x = A_times_x_plus_b(A, x, b);
-    aes_sbox[i] = x;
-    aes_inv_sbox[x] = i;
-  }
-}
-
-void
-aes_compute_tables() {
-  int i;
-  uint32_t x1, x2, x3;
-  v32_t tmp;
-
-  /* initialize substitution table */
-  aes_init_sbox();
-
-  /* combine sbox with linear operations to form 8-bit to 32-bit tables */
-  for (i=0; i < 256; i++) {
-    x1 = aes_sbox[i];
-    x2 = gf2_8_shift(x1);
-    x3 = x2 ^ x1;
-
-    tmp.octet[0] = x2;
-    tmp.octet[1] = x1;
-    tmp.octet[2] = x1;
-    tmp.octet[3] = x3;
-    T0[i] = tmp.value;
-
-    tmp.octet[0] = x3;
-    tmp.octet[1] = x2;
-    tmp.octet[2] = x1;
-    tmp.octet[3] = x1;
-    T1[i] = tmp.value;
-     
-    tmp.octet[0] = x1;
-    tmp.octet[1] = x3;
-    tmp.octet[2] = x2;
-    tmp.octet[3] = x1;
-    T2[i] = tmp.value;
-
-    tmp.octet[0] = x1;
-    tmp.octet[1] = x1;
-    tmp.octet[2] = x3;
-    tmp.octet[3] = x2;
-    T3[i] = tmp.value;
-     
-  }
-}
-
-
-/*
- * the tables U0, U1, U2, U3 implement the aes operations invSubBytes,
- * invMixColumns, and invShiftRows 
- */
-
-uint32_t U0[256], U1[256], U2[256], U3[256], U4[256];
-
-extern octet_t aes_inv_sbox[256];
-
-void
-aes_compute_inv_tables() {
-  int i;
-  octet_t x, xe, x9, xd, xb;
-  v32_t tmp;
-
-  /* combine sbox with linear operations to form 8-bit to 32-bit tables */
-  for (i=0; i < 256; i++) {
-     x = aes_inv_sbox[i];
-
-     xe = gf2_8_multiply(0x0e, x);     
-     x9 = gf2_8_multiply(0x09, x);     
-     xd = gf2_8_multiply(0x0d, x);     
-     xb = gf2_8_multiply(0x0b, x);     
-
-     tmp.octet[0] = xe;
-     tmp.octet[1] = x9;
-     tmp.octet[2] = xd;
-     tmp.octet[3] = xb;
-     U0[i] = tmp.value;
-
-     tmp.octet[0] = xb;
-     tmp.octet[1] = xe;
-     tmp.octet[2] = x9;
-     tmp.octet[3] = xd;
-     U1[i] = tmp.value;
-     
-     tmp.octet[0] = xd;
-     tmp.octet[1] = xb;
-     tmp.octet[2] = xe;
-     tmp.octet[3] = x9;
-     U2[i] = tmp.value;
-
-     tmp.octet[0] = x9;
-     tmp.octet[1] = xd;
-     tmp.octet[2] = xb;
-     tmp.octet[3] = xe;
-     U3[i] = tmp.value;
-
-     tmp.octet[0] = tmp.octet[1] = tmp.octet[2] = tmp.octet[3] = x;
-     U4[i] = tmp.value;
-   }
-}
-
-
-/*
- * aes_test_inverse() returns err_status_ok if aes
- * encryption and decryption are true inverses of each other, and
- * returns err_status_algo_fail otherwise
- */
-
-#include "err.h"
-
-err_status_t
-aes_test_inverse();
-
-#define TABLES_32BIT 1
-
-int
-main() {
-  int i;
-
-  aes_init_sbox();
-  aes_compute_inv_tables();
-
-#if TABLES_32BIT
-  printf("uint32_t U0 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%0lx, ", U0[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U1 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U1[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U2 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U2[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U3 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U3[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U4 = {");
- for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U4[i]);
-  }
-  printf("\n}\n");
-
-#else
-
-  printf("uint32_t U0 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U0[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U1 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U1[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U2 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U2[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U3 = {");
-  for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U3[i]);
-  }
-  printf("\n}\n");
-
- printf("uint32_t U4 = {");
- for (i=0; i < 256; i++) {
-    if ((i % 4) == 0)
-      printf("\n");
-    printf("0x%lx, ", U4[i]);
-  }
-  printf("\n}\n");
-
-
-#endif /* TABLES_32BIT */
-
-
-#if AES_INVERSE_TEST
-  /* 
-   * test that aes_encrypt and aes_decrypt are actually
-   * inverses of each other 
-   */
-    
-  printf("aes inverse test: ");
-  if (aes_test_inverse() == err_status_ok)
-    printf("passed\n");
-  else {
-    printf("failed\n");
-    exit(1);
-  }
-#endif
-  
-  return 0;
-}
-
-#if AES_INVERSE_TEST
-
-err_status_t
-aes_test_inverse() {
-  v128_t x, y;
-  aes_expanded_key_t expanded_key, decrypt_key;
-  octet_t plaintext[16] = {
-    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff 
-  };
-  octet_t key[16] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
-  };
-  v128_t k;
-  v128_set_to_zero(&x);
-  
-  v128_copy_octet_string(&k, key);
-  v128_copy_octet_string(&x, plaintext);
-  aes_expand_encryption_key(k, expanded_key);
-  aes_expand_decryption_key(k, decrypt_key);
-  aes_encrypt(&x, expanded_key);
-  aes_decrypt(&x, decrypt_key);
-  
-  /* compare to expected value then report */
-  v128_copy_octet_string(&y, plaintext);
-
-  if (v128_is_eq(&x, &y))
-    return err_status_ok;
-  return err_status_algo_fail;
-  
-}
- 
-#endif 
diff --git a/test/aes_calc.c b/test/aes_calc.c
deleted file mode 100644
index 56b0323..0000000
--- a/test/aes_calc.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * aes_calc.c
- * 
- * A simple AES calculator for generating AES encryption values
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
-  
- Example usage (with first NIST FIPS 197 test case):
- 
-[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v
- plaintext:      00112233445566778899aabbccddeeff
- key:            000102030405060708090a0b0c0d0e0f
- ciphertext:     69c4e0d86a7b0430d8cdb78070b4c55a
-
- */
-
-#include "aes.h"
-#include <stdio.h>
-#include <string.h>
-
-void
-usage(char *prog_name) {
-  printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
-  exit(255);
-}
-
-#define AES_KEY_LEN 16
-
-int
-main (int argc, char *argv[]) {
-  v128_t data, key;
-  aes_expanded_key_t exp_key;
-  int len;
-  int verbose;
-
-  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 {
-    /* 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_KEY_LEN*2) {
-    fprintf(stderr, 
-	    "error: too many digits in key "
-	    "(should be %d hexadecimal digits, found %u)\n",
-	    AES_KEY_LEN*2, (unsigned)strlen(argv[1]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((octet_t *)&key, argv[1], AES_KEY_LEN*2);
-  /* check that hex string is the right length */
-  if (len < AES_KEY_LEN*2) {
-    fprintf(stderr, 
-	    "error: too few digits in key "
-	    "(should be %d hexadecimal digits, found %d)\n",
-	    AES_KEY_LEN*2, len);
-    exit(1);    
-  } 
-      
-  /* read in plaintext, checking length */
-  if (strlen(argv[2]) > 16*2) {
-    fprintf(stderr, 
-	    "error: too many digits in plaintext "
-	    "(should be %d hexadecimal digits, found %u)\n",
-	    16*2, (unsigned)strlen(argv[2]));
-    exit(1);    
-  }
-  len = hex_string_to_octet_string((octet_t *)(&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((octet_t *)&data, 16));
-  }
-
-  /* encrypt plaintext */
-  aes_expand_encryption_key(key, exp_key);
-
-  aes_encrypt(&data, exp_key);
-
-  /* write ciphertext to output */
-  if (verbose) {
-    printf("key:\t\t%s\n", v128_hex_string(&key));
-    printf("ciphertext:\t");
-  }
-  printf("%s\n", v128_hex_string(&data));
-
-  return 0;
-}
-
diff --git a/test/auth_driver.c b/test/auth_driver.c
deleted file mode 100644
index 071f127..0000000
--- a/test/auth_driver.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * auth_driver.c
- *
- * a driver for auth functions
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include <stdio.h>    /* for printf()       */
-#include <stdlib.h>   /* for crypto_alloc() */
-#include <unistd.h>   /* for getopt()       */
-
-#include "auth.h"
-#include "tmmhv2.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;
-  char 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, (octet_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;
-  octet_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, (octet_t *)msg_string, msg_len_octets, (octet_t *)result);
-  }
-  timer = clock() - timer;
-
-  free(msg_string);
-  free(result);
-  
-  return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer;
-}
-
-
diff --git a/test/cipher_driver.c b/test/cipher_driver.c
deleted file mode 100644
index b1aed21..0000000
--- a/test/cipher_driver.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * cipher_driver.c
- *
- * A driver for the generic cipher type
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <stdio.h>           /* for printf() */
-#include <stdlib.h>          /* for random() */
-#include <string.h>          /* for memset() */
-#include <unistd.h>          /* for getopt() */
-#include "cipher.h"
-#include "aes_icm.h"
-#include "null_cipher.h"
-
-#define PRINT_DEBUG 0
-
-void
-cipher_driver_test_throughput(cipher_t *c);
-
-err_status_t
-cipher_driver_self_test(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);
-
-
-/*
- * functions for testing cipher cache thrash
- */
-err_status_t
-cipher_driver_test_array_throughput(cipher_type_t *ct, 
-				    int klen, int num_cipher);
-
-void
-cipher_array_test_throughput(cipher_t *ca[], int num_cipher);
-
-double
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			     int octets_in_buffer, int num_trials);
-
-err_status_t
-cipher_array_delete(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);
-
-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;
-}
-
-/*
- * null_cipher and 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;
-
-int
-main(int argc, char *argv[]) {
-  cipher_t *c = NULL;
-  err_status_t status;
-  unsigned char test_key[20] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-    0x10, 0x11, 0x12, 0x13
-  };
-  char 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]);
-
-   /* 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); 
- 
-  }
-
-  if (do_validation) {
-    cipher_driver_self_test(&null_cipher);
-    cipher_driver_self_test(&aes_icm);
-  }
-
-  /* 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_any);
-  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 */
-    status = cipher_type_alloc(&aes_icm, &c, 30);  
-    if (status) {
-      fprintf(stderr, "error: can't allocate cipher\n");
-      exit(status);
-    }
-
-    status = cipher_init(c, test_key, direction_any);
-    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);
-  
-  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 = 100000;  
-  
-  printf("timing %s throughput:\n", c->type->description);
-  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);
-
-}
-
-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;
-}
-
-/*
- * 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, len, num_trials = 1000;
-  int buflen = 1024;
-  octet_t buffer0[buflen], buffer1[buflen], *current, *end;
-  octet_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);
-
-  for (i=0; i < num_trials; i++) {
-
-   /* 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;
-
-    /* generate 'reference' value by encrypting all at once */
-    status = cipher_encrypt(c, buffer0, &buflen);
-    if (status)
-      return status;
-
-    /* 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) {
-
-      /* choose a short length */
-      len = random() & 0x01f;
-
-      /* make sure that len doesn't cause us to overreach the buffer */
-      if (current + len > end)
-	len = end - current;
-
-      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 < 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");
-
-  return err_status_ok;
-}
-
-
-/*
- * The function cipher_test_throughput_array() tests the effect of CPU
- * cache thrash on cipher throughput.  
- *
- * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
- * of 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;
-  octet_t *key;
-  cipher_t **cipher_array;
-
-  /* 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;
-
-  /* set ca to location of cipher_array */
-  *ca = cipher_array;
-
-  /* allocate key */
-  key = crypto_alloc(klen);
-  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 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] = (octet_t) random();
-    status = cipher_init(*cipher_array, key, direction_any);
-    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++;
-  }
-
-  return 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]);
-  }
-
-  free(cipher_array);
-  
-  return 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.0 is returned
- */
-
-#include <time.h>
-
-double
-cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher, 
-			     int octets_in_buffer, int num_trials) {
-  int i;
-  v128_t nonce;
-  clock_t timer;
-  unsigned char *enc_buf;
-  int cipher_index = 0;
-
-
-  enc_buf = crypto_alloc(octets_in_buffer);
-  if (enc_buf == NULL)
-    return 0.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) {
-
-    /* choose a cipher at random from the array*/
-    cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
-
-    /* encrypt buffer with cipher */
-    cipher_set_iv(cipher_array[cipher_index], &nonce);
-    cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer);
-  }
-  timer = clock() - timer;
-
-  free(enc_buf);
-  
-  return (double) 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 = 10000;
-
-  printf("timing %s throughput with array size %d:\n", 
-	 (ca[0])->type->description, 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;
-
-  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;
-}
diff --git a/test/cutest.h b/test/cutest.h
new file mode 100644
index 0000000..f46626d
--- /dev/null
+++ b/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__ */
diff --git a/test/datatypes_driver.c b/test/datatypes_driver.c
deleted file mode 100644
index 1e315b6..0000000
--- a/test/datatypes_driver.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * datatypes_driver.c
- *
- * a test driver for crypto/math datatypes
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include <stdio.h>            /* for printf() */
-#include <string.h>           /* for strlen() */
-#include "datatypes.h"
-
-void
-byte_order();
-
-void
-test_hex_string_funcs();
-
-void
-print_string(octet_t *s);
-
-void
-test_bswap();
-
-int
-main () {
-  
-  /*
-   * 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;
-  octet_t *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.";
-  octet_t *s = "incomplet"; 
- 
-  print_string(r);
-  print_string(s);
- 
-  byte_order();
-  test_hex_string_funcs();
-
-  for (j=0; j < 128; j++) {
-    v128_set_to_zero(&x);
-    /*      x.v32[0] = (1 << j); */
-    v128_set_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    v128_clear_bit(&x, j);
-    printf("%s\n", v128_bit_string(&x)); 
-    
-  }
-
-  printf("----------------------------------------------\n");
-  v128_set_to_zero(&x);
-  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++) {
-    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();
-
-  return 0;
-}
-
-
-/* byte_order() prints out byte ordering of datatypes */
-
-void
-byte_order() {
-  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++)
-    c.octet[i] = i;
-  for (i=0; i < sizeof(d); i++)
-    d.octet[i] = i;
-  
-  printf("v128_t:\t%s\n", v128_hex_string(&e));
-  printf("v64_t:\t%s\n", v64_hex_string(&d));
-  printf("v32_t:\t%s\n", v32_hex_string(c));
-  printf("v16_t:\t%s\n", v16_hex_string(b));
-
-  c.value = 0x01020304;
-  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 
-
-  printf("byte ordering of crypto/math datatypes:\n");
-  for (i=0; i < sizeof(e); i++)
-    e.octet[i] = i;
-  printf("v128_t: %s\n", v128_hex_string(&e));
-  
-}
-
-void
-test_hex_string_funcs() {
-  octet_t hex1[] = "abadcafe";
-  octet_t hex2[] = "0123456789abcdefqqqqq";
-  octet_t 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));
-  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));
-  printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
-
-}
-
-void
-print_string(octet_t *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
-test_bswap() {
-  uint32_t x = 0x11223344;
-  uint64_t y = 0x1122334455667788LL;
-
-  printf("before: %0x\nafter:  %0x\n", x, bswap_32(x));
-  printf("before: %0llx\nafter:  %0llx\n", y, bswap_64(y));
-
-  y = 1234;
-
-  printf("1234: %0llx\n", y);
-  printf("as octet string: %s\n", 
-	 octet_string_hex_string((octet_t *) &y, 8));
-  y = bswap_64(y);
-  printf("bswapped octet string: %s\n", 
-	 octet_string_hex_string((octet_t *) &y, 8));
-
-}
diff --git a/test/dtls_srtp_driver.c b/test/dtls_srtp_driver.c
new file mode 100644
index 0000000..4f4d0a3
--- /dev/null
+++ b/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;
+}
diff --git a/test/getopt_s.c b/test/getopt_s.c
new file mode 100644
index 0000000..e0bd7f7
--- /dev/null
+++ b/test/getopt_s.c
@@ -0,0 +1,109 @@
+/*
+ * 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 GETOPT_NOT_FOUND;
+        }
+        max_string_len--;
+        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;
+}
diff --git a/test/kernel_driver.c b/test/kernel_driver.c
deleted file mode 100644
index d26d4c5..0000000
--- a/test/kernel_driver.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * kernel_driver.c
- *
- * a test driver for the crypto_kernel
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-/*
- *	
- * Copyright(c) 2001-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include <stdio.h>           /* for printf() */
-#include <unistd.h>          /* for getopt() */
-#include "crypto_kernel.h"
-
-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;
-  char q;
-  int do_validation      = 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);
-  }
-  printf("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]);
-    }    
-  }
-
-  if (do_validation) {
-    printf("checking crypto_kernel status...\n");
-    status = crypto_kernel_status();
-    if (status) {
-      printf("failed\n");
-      exit(1);
-    }
-    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;
-}
-
-/*
- * crypto_kernel_cipher_test() is a test of the cipher interface
- * of the crypto_kernel
- */
-
-err_status_t
-crypto_kernel_cipher_test() {
-
-  /* not implemented yet! */
-
-  return err_status_ok;
-}
diff --git a/test/lfsr.c b/test/lfsr.c
deleted file mode 100644
index 28ea02e..0000000
--- a/test/lfsr.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * lfsr.c
- *
- */
-
-
-#include <stdio.h>
-#include "datatypes.h"
-
-uint32_t 
-parity(uint32_t x) {
-
-  x ^= (x >> 16);
-  x ^= (x >> 8);
-  x ^= (x >> 4);
-  x ^= (x >> 2);
-  x ^= (x >> 1);
-
-  return x & 1;
-}
-
-
-/* typedef struct { */
-/*   uint32_t register[8]; */
-/* } lfsr_t; */
-
-void
-compute_period(uint32_t feedback_polynomial) {
-  int i;
-  v32_t lfsr;
-  v32_t mask;
-
-  mask.value = feedback_polynomial;
-  lfsr.value = 1;
-
-  printf("polynomial: %s\t", v32_bit_string(mask));
-
-  for (i=0; i < 256; i++) {
-/*     printf("%s\n", v32_bit_string(lfsr)); */
-    if (parity(mask.value & lfsr.value))
-      lfsr.value = ((lfsr.value << 1) | 1) & 0xff;
-    else
-      lfsr.value = (lfsr.value << 1) & 0xff;
-    
-    /* now halt if we're back at the initial state */
-    if (lfsr.value == 1) {
-      printf("period: %d\n", i);
-      break;
-    }
-  }
-}
-
-uint32_t poly0 = 223;
-
-
-uint32_t polynomials[39] = {
-31, 
-47,
-55,
-59,
-61,
-79,
-87,
-91,
-103,
-107,
-109,
-115,
-117,
-121,
-143,
-151,
-157,
-167,
-171,
-173,
-179,
-181,
-185,
-199,
-203,
-205,
-211,
-213,
-227,
-229,
-233, 
-241,
-127,
-191,
-223, 
-239,
-247,
-251,
-253 
-};
-
-char binary_string[32];
-
-char *
-u32_bit_string(uint32_t x, unsigned int length) {
-  unsigned int mask;
-  int index;
- 
-  mask = 1 << length;
-  index = 0;
-  for (; mask > 0; mask >>= 1)
-    if ((x & mask) == 0)
-      binary_string[index++] = '0';
-    else
-      binary_string[index++] = '1';
-
-  binary_string[index++] = 0;  /* NULL terminate string */
-  return binary_string;
-}
-
-extern int octet_weight[256];
-
-unsigned int 
-weight(uint32_t poly) {
-  int wt = 0;
-
-  /* note: endian-ness makes no difference */
-  wt += octet_weight[poly        & 0xff]; 
-  wt += octet_weight[(poly >> 8) & 0xff];
-  wt += octet_weight[(poly >> 16) & 0xff];
-  wt += octet_weight[(poly >> 24)];
-
-  return wt;
-}
-
-#define MAX_PERIOD 65535
-
-#define debug_print 0
-
-int
-period(uint32_t poly) {
-  int i;
-  uint32_t x;
-
-
-  /* set lfsr to 1 */
-  x = 1;
-#if debug_print
-  printf("%d:\t%s\n", 0, u32_bit_string(x,8));
-#endif
-  for (i=1; i < MAX_PERIOD; i++) {
-    if (x & 1) 
-      x = (x >> 1) ^ poly;
-    else
-      x = (x >> 1);
-
-#if debug_print
-    /* print for a sanity check */
-    printf("%d:\t%s\n", i, u32_bit_string(x,8));
-#endif
-
-    /* check for return to original value */
-    if (x == 1)
-      return i;
-  }
-  return i;
-}
-
-/*
- * weight distribution computes the weight distribution of the
- * code generated by the polynomial poly
- */
-
-#define MAX_LEN    8
-#define MAX_WEIGHT (1 << MAX_LEN)
-
-int A[MAX_WEIGHT+1];
-
-void
-weight_distribution2(uint32_t poly, int *A) {
-  int i;
-  uint32_t x;
-
-  /* zeroize array */
-  for (i=0; i < MAX_WEIGHT+1; i++)
-    A[i] = 0;
-
-  /* loop over all input sequences */
-  
-  
-  /* set lfsr to 1 */
-  x = 1;
-#if debug_print
-  printf("%d:\t%s\n", 0, u32_bit_string(x,8));
-#endif
-  for (i=1; i < MAX_PERIOD; i++) {
-    if (x & 1) 
-      x = (x >> 1) ^ poly;
-    else
-      x = (x >> 1);
-
-#if debug_print
-    /* print for a sanity check */
-    printf("%d:\t%s\n", i, u32_bit_string(x,8));
-#endif
-    
-    /* increment weight */
-    wt += (x & 1);
-
-    /* check for return to original value */
-    if (x == 1)
-      break;
-  }
-
-  /* set zero */
-  A[0] = 0;
-}
-
-
-void
-weight_distribution(uint32_t poly, int *A) {
-  int i;
-  uint32_t x;
-
-  /* zeroize array */
-  for (i=0; i < MAX_WEIGHT+1; i++)
-    A[i] = 0;
-
-  /* set lfsr to 1 */
-  x = 1;
-#if debug_print
-  printf("%d:\t%s\n", 0, u32_bit_string(x,8));
-#endif
-  for (i=1; i < MAX_PERIOD; i++) {
-    if (x & 1) 
-      x = (x >> 1) ^ poly;
-    else
-      x = (x >> 1);
-
-#if debug_print
-    /* print for a sanity check */
-    printf("%d:\t%s\n", i, u32_bit_string(x,8));
-#endif
-
-    /* compute weight, increment proper element */
-    A[weight(x)]++;
-
-    /* check for return to original value */
-    if (x == 1)
-      break;
-  }
-
-  /* set zero */
-  A[0] = 0;
-}
-
-
-
-
-int
-main () {
-
-  int i,j;
-  v32_t x;
-  v32_t p;
-
-  /* originally 0xaf */
-  p.value = 0x9;
-
-  printf("polynomial: %s\tperiod: %d\n",  
- 	   u32_bit_string(p.value,8), period(p.value)); 
- 
-   /* compute weight distribution */
-  weight_distribution(p.value, A);
-  
-  /* print weight distribution */
-  for (i=0; i <= 8; i++) {
-    printf("A[%d]: %d\n", i, A[i]);
-  }
-  
-#if 0
-  for (i=0; i < 39; i++) {
-     printf("polynomial: %s\tperiod: %d\n",  
- 	   u32_bit_string(polynomials[i],8), period(polynomials[i])); 
-   
-     /* compute weight distribution */
-     weight_distribution(p.value, A);
-     
-     /* print weight distribution */
-     for (j=0; j <= 8; j++) {
-       printf("A[%d]: %d\n", j, A[j]);
-     }   
-  }
-#endif
-
-  { 
-    int bits = 8;
-    uint32_t y;
-    for (y=0; y < (1 << bits); y++) {
-      printf("polynomial: %s\tweight: %d\tperiod: %d\n", 
-	     u32_bit_string(y,bits), weight(y), period(y));
-      
-      /* compute weight distribution */
-      weight_distribution(y, A);
-      
-      /* print weight distribution */
-      for (j=0; j <= 8; j++) {
-	printf("A[%d]: %d\n", j, A[j]);
-      }     
-    }
-  }
-
-  return 0;
-}
diff --git a/test/rand_gen.c b/test/rand_gen.c
deleted file mode 100644
index c8fc4f3..0000000
--- a/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-2005 Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#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;
-  char 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) {
-    octet_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;
-}
-
diff --git a/test/rdbx_driver.c b/test/rdbx_driver.c
index 36639ea..df434a0 100644
--- a/test/rdbx_driver.c
+++ b/test/rdbx_driver.c
@@ -6,28 +6,27 @@
  * David A. 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
@@ -43,264 +42,319 @@
  *
  */
 
-#include <stdio.h>        /* for printf() */
-#include <unistd.h>       /* for getopt() */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>    /* for printf()          */
+#include "getopt_s.h" /* for local getopt()    */
 
 #include "rdbx.h"
+#include "cipher_priv.h"
 
 #ifdef ROC_TEST
-#error "rdbx_t won't work with ROC_TEST - bitmask same size as seq_median"
+#error "srtp_rdbx_t won't work with ROC_TEST - bitmask same size as seq_median"
 #endif
 
 #include "ut_sim.h"
 
-err_status_t 
-test_replay_dbx(int num_trials);
+srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws);
 
-double
-rdbx_check_adds_per_second(int num_trials);
+double rdbx_check_adds_per_second(int num_trials, unsigned long ws);
 
-void
-usage(char *prog_name) {
-  printf("usage: %s [ -t | -v ]\n", prog_name);
-  exit(255);
+void usage(char *prog_name)
+{
+    printf("usage: %s [ -t | -v ]\n", prog_name);
+    exit(255);
 }
 
-int
-main (int argc, char *argv[]) {
-  double rate;
-  err_status_t status;
-  char q;
-  unsigned do_timing_test = 0;
-  unsigned do_validation = 0;
+int main(int argc, char *argv[])
+{
+    double rate;
+    srtp_err_status_t status;
+    int q;
+    unsigned do_timing_test = 0;
+    unsigned do_validation = 0;
 
-  /* process input arguments */
-  while (1) {
-    q = getopt(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 rdbx_t...\n");
-
-    status = test_replay_dbx(1 << 12);
-    if (status) {
-      printf("failed\n");
-      exit(1);
+    /* process input arguments */
+    while (1) {
+        q = getopt_s(argc, argv, "tv");
+        if (q == -1)
+            break;
+        switch (q) {
+        case 't':
+            do_timing_test = 1;
+            break;
+        case 'v':
+            do_validation = 1;
+            break;
+        default:
+            usage(argv[0]);
+        }
     }
-    printf("passed\n");
-  }
 
-  if (do_timing_test) {
-    rate = rdbx_check_adds_per_second(1 << 18);
-    printf("rdbx_check/replay_adds per second: %e\n", rate);
-  }
-  
-  return 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(rdbx_t *rdbx) {
-  printf("rdbx: {%llu, %s}\n",
-	 (rdbx->index), v128_bit_string(&rdbx->bitmask));
+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
- * err_status_algo_fail is returned.
+ * srtp_err_status_algo_fail is returned.
  *
  */
 
-err_status_t
-rdbx_check_add(rdbx_t *rdbx, uint32_t idx) {
-  int delta;
-  xtd_seq_num_t est;
-  
-  delta = index_guess(&rdbx->index, &est, idx);
-  
-  if (rdbx_check(rdbx, delta) != err_status_ok) {
-    printf("replay_check failed at index %u\n", idx);
-    return err_status_algo_fail;
-  }
+srtp_err_status_t rdbx_check_add(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
 
-  /*
-   * in practice, we'd authenticate the packet containing idx, using
-   * the estimated value est, at this point
-   */
-  
-  if (rdbx_add_index(rdbx, delta) != err_status_ok) {
-    printf("rdbx_add_index failed at index %u\n", idx);
-    return err_status_algo_fail;
-  }  
+    delta = srtp_index_guess(&rdbx->index, &est, idx);
 
-  return err_status_ok;
+    if (srtp_rdbx_check(rdbx, delta) != srtp_err_status_ok) {
+        printf("replay_check failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    /*
+     * in practice, we'd authenticate the packet containing idx, using
+     * the estimated value est, at this point
+     */
+
+    if (srtp_rdbx_add_index(rdbx, delta) != srtp_err_status_ok) {
+        printf("rdbx_add_index failed at index %u\n", idx);
+        return srtp_err_status_algo_fail;
+    }
+
+    return srtp_err_status_ok;
 }
 
 /*
- * rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx)
- * 
+ * 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
  */
 
-err_status_t
-rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) {
-  int delta;
-  xtd_seq_num_t est;
-  err_status_t status;
+srtp_err_status_t rdbx_check_expect_failure(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
+    srtp_err_status_t status;
 
-  delta = index_guess(&rdbx->index, &est, idx);
+    delta = srtp_index_guess(&rdbx->index, &est, idx);
 
-  status = rdbx_check(rdbx, delta);
-  if (status == err_status_ok) {
-    printf("delta: %d ", delta);
-    printf("replay_check failed at index %u (false positive)\n", idx);
-    return err_status_algo_fail; 
-  }
+    status = srtp_rdbx_check(rdbx, delta);
+    if (status == srtp_err_status_ok) {
+        printf("delta: %d ", delta);
+        printf("replay_check failed at index %u (false positive)\n", idx);
+        return srtp_err_status_algo_fail;
+    }
 
-  return err_status_ok;
+    return srtp_err_status_ok;
 }
 
-err_status_t
-rdbx_check_unordered(rdbx_t *rdbx, uint32_t idx) {
-  err_status_t rstat;
+srtp_err_status_t rdbx_check_add_unordered(srtp_rdbx_t *rdbx, uint32_t idx)
+{
+    int delta;
+    srtp_xtd_seq_num_t est;
+    srtp_err_status_t rstat;
 
-  rstat = rdbx_check(rdbx, idx);
-  if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
-    printf("replay_check_unordered failed at index %u\n", idx);
-    return err_status_algo_fail;
-  }
-  return err_status_ok;
+    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;
 }
 
-#define MAX_IDX 160
+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;
 
-err_status_t
-test_replay_dbx(int num_trials) {
-  rdbx_t rdbx;
-  uint32_t idx, ircvd;
-  ut_connection utc;
-  err_status_t status;
-  int num_fp_trials;
+    status = srtp_rdbx_init(&rdbx, ws);
+    if (status) {
+        printf("replay_init failed with error code %d\n", status);
+        exit(1);
+    }
 
-  status = rdbx_init(&rdbx);
-  if (status) {
-    printf("replay_init failed with error code %d\n", status);
-    exit(1);
-  }
+    /*
+     *  test sequential insertion
+     */
+    printf("\ttesting sequential insertion...");
+    for (idx = 0; (int)idx < num_trials; idx++) {
+        status = rdbx_check_add(&rdbx, idx);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
 
-  /*
-   *  test sequential insertion 
-   */
-  printf("\ttesting sequential insertion...");
-  for (idx=0; idx < num_trials; idx++) {
-    status = rdbx_check_add(&rdbx, idx);
-    if (status)
-      return status;
-  }
-  printf("passed\n");
+    /*
+     *  test for false positives by checking all of the index
+     *  values which we've just added
+     *
+     * note that we limit the number of trials here, since allowing the
+     * rollover counter to roll over would defeat this test
+     */
+    num_fp_trials = num_trials % 0x10000;
+    if (num_fp_trials == 0) {
+        printf("warning: no false positive tests performed\n");
+    }
+    printf("\ttesting for false positives...");
+    for (idx = 0; (int)idx < num_fp_trials; idx++) {
+        status = rdbx_check_expect_failure(&rdbx, idx);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
 
-  /*
-   *  test for false positives by checking all of the index
-   *  values which we've just added
-   *
-   * note that we limit the number of trials here, since allowing the
-   * rollover counter to roll over would defeat this test
-   */
-  num_fp_trials = num_trials % 0x10000;
-  if (num_fp_trials == 0) {
-    printf("warning: no false positive tests performed\n");
-  }
-  printf("\ttesting for false positives...");
-  for (idx=0; idx < num_fp_trials; idx++) {
-    status = rdbx_check_expect_failure(&rdbx, idx);
-    if (status)
-      return status;
-  }
-  printf("passed\n");
+    /* re-initialize */
+    srtp_rdbx_dealloc(&rdbx);
 
-  /* re-initialize */
-  if (rdbx_init(&rdbx) != err_status_ok) {
-    printf("replay_init failed\n");
-    return err_status_init_fail;
-  }
+    if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
+        printf("replay_init failed\n");
+        return srtp_err_status_init_fail;
+    }
 
-  /*
-   * test non-sequential insertion 
-   *
-   * this test covers only fase negatives, since the values returned
-   * by ut_next_index(...) are distinct
-   */
-  ut_init(&utc);
+    /*
+     * test non-sequential insertion
+     *
+     * this test covers only fase negatives, since the values returned
+     * by ut_next_index(...) are distinct
+     */
+    ut_init(&utc);
 
-  printf("\ttesting non-sequential insertion...");  
-  for (idx=0; idx < num_trials; idx++) {
-    ircvd = ut_next_index(&utc);
-    status = rdbx_check_unordered(&rdbx, ircvd);
-    if (status)
-      return status;
-  }
-  printf("passed\n");
+    printf("\ttesting non-sequential insertion...");
+    for (idx = 0; (int)idx < num_trials; idx++) {
+        ircvd = ut_next_index(&utc);
+        status = rdbx_check_add_unordered(&rdbx, ircvd);
+        if (status)
+            return status;
+        status = rdbx_check_expect_failure(&rdbx, ircvd);
+        if (status)
+            return status;
+    }
+    printf("passed\n");
 
-  return err_status_ok;
+    /* 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 << (srtp_cipher_rand_u32_for_tests() % 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()  */
 
+double rdbx_check_adds_per_second(int num_trials, unsigned long ws)
+{
+    uint32_t i;
+    int delta;
+    srtp_rdbx_t rdbx;
+    srtp_xtd_seq_num_t est;
+    clock_t timer;
+    int failures; /* count number of failures */
 
-#include <time.h>       /* for clock()  */
-#include <stdlib.h>     /* for random() */
+    if (srtp_rdbx_init(&rdbx, ws) != srtp_err_status_ok) {
+        printf("replay_init failed\n");
+        exit(1);
+    }
 
-double
-rdbx_check_adds_per_second(int num_trials) {
-  uint32_t i;
-  int delta;
-  rdbx_t rdbx;
-  xtd_seq_num_t est;
-  clock_t timer;
-  int failures;                    /* count number of failures        */
-  
-  if (rdbx_init(&rdbx) != err_status_ok) {
-    printf("replay_init failed\n");
-    exit(1);
-  }  
+    failures = 0;
+    timer = clock();
+    for (i = 0; (int)i < num_trials; i++) {
+        delta = srtp_index_guess(&rdbx.index, &est, i);
 
-  failures = 0;
-  timer = clock();
-  for(i=0; i < num_trials; i++) {
-    
-    delta = index_guess(&rdbx.index, &est, i);
-    
-    if (rdbx_check(&rdbx, delta) != err_status_ok) 
-      ++failures;
-    else
-      if (rdbx_add_index(&rdbx, delta) != err_status_ok)
-	++failures;
-  }
-  timer = clock() - timer;
+        if (srtp_rdbx_check(&rdbx, delta) != srtp_err_status_ok)
+            ++failures;
+        else if (srtp_rdbx_add_index(&rdbx, delta) != srtp_err_status_ok)
+            ++failures;
+    }
+    timer = clock() - timer;
+    if (timer < 1) {
+        timer = 1;
+    }
 
-  printf("number of failures: %d \n", failures);
+    printf("number of failures: %d \n", failures);
 
-  return (double) CLOCKS_PER_SEC * num_trials / timer;
+    srtp_rdbx_dealloc(&rdbx);
+
+    return (double)CLOCKS_PER_SEC * num_trials / timer;
 }
-
diff --git a/test/replay_driver.c b/test/replay_driver.c
index dc403b1..e0808b6 100644
--- a/test/replay_driver.c
+++ b/test/replay_driver.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,139 +43,243 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 
 #include "rdb.h"
 #include "ut_sim.h"
 
-void
-test_rdb_db();
+#include "cipher_priv.h"
 
-double
-rdb_check_adds_per_second();
+/*
+ * num_trials defines the number of trials that are used in the
+ * validation functions below
+ */
 
-int
-main () {
+unsigned num_trials = 1 << 16;
 
-  printf("testing anti-replay database (rdb_t)...\n");
-  test_rdb_db();
-  printf("done\n");
+srtp_err_status_t test_rdb_db(void);
 
-  printf("rdb_check/rdb_adds per second: %e\n",
-	 rdb_check_adds_per_second());
-  
-  return 0;
+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(rdb_t *rdb) {
-  printf("rdb: {%u, %s}\n", rdb->window_start, 
-	 v128_bit_string(&rdb->bitmask));
+void print_rdb(srtp_rdb_t *rdb)
+{
+    printf("rdb: {%u, %s}\n", rdb->window_start,
+           v128_bit_string(&rdb->bitmask));
 }
 
-void
-rdb_check_add(rdb_t *rdb, uint32_t idx) {
+srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx)
+{
+    if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) {
+        printf("rdb_check failed at index %u\n", idx);
+        return srtp_err_status_fail;
+    }
+    if (srtp_rdb_add_index(rdb, idx) != srtp_err_status_ok) {
+        printf("rdb_add_index failed at index %u\n", idx);
+        return srtp_err_status_fail;
+    }
 
-  if (rdb_check(rdb, idx) != err_status_ok) {
-    printf("rdb_check failed at index %u\n", idx);
-    return;
-  }
-  if (rdb_add_index(rdb, idx) != err_status_ok)
-    printf("rdb_add_index failed at index %u\n", idx);
-
+    return srtp_err_status_ok;
 }
 
-void
-rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) {
+srtp_err_status_t rdb_check_expect_failure(srtp_rdb_t *rdb, uint32_t idx)
+{
+    srtp_err_status_t err;
 
-  if (rdb_check(rdb, idx) != err_status_fail)
-    printf("rdb_check failed at index %u (false positive)\n", idx);
+    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;
 }
 
-void
-rdb_check_unordered(rdb_t *rdb, uint32_t idx) {
-  err_status_t rstat;
+srtp_err_status_t rdb_check_add_unordered(srtp_rdb_t *rdb, uint32_t idx)
+{
+    srtp_err_status_t rstat;
 
-  rstat = rdb_check(rdb, idx);
-  if ((rstat != err_status_ok) && (rstat != err_status_replay_old))
-    printf("rdb_check_unordered failed at index %u\n", idx);
+    /* 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;
+    }
 
-#define MAX_IDX 160
+    /* test sequential insertion */
+    for (idx = 0; idx < num_trials; idx++) {
+        err = rdb_check_add(&rdb, idx);
+        if (err)
+            return err;
+    }
 
-void
-test_rdb_db() {
-  rdb_t rdb;
-  uint32_t idx, ircvd;
-  ut_connection utc;
-  
-  if (rdb_init(&rdb) != err_status_ok) {
-    printf("rdb_init failed\n");
-    exit(1);
-  }
+    /* test for false positives */
+    for (idx = 0; idx < num_trials; idx++) {
+        err = rdb_check_expect_failure(&rdb, idx);
+        if (err)
+            return err;
+    }
 
-  /* test sequential insertion */
-  for (idx=0; idx < MAX_IDX; idx++) {
-    rdb_check_add(&rdb, idx);
-  }
+    /* re-initialize */
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        return srtp_err_status_fail;
+    }
 
-  /* test for false positives */
-  for (idx=0; idx < MAX_IDX; idx++) {
-    rdb_check_expect_failure(&rdb, idx);
-  }
+    /* test non-sequential insertion */
+    ut_init(&utc);
 
-  /* re-initialize */
-  if (rdb_init(&rdb) != err_status_ok) {
-    printf("rdb_init failed\n");
-    exit(1);
-  }
+    for (idx = 0; idx < num_trials; idx++) {
+        ircvd = ut_next_index(&utc);
+        err = rdb_check_add_unordered(&rdb, ircvd);
+        if (err)
+            return err;
+        err = rdb_check_expect_failure(&rdb, ircvd);
+        if (err)
+            return err;
+    }
 
-  /* test non-sequential insertion */
-  ut_init(&utc);
-  
-  for (idx=0; idx < MAX_IDX; idx++) {
-    ircvd = ut_next_index(&utc);
-    rdb_check_unordered(&rdb, ircvd);
-  }
-  
+    /* 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 << (srtp_cipher_rand_u32_for_tests() % 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() */
+#include <time.h>   /* for clock()  */
+#include <stdlib.h> /* for random() */
 
 #define REPLAY_NUM_TRIALS 10000000
 
-double
-rdb_check_adds_per_second() {
-  uint32_t i;
-  rdb_t rdb;
-  clock_t timer;
-  int failures;                    /* count number of failures        */
-  
-  if (rdb_init(&rdb) != err_status_ok) {
-    printf("rdb_init failed\n");
-    exit(1);
-  }  
+double rdb_check_adds_per_second(void)
+{
+    uint32_t i;
+    srtp_rdb_t rdb;
+    clock_t timer;
+    int failures = 0; /* count number of failures        */
 
-  timer = clock();
-  for(i=0; i < REPLAY_NUM_TRIALS; i+=3) {
-    if (rdb_check(&rdb, i+2) != err_status_ok)
-      ++failures;
-    if (rdb_add_index(&rdb, i+2) != err_status_ok)
-      ++failures;
-    if (rdb_check(&rdb, i+1) != err_status_ok)
-      ++failures;
-    if (rdb_add_index(&rdb, i+1) != err_status_ok)
-      ++failures;
-    if (rdb_check(&rdb, i) != err_status_ok)
-      ++failures;
-    if (rdb_add_index(&rdb, i) != err_status_ok)
-      ++failures;
-  }
-  timer = clock() - timer;
+    if (srtp_rdb_init(&rdb) != srtp_err_status_ok) {
+        printf("rdb_init failed\n");
+        exit(1);
+    }
 
-  return (double) CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
+    timer = clock();
+    for (i = 0; i < REPLAY_NUM_TRIALS; i += 3) {
+        if (srtp_rdb_check(&rdb, i + 2) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i + 2) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_check(&rdb, i + 1) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i + 1) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_check(&rdb, i) != srtp_err_status_ok)
+            ++failures;
+        if (srtp_rdb_add_index(&rdb, i) != srtp_err_status_ok)
+            ++failures;
+    }
+    timer = clock() - timer;
+
+    return (double)CLOCKS_PER_SEC * REPLAY_NUM_TRIALS / timer;
 }
diff --git a/test/roc_driver.c b/test/roc_driver.c
index 10e5488..4398620 100644
--- a/test/roc_driver.c
+++ b/test/roc_driver.c
@@ -8,26 +8,26 @@
  */
 
 /*
- *	
- * 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
@@ -43,123 +43,128 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdio.h>
 
 /*
  * defining ROC_TEST causes small datatypes to be used in
- * xtd_seq_num_t - this allows the functions to be exhaustively tested.
+ * srtp_xtd_seq_num_t - this allows the functions to be exhaustively tested.
  */
 #if ROC_NEEDS_TO_BE_TESTED
-#define ROC_TEST     
+#define ROC_TEST
 #endif
 
 #include "rdbx.h"
 #include "ut_sim.h"
 
-err_status_t
-roc_test(int num_trials);
+srtp_err_status_t roc_test(int num_trials);
 
-int
-main () {
-  err_status_t status;
+int main(void)
+{
+    srtp_err_status_t status;
 
-  printf("rollover counter test driver\n"
-	 "David A. McGrew\n"
-	 "Cisco Systems, Inc.\n");
-  
-  printf("testing index functions...");
-  status = roc_test(1 << 18);
-  if (status) {
-    printf("failed\n");
-    exit(status);
-  }
-  printf("passed\n");
-  return 0;
+    printf("rollover counter test driver\n"
+           "David A. McGrew\n"
+           "Cisco Systems, Inc.\n");
+
+    printf("testing index functions...");
+    status = roc_test(1 << 18);
+    if (status) {
+        printf("failed\n");
+        exit(status);
+    }
+    printf("passed\n");
+    return 0;
 }
 
-
 #define ROC_VERBOSE 0
 
-err_status_t
-roc_test(int num_trials) {
-  xtd_seq_num_t local, est, ref;
-  ut_connection utc;
-  int i, num_bad_est = 0;
-  int delta;
-  uint32_t ircvd;
-  double failure_rate;
+srtp_err_status_t roc_test(int num_trials)
+{
+    srtp_xtd_seq_num_t local, est, ref;
+    ut_connection utc;
+    int i, num_bad_est = 0;
+    int delta;
+    uint32_t ircvd;
+    double failure_rate;
 
-  index_init(&local);
-  index_init(&ref);
-  index_init(&est);
+    srtp_index_init(&local);
+    srtp_index_init(&ref);
+    srtp_index_init(&est);
 
-  printf("\n\ttesting sequential insertion...");
-  for (i=0; i < 2048; i++) {
-    delta = index_guess(&local, &est, (uint16_t) ref);
+    printf("\n\ttesting sequential insertion...");
+    for (i = 0; i < 2048; i++) {
+        srtp_index_guess(&local, &est, (uint16_t)ref);
 #if ROC_VERBOSE
-    printf("%lld, %lld, %d\n", ref, est,  i);
+        printf("%lld, %lld, %d\n", ref, est, i);
 #endif
-    if (ref != est) {
+        if (ref != est) {
 #if ROC_VERBOSE
-      printf(" *bad estimate*\n");
+            printf(" *bad estimate*\n");
 #endif
-      ++num_bad_est;
+            ++num_bad_est;
+        }
+        srtp_index_advance(&ref, 1);
     }
-    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 err_status_algo_fail;
-  }
-  printf("done\n");
-
-
-  printf("\ttesting non-sequential insertion...");
-  index_init(&local);
-  index_init(&ref);
-  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 = 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
-    
-    /* now update local xtd_seq_num_t as necessary */
-    if (delta > 0) 
-      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;
     }
-  }
-  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 err_status_algo_fail;
-  }
-  printf("done\n");
+    printf("done\n");
 
-  return err_status_ok;
+    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;
 }
diff --git a/test/rtp.c b/test/rtp.c
index 94628e1..70248ee 100644
--- a/test/rtp.c
+++ b/test/rtp.c
@@ -7,6 +7,41 @@
  * 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"
 
@@ -14,139 +49,181 @@
 #include <string.h>
 
 #include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-
-#define PRINT_DEBUG    0    /* set to 1 to print out debugging data */
-#define VERBOSE_DEBUG  0    /* set to 1 to print out more data      */
-
-ssize_t
-rtp_sendto(rtp_sender_t *sender, const void* msg, int len) {
-  int octets_sent;
-  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;
-  }
+
+#include "cipher_priv.h"
+
+#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);
+    srtp_print_packet(&sender->message.header, pkt_len);
 #endif
-  octets_sent = sendto(sender->socket, &sender->message,
-		       pkt_len, 0, (struct sockaddr *)&sender->addr,
-		       sizeof (struct sockaddr_in));
+    octets_sent =
+        sendto(sender->socket, (void *)&sender->message, pkt_len, 0,
+               (struct sockaddr *)&sender->addr, sizeof(struct sockaddr_in));
 
-  if (octets_sent != pkt_len) {
+    if (octets_sent != pkt_len) {
 #if PRINT_DEBUG
-    fprintf(stderr, "error: couldn't send message %s", (char *)msg);
-    perror("");
+        fprintf(stderr, "error: couldn't send message %s", (char *)msg);
+        perror("");
 #endif
-  }
+    }
 
-  return octets_sent;
+    return octets_sent;
 }
 
-ssize_t
-rtp_recvfrom(rtp_receiver_t *receiver, void *msg, int *len) {
-  int octets_recvd;
-  err_status_t stat;
-  
-  octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
-			 *len, 0, (struct sockaddr *) NULL, 0);
+int rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len)
+{
+    int octets_recvd;
+    srtp_err_status_t stat;
 
-  /* verify rtp header */
-  if (receiver->message.header.version != 2) {
-    *len = 0;
-    return -1;
-  }
+    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",
-	  octets_recvd, receiver->message.header.ssrc);
+    fprintf(stderr, "%d octets received from SSRC %u\n", octets_recvd,
+            receiver->message.header.ssrc);
 #endif
 #if VERBOSE_DEBUG
-  srtp_print_packet(&receiver->message.header, octets_recvd);
+    srtp_print_packet(&receiver->message.header, octets_recvd);
 #endif
 
-  /* apply srtp */
-  stat = srtp_unprotect(receiver->srtp_ctx,
-			&receiver->message.header, &octets_recvd);
-  if (stat) {
-#if PRINT_DEBUG
-    fprintf(stderr,
-	    "\nerror: srtp unprotection failed with code %d", stat);
-    if (stat == err_status_replay_fail)
-      fprintf(stderr, " (replay check failed)\n");
-    if (stat == err_status_auth_fail)
-      fprintf(stderr, " (auth check failed)\n"); 
-#endif
-    return -1;
-  }
-  strncpy(msg, receiver->message.body, octets_recvd);
-  
-  return octets_recvd;
+    /* apply srtp */
+    stat = srtp_unprotect(receiver->srtp_ctx, &receiver->message.header,
+                          &octets_recvd);
+    if (stat) {
+        fprintf(stderr, "error: srtp unprotection failed with code %d%s\n",
+                stat,
+                stat == srtp_err_status_replay_fail
+                    ? " (replay check failed)"
+                    : stat == srtp_err_status_auth_fail ? " (auth check failed)"
+                                                        : "");
+        return -1;
+    }
+    strncpy(msg, receiver->message.body, octets_recvd);
+
+    return octets_recvd;
 }
 
-int
-rtp_sender_init(rtp_sender_t *sender, 
-		int socket, 
-		struct sockaddr_in addr,
-		uint32_t ssrc) {
+int rtp_sender_init(rtp_sender_t sender,
+                    int sock,
+                    struct sockaddr_in addr,
+                    unsigned int ssrc)
+{
+    /* set header values */
+    sender->message.header.ssrc = htonl(ssrc);
+    sender->message.header.ts = 0;
+    sender->message.header.seq = (uint16_t)srtp_cipher_rand_u32_for_tests();
+    sender->message.header.m = 0;
+    sender->message.header.pt = 0x1;
+    sender->message.header.version = 2;
+    sender->message.header.p = 0;
+    sender->message.header.x = 0;
+    sender->message.header.cc = 0;
 
-  /* set header values */
-  sender->message.header.ssrc    = htonl(ssrc);
-  sender->message.header.ts      = 0;
-  sender->message.header.seq     = (uint16_t) random();
-  sender->message.header.m       = 0;
-  sender->message.header.pt      = 0x8f;
-  sender->message.header.version = 2;
-  sender->message.header.p       = 0;
-  sender->message.header.x       = 0;
-  sender->message.header.cc      = 0;
+    /* set other stuff */
+    sender->socket = sock;
+    sender->addr = addr;
 
-  /* set other stuff */
-  sender->socket = socket;
-  sender->addr = addr;
-
-  return 0;
+    return 0;
 }
 
-int
-rtp_receiver_init(rtp_receiver_t *rcvr, 
-		  int socket, 
-		  struct sockaddr_in addr,
-		  uint32_t 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      = 0x8f;
-  rcvr->message.header.version = 2;
-  rcvr->message.header.p       = 0;
-  rcvr->message.header.x       = 0;
-  rcvr->message.header.cc      = 0;
+int rtp_receiver_init(rtp_receiver_t rcvr,
+                      int sock,
+                      struct sockaddr_in addr,
+                      unsigned int ssrc)
+{
+    /* set header values */
+    rcvr->message.header.ssrc = htonl(ssrc);
+    rcvr->message.header.ts = 0;
+    rcvr->message.header.seq = 0;
+    rcvr->message.header.m = 0;
+    rcvr->message.header.pt = 0x1;
+    rcvr->message.header.version = 2;
+    rcvr->message.header.p = 0;
+    rcvr->message.header.x = 0;
+    rcvr->message.header.cc = 0;
 
-  /* set other stuff */
-  rcvr->socket = socket;
-  rcvr->addr = addr;
+    /* set other stuff */
+    rcvr->socket = sock;
+    rcvr->addr = addr;
 
-  return 0;
+    return 0;
 }
 
+int rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy)
+{
+    return srtp_create(&sender->srtp_ctx, policy);
+}
 
+int rtp_sender_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);
+}
diff --git a/test/rtp.h b/test/rtp.h
new file mode 100644
index 0000000..37921a6
--- /dev/null
+++ b/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 */
diff --git a/test/rtp_decoder.c b/test/rtp_decoder.c
new file mode 100644
index 0000000..6f4ed04
--- /dev/null
+++ b/test/rtp_decoder.c
@@ -0,0 +1,764 @@
+/*
+ * 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 gcm_on;
+    int key_size;
+    int tag_size;
+};
+
+static struct srtp_crypto_suite srtp_crypto_suites[] = {
+#if 0
+  {.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
+#endif
+    {.can_name = "AES_CM_128_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 128,
+     .tag_size = 4 },
+    {.can_name = "AES_CM_128_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 128,
+     .tag_size = 10 },
+    {.can_name = "AES_192_CM_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 192,
+     .tag_size = 4 },
+    {.can_name = "AES_192_CM_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 192,
+     .tag_size = 10 },
+    {.can_name = "AES_256_CM_HMAC_SHA1_32",
+     .gcm_on = 0,
+     .key_size = 256,
+     .tag_size = 4 },
+    {.can_name = "AES_256_CM_HMAC_SHA1_80",
+     .gcm_on = 0,
+     .key_size = 256,
+     .tag_size = 10 },
+    {.can_name = "AEAD_AES_128_GCM",
+     .gcm_on = 1,
+     .key_size = 128,
+     .tag_size = 16 },
+    {.can_name = "AEAD_AES_256_GCM",
+     .gcm_on = 1,
+     .key_size = 256,
+     .tag_size = 16 },
+    {.can_name = NULL }
+};
+
+void rtp_decoder_srtp_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;
+    }
+    fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
+}
+
+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 = 0;
+    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 = { { 0 } };
+    rtp_decoder_mode_t mode = mode_rtp;
+    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);
+    }
+
+    status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
+    if (status) {
+        fprintf(stderr, "error: install log handler failed\n");
+        exit(1);
+    }
+
+    /* check args */
+    while (1) {
+        c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:");
+        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 != 192 &&
+                scs.key_size != 256) {
+                fprintf(
+                    stderr,
+                    "error: encryption key size must be 128, 192 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_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;
+            gcm_on = scs.gcm_on;
+            break;
+        case 'm':
+            if (strcasecmp("rtp", optarg_s) == 0) {
+                mode = mode_rtp;
+            } else if (strcasecmp("rtcp", optarg_s) == 0) {
+                mode = mode_rtcp;
+            } else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
+                mode = mode_rtcp_mux;
+            } else {
+                fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
+                exit(1);
+            }
+            break;
+        default:
+            usage(argv[0]);
+        }
+    }
+
+    if (scs.tag_size == 0) {
+        if (gcm_on) {
+            scs.tag_size = 16;
+        } else {
+            scs.tag_size = 10;
+        }
+    }
+
+    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 (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
+        fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
+                scs.tag_size);
+        exit(1);
+    }
+
+    if (do_list_mods) {
+        status = srtp_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:
+                    if (scs.tag_size == 16) {
+                        srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_128_16_auth(
+                            &policy.rtcp);
+                    } else {
+                        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:
+                    if (scs.tag_size == 16) {
+                        srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
+                        srtp_crypto_policy_set_aes_gcm_256_16_auth(
+                            &policy.rtcp);
+                    } else {
+                        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:
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
+                            &policy.rtcp);
+                    }
+                    break;
+                case 192:
+#ifdef OPENSSL
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                            &policy.rtcp);
+                    }
+#else
+                    fprintf(stderr,
+                            "error: AES 192 mode only supported when using the "
+                            "OpenSSL crypto engine.\n");
+                    return 0;
+
+#endif
+                    break;
+                case 256:
+                    if (scs.tag_size == 4) {
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &policy.rtcp);
+                    } else {
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &policy.rtp);
+                        srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                            &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_aes_cm_128_hmac_sha1_80(
+                        &policy.rtcp);
+                    break;
+                case 192:
+#ifdef OPENSSL
+                    srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
+                        &policy.rtcp);
+#else
+                    fprintf(stderr,
+                            "error: AES 192 mode only supported when using the "
+                            "OpenSSL crypto engine.\n");
+                    return 0;
+
+#endif
+                    break;
+                case 256:
+                    srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
+                    srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
+                        &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,
+                                                strlen(input_key));
+        } 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\n");
+        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");
+    if (rtp_decoder_init(dec, policy, mode)) {
+        fprintf(stderr, "error: init failed\n");
+        exit(1);
+    }
+
+    pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
+
+    if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
+        fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
+    }
+    if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
+        fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
+    }
+    fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);
+
+    rtp_decoder_deinit(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][-t][-e] [-s "
+        "<srtp-crypto-suite>] [-m <mode>]\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"
+        "       -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\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);
+}
+
+int rtp_decoder_deinit(rtp_decoder_t decoder)
+{
+    if (decoder->srtp_ctx) {
+        return srtp_dealloc(decoder->srtp_ctx);
+    }
+    return 0;
+}
+
+int rtp_decoder_init(rtp_decoder_t dcdr,
+                     srtp_policy_t policy,
+                     rtp_decoder_mode_t mode)
+{
+    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->error_cnt = 0;
+    dcdr->rtp_cnt = 0;
+    dcdr->rtcp_cnt = 0;
+    dcdr->mode = mode;
+    dcdr->policy = policy;
+    dcdr->policy.ssrc.type = ssrc_any_inbound;
+
+    if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
+        return 1;
+    }
+    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;
+    rtp_msg_t message;
+    int rtp;
+    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 *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
+    pktsize = hdr->caplen - dcdr->rtp_offset;
+    octets_recvd = pktsize;
+
+    if (octets_recvd == -1) {
+        return;
+    }
+
+    if (dcdr->mode == mode_rtp) {
+        rtp = 1;
+    } else if (dcdr->mode == mode_rtcp) {
+        rtp = 0;
+    } else {
+        rtp = 1;
+        if (octets_recvd >= 2) {
+            /* rfc5761 */
+            u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
+            rtp = payload_type < 64 || payload_type > 95;
+        }
+    }
+
+    if (rtp) {
+        /* verify rtp header */
+        if (message.header.version != 2) {
+            return;
+        }
+
+        status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
+        if (status) {
+            dcdr->error_cnt++;
+            return;
+        }
+        dcdr->rtp_cnt++;
+    } else {
+        status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
+        if (status) {
+            dcdr->error_cnt++;
+            return;
+        }
+        dcdr->rtcp_cnt++;
+    }
+    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(&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
+}
diff --git a/test/rtp_decoder.h b/test/rtp_decoder.h
new file mode 100644
index 0000000..30a51d8
--- /dev/null
+++ b/test/rtp_decoder.h
@@ -0,0 +1,121 @@
+/*
+ * 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 enum {
+    mode_rtp = 0,
+    mode_rtcp,
+    mode_rtcp_mux,
+} rtp_decoder_mode_t;
+
+typedef struct rtp_decoder_ctx_t {
+    srtp_policy_t policy;
+    srtp_ctx_t *srtp_ctx;
+    rtp_decoder_mode_t mode;
+    int rtp_offset;
+    struct timeval start_tv;
+    int frame_nr;
+    int error_cnt;
+    int rtp_cnt;
+    int rtcp_cnt;
+} 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,
+                     rtp_decoder_mode_t mode);
+
+int rtp_decoder_deinit(rtp_decoder_t decoder);
+
+void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
+                                  const char *msg,
+                                  void *data);
+
+void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
+                                  const char *msg,
+                                  void *data);
+
+#endif /* RTP_DECODER_H */
diff --git a/test/rtpw b/test/rtpw
deleted file mode 100755
index 08950dd..0000000
--- a/test/rtpw
+++ /dev/null
Binary files differ
diff --git a/test/rtpw.c b/test/rtpw.c
index 63736fc..901816e 100644
--- a/test/rtpw.c
+++ b/test/rtpw.c
@@ -7,34 +7,34 @@
  * Cisco Systems, Inc.
  *
  * This app is a simple RTP application intended only for testing
- * libsrtp.  It reads one word at a time from /usr/dict/words (or
- * whatever file is specified as DICT_FILE), and sends one word out
+ * 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-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
@@ -50,43 +50,82 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <stdio.h>          /* for printf, fprintf */
-#include <stdlib.h>         /* for atoi()          */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>     /* openbsd wants this  */
-#include <arpa/inet.h>
+#include "getopt_s.h" /* for local getopt()  */
+
+#include <stdio.h>  /* for printf, fprintf */
+#include <stdlib.h> /* for atoi()          */
 #include <errno.h>
-#include <unistd.h>         /* for close()         */
-#include <string.h>         /* for strncpy()       */
-#include <time.h>	    /* for usleep()        */
+#include <signal.h> /* for signal()        */
 
-#include "srtp.h"           
+#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        "/usr/share/dict/words"
-#define USEC_RATE        (5e5)
-#define MAX_WORD_LEN     128  
+#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      64
-#define MASTER_KEY_LEN   30
+#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);
+void usage(char *prog_name);
 
 /*
  * leave_group(...) de-registers from a multicast group
  */
 
-void
-leave_group(int sock, struct ip_mreq mreq, char *name);
+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
@@ -94,352 +133,569 @@
 
 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;
+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;
-  sec_serv_t sec_servs = sec_serv_none;
-  unsigned char ttl = 5;
-  int c;
-  unsigned char *input_key = NULL;
-  unsigned char *address = NULL;
-  octet_t key[MAX_KEY_LEN];
-  unsigned short port = 0;
-  rtp_sender_t snd;
-  srtp_policy_t policy;
-  err_status_t status;
-  int len;
-  int do_list_mods = 0;
-  uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
+    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;
 
-  /* 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(argc, argv, "k:rsaeld:");
-    if (c == -1) {
-      break;
-    }
-    switch (c) {
-    case 'k':
-      input_key = optarg;
-      break;
-    case 'e':
-      sec_servs |= sec_serv_conf;
-      break;
-    case 'a':
-      sec_servs |= sec_serv_auth;
-      break;
-    case 'r':
-      prog_type = receiver;
-      break;
-    case 's':
-      prog_type = sender;
-      break;
-    case 'd':
-      status = crypto_kernel_set_debug_module(optarg, 1);
-      if (status) {
-        printf("error: set debug module (%s) failed\n", optarg);
+    ret = WSAStartup(wVersionRequested, &wsaData);
+    if (ret != 0) {
+        fprintf(stderr, "error: WSAStartup() failed: %d\n", ret);
         exit(1);
-      }
-      break;
-    case 'l':
-      do_list_mods = 1;
-      break;
-    default:
-      usage(argv[0]);
     }
-  }
-
-  if (prog_type == unknown) {
-    if (do_list_mods) {
-      status = crypto_kernel_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 + 2) {
-    /* wrong number of arguments */
-    usage(argv[0]);
-  }
-
-  /* get address from arg */
-  address = argv[optind++];
-
-  /* get port from arg */
-  port = atoi(argv[optind++]);
-
-  /* set address */
-#if 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) {
-    fprintf(stderr, "%s: couldn't open socket\n", argv[0]);
-    exit(1);
-  }
+    memset(&policy, 0x0, sizeof(srtp_policy_t));
 
-  name.sin_addr   = rcvr_addr;    
-  name.sin_family = PF_INET;
-  name.sin_port   = htons(port);
- 
-  if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
+    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);
+    }
+
+    memset(&name, 0, sizeof(struct sockaddr_in));
+    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 GCM
+                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 "
+                       "or NSS 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 GCM
+                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) {
-      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, &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
-     */
-    crypto_policy_set_rtp_default(&policy.rtp);
-    crypto_policy_set_rtcp_default(&policy.rtcp);
-    policy.ssrc.type  = ssrc_specific;
-    policy.ssrc.value = ssrc;
-    policy.key  = key;
-    policy.next = NULL;
-    policy.rtp.sec_serv = sec_servs;
-    policy.rtcp.sec_serv = sec_serv_none;  /* we don't do RTCP anyway */
-
-    /*
-     * read key from hexadecimal on command line into an octet string
-     */
-    len = hex_string_to_octet_string(key, input_key, MASTER_KEY_LEN*2);
-    
-    /* check that hex string is the right length */
-    if (len < MASTER_KEY_LEN*2) {
-      fprintf(stderr, 
-	      "error: too few digits in key/salt "
-	      "(should be %d hexadecimal digits, found %d)\n",
-	      MASTER_KEY_LEN*2, len);
-      exit(1);    
-    } 
-    if (strlen(input_key) > MASTER_KEY_LEN*2) {
-      fprintf(stderr, 
-	      "error: too many digits in key/salt "
-	      "(should be %d hexadecimal digits, found %u)\n",
-	      MASTER_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.
-     */
-    policy.ssrc.type           = ssrc_specific;
-    policy.ssrc.value          = ssrc;
-    policy.rtp.cipher_type     = NULL_CIPHER;
-    policy.rtp.cipher_key_len  = 0; 
-    policy.rtp.auth_type       = NULL_AUTH;
-    policy.rtp.auth_key_len    = 0;
-    policy.rtp.auth_tag_len    = 0;
-    policy.rtp.sec_serv        = sec_serv_none;   
-    policy.rtcp.cipher_type    = NULL_CIPHER;
-    policy.rtcp.cipher_key_len = 0; 
-    policy.rtcp.auth_type      = NULL_AUTH;
-    policy.rtcp.auth_key_len   = 0;
-    policy.rtcp.auth_tag_len   = 0;
-    policy.rtcp.sec_serv       = sec_serv_none;   
-    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); 
-    }
+        /* 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 */
-    rtp_sender_init(&snd, sock, name, ssrc); 
-    status = srtp_create(&snd.srtp_ctx, &policy);
+        /* 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) {
-      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 (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);
-    }
-    
-  } 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);
+        printf("error: srtp shutdown failed with error code %d\n", status);
+        exit(1);
     }
 
-    rtp_receiver_init(&rcvr, sock, name, ssrc);
-    status = srtp_create(&rcvr.srtp_ctx, &policy);
-    if (status) {
-      fprintf(stderr, 
-	      "error: srtp_create() failed with code %d\n", 
-	      status);
-      exit(1);
-    }
+#ifdef RTPW_USE_WINSOCK2
+    WSACleanup();
+#endif
 
-    /* get next word and loop */
-    while (1) {
-      len = MAX_WORD_LEN;
-      if (rtp_recvfrom(&rcvr, word, &len) > -1)
-	printf("\tword: %s", word);
-      else
-	printf("error receiving data\n");
-    }
-      
-  } 
-
-  if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
-    leave_group(sock, mreq, argv[0]);
-  }
-  return 0;
+    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 use encryption\n"
-	 "       -k <key>  sets the srtp master key\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",
-	 string, string);
-  exit(1);
-  
+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;
 
-void
-leave_group(int sock, struct ip_mreq mreq, char *name) {
-  int ret;
-
-  ret = setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
-  if (ret < 0) {
-	fprintf(stderr, "%s: Failed to leave multicast group", name);
-	perror("");
-  }
+    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;
+}
diff --git a/test/rtpw_test.sh b/test/rtpw_test.sh
new file mode 100755
index 0000000..158a393
--- /dev/null
+++ b/test/rtpw_test.sh
@@ -0,0 +1,176 @@
+#!/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"
+        ;;
+    *Linux*)
+        EXE=""
+        export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+    *Darwin*)
+        EXE=""
+        export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+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
+
+
diff --git a/test/rtpw_test_gcm.sh b/test/rtpw_test_gcm.sh
new file mode 100755
index 0000000..644255e
--- /dev/null
+++ b/test/rtpw_test_gcm.sh
@@ -0,0 +1,260 @@
+#!/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"
+        ;;
+    *Linux*)
+        EXE=""
+        export LD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+    *Darwin*)
+        EXE=""
+        export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR
+        ;;
+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
+
+
diff --git a/test/sha1_driver.c b/test/sha1_driver.c
deleted file mode 100644
index d9bfa8b..0000000
--- a/test/sha1_driver.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * sha1_driver.c
- *
- * a test driver for SHA-1
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-/*
- *	
- * Copyright (c) 2001-2005, Cisco Systems, Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- *   Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * 
- *   Redistributions in binary form must reproduce the above
- *   copyright notice, this list of conditions and the following
- *   disclaimer in the documentation and/or other materials provided
- *   with the distribution.
- * 
- *   Neither the name of the Cisco Systems, Inc. nor the names of its
- *   contributors may be used to endorse or promote products derived
- *   from this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <stdio.h>
-#include "sha1.h"
-
-int
-hmac_sha1_test();
-
-int
-main () {
-  uint32_t hash_value[5];
-  octet_t msg_ref[3] = { 0x61, 0x62, 0x63 };
-  octet_t hash_ref[20] = {
-    0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
-    0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 
-    0x9c, 0xd0, 0xd8, 0x9d 
-  };
-  octet_t msg_ref2[56] = {
-    0x61, 0x62, 0x63, 0x64, 0x62, 0x63, 0x64, 0x65, 
-    0x63, 0x64, 0x65, 0x66, 0x64, 0x65, 0x66, 0x67,
-    0x65, 0x66, 0x67, 0x68, 0x66, 0x67, 0x68, 0x69, 
-    0x67, 0x68, 0x69, 0x6a, 0x68, 0x69, 0x6a, 0x6b,
-    0x69, 0x6a, 0x6b, 0x6c, 0x6a, 0x6b, 0x6c, 0x6d,
-    0x6b, 0x6c, 0x6d, 0x6e, 0x6c, 0x6d, 0x6e, 0x6f,
-    0x6d, 0x6e, 0x6f, 0x70, 0x6e, 0x6f, 0x70, 0x71
-  };
-  octet_t hash_ref2[20] = {
-    0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 
-    0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
-    0xe5, 0x46, 0x70, 0xf1
-  };
-  sha1_ctx_t ctx;
-
-  printf("sha1 test driver\n"
-         "David A. McGrew\n"
-         "Cisco Systems, Inc.\n");
-
-  sha1_init(&ctx);
-  sha1_update(&ctx, msg_ref, 3);
-  sha1_final(&ctx, hash_value);
-  printf("reference value: %s\n", 
-	 octet_string_hex_string((octet_t *)hash_ref, 20));
-  printf("computed value:  %s\n", 
-	 octet_string_hex_string((octet_t *)hash_value, 20));
-
-  sha1_init(&ctx);
-  sha1_update(&ctx, msg_ref2, 56);
-  sha1_final(&ctx, hash_value);
-  printf("reference value: %s\n", 
-	 octet_string_hex_string((octet_t *)hash_ref2, 20));
-  printf("computed value:  %s\n", 
-	 octet_string_hex_string((octet_t *)hash_value, 20));
-
-  return 0;
-}
diff --git a/test/srtp_driver.c b/test/srtp_driver.c
index a8a14e7..1335540 100644
--- a/test/srtp_driver.c
+++ b/test/srtp_driver.c
@@ -1,32 +1,32 @@
 /*
  * srtp_driver.c
- * 
+ *
  * a test driver for libSRTP
  *
  * David A. 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
@@ -42,65 +42,142 @@
  *
  */
 
-
 #include <string.h>   /* for memcpy()          */
 #include <time.h>     /* for clock()           */
 #include <stdlib.h>   /* for malloc(), free()  */
 #include <stdio.h>    /* for print(), fflush() */
-#include <unistd.h>   /* for getopt()          */
+#include "getopt_s.h" /* for local getopt()    */
 
-#include "srtp.h"
+#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
 
-err_status_t
-srtp_validate();
+srtp_err_status_t srtp_validate(void);
 
-err_status_t
-srtp_create_big_policy(srtp_policy_t **list);
+#ifdef GCM
+srtp_err_status_t srtp_validate_gcm(void);
+#endif
 
-err_status_t
-srtp_test_remove_stream();
+srtp_err_status_t srtp_validate_encrypted_extensions_headers(void);
 
-double
-srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
+#ifdef GCM
+srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm(void);
+#endif
 
-double
-srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
+srtp_err_status_t srtp_validate_aes_256(void);
 
-void
-srtp_do_timing(const srtp_policy_t *policy);
+srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list);
 
-void
-srtp_do_rejection_timing(const srtp_policy_t *policy);
+srtp_err_status_t srtp_dealloc_big_policy(srtp_policy_t *list);
 
-err_status_t
-srtp_test();
+srtp_err_status_t srtp_test_empty_payload(void);
 
-err_status_t
-srtp_session_print_policy(srtp_t srtp);
+#ifdef GCM
+srtp_err_status_t srtp_test_empty_payload_gcm(void);
+#endif
 
-err_status_t
-srtp_print_policy(const srtp_policy_t *policy); 
+srtp_err_status_t srtp_test_remove_stream(void);
 
-char *
-srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
+srtp_err_status_t srtp_test_update(void);
 
-double
-mips_estimate(int num_trials, int *ignore);
+srtp_err_status_t srtp_test_protect_trailer_length(void);
 
-extern octet_t test_key[30];
+srtp_err_status_t srtp_test_protect_rtcp_trailer_length(void);
 
-void
-usage(char *prog_name) {
-  printf("usage: %s [ -t ][ -c ][ -v ][-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"
-         "  -d <mod>   turn on debugging module <mod>\n"
-         "  -l         list debugging modules\n", prog_name);
-  exit(1);
+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);
 }
 
 /*
@@ -110,7 +187,6 @@
 
 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;
@@ -118,222 +194,445 @@
 /*
  * mod_driver debug module - debugging module for this test driver
  *
- * we use the crypto_kernel debugging system in this driver, which 
+ * we use the crypto_kernel debugging system in this driver, which
  * makes the interface uniform and increases portability
- */ 
+ */
 
-debug_module_t mod_driver = {
-  0,                  /* debugging is off by default */
-  "driver"            /* printable name for module   */
+srtp_debug_module_t mod_driver = {
+    0,       /* debugging is off by default */
+    "driver" /* printable name for module   */
 };
 
-int
-main (int argc, char *argv[]) {
-  char 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;
-  err_status_t status;
+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\n");
-    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 = 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(argc, argv, "trcvld:");
-    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 'l':
-      do_list_mods = 1;
-      break;
-    case 'd':
-      status = crypto_kernel_set_debug_module(optarg, 1);
-      if (status) {
-        printf("error: set debug module (%s) failed\n", optarg);
+    /*
+     * 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);
-      }  
-      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_list_mods) {
-    status = crypto_kernel_list_debug_modules();
+    /* initialize srtp library */
+    status = srtp_init();
     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 for each policy */
-    while (*policy != NULL) {
-      printf("testing srtp_protect and srtp_unprotect\n");
-      if (srtp_test(*policy) == err_status_ok)
-	printf("passed\n\n");
-      else {
-	printf("failed\n");
-	exit(1);
-      }
-      policy++;
+        printf("error: srtp init failed with error code %d\n", status);
+        exit(1);
     }
 
-    /* create a big policy list and run tests on it */
-    status = srtp_create_big_policy(&big_policy);
+    /*  load srtp_driver debug module */
+    status = srtp_crypto_kernel_load_debug_module(&mod_driver);
     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) == err_status_ok)
-      printf("passed\n\n");
-    else {
-      printf("failed\n");
-      exit(1);
+        printf("error: load of srtp_driver debug module failed "
+               "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) == 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 packets\n");
-    if (srtp_validate() == err_status_ok) 
-      printf("passed\n\n");
-    else {
-      printf("failed\n");
-       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]);
+        }
     }
 
-    /*
-     * test the function srtp_remove_stream()
-     */
-    printf("testing srtp_remove_stream()...");
-    if (srtp_test_remove_stream() == err_status_ok)
-      printf("passed\n");
-    else {
-      printf("failed\n");
-      exit(1);
+    if (!do_validation && !do_timing_test && !do_codec_timing &&
+        !do_list_mods && !do_rejection_test) {
+        usage(argv[0]);
     }
-  }
-  
-  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_log_stdout) {
+        status = srtp_install_log_handler(log_handler, NULL);
+        if (status) {
+            printf("error: install log handler failed\n");
+            exit(1);
+        }
     }
-  }
 
-  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_list_mods) {
+        status = srtp_list_debug_modules();
+        if (status) {
+            printf("error: list of debug modules failed\n");
+            exit(1);
+        }
     }
-  }
-  
-  if (do_codec_timing) {
-    srtp_policy_t policy;
-    int ignore;
-    double mips = mips_estimate(1000000000, &ignore);
 
-    crypto_policy_set_rtp_default(&policy.rtp);
-    crypto_policy_set_rtcp_default(&policy.rtcp);
-    policy.ssrc.type  = ssrc_specific;
-    policy.ssrc.value = 0xdecafbad;
-    policy.key  = test_key;
-    policy.next = NULL;
+    if (do_validation) {
+        const srtp_policy_t **policy = policy_array;
+        srtp_policy_t *big_policy;
 
-    printf("mips estimate: %e\n", mips);
+        /* 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 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 * (80 * 8) / 
-	   srtp_bits_per_second(80, &policy) / .01 );
-    printf("G.711\t\t%d\t\t\t%e\n", 160, 
-           (double) mips * (160 * 8) / 
-	   srtp_bits_per_second(160, &policy) / .02);
-    printf("G.726-32\t%d\t\t\t%e\n", 40, 
-           (double) mips * (40 * 8) / 
-	   srtp_bits_per_second(40, &policy) / .01 );
-    printf("G.726-32\t%d\t\t\t%e\n", 80, 
-           (double) mips * (80 * 8) / 
-	   srtp_bits_per_second(80, &policy) / .02);
-    printf("G.729\t\t%d\t\t\t%e\n", 10, 
-           (double) mips * (10 * 8) / 
-	   srtp_bits_per_second(10, &policy) / .01 );
-    printf("G.729\t\t%d\t\t\t%e\n", 20, 
-           (double) mips * (20 * 8) /
-	   srtp_bits_per_second(20, &policy) / .02 );
-  }
+            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);
+            }
 
-  return 0;  
+            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 GCM
+        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 GCM
+        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 GCM
+        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
@@ -347,470 +646,905 @@
  * 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;
-  octet_t *buffer;
-  srtp_hdr_t *hdr;
-  int bytes_in_hdr = 12;
+srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len,
+                                    uint32_t ssrc,
+                                    int *pkt_len)
+{
+    int i;
+    uint8_t *buffer;
+    srtp_hdr_t *hdr;
+    int bytes_in_hdr = 12;
 
-  /* allocate memory for test packet */
-  hdr = malloc(pkt_octet_len + bytes_in_hdr
-	       + SRTP_MAX_TRAILER_LEN + 4);
-  if (!hdr)
-    return NULL;
-  
-  hdr->version = 2;              /* RTP version two     */
-  hdr->p    = 0;                 /* no padding needed   */
-  hdr->x    = 0;                 /* no header extension */
-  hdr->cc   = 0;                 /* no CSRCs            */
-  hdr->m    = 0;                 /* marker bit          */
-  hdr->pt   = 0xf;               /* payload type        */
-  hdr->seq  = htons(0x1234);     /* sequence number     */
-  hdr->ts   = htonl(0xdecafbad); /* timestamp           */
-  hdr->ssrc = htonl(ssrc);       /* synch. source       */
+    /* allocate memory for test packet */
+    hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
+                               SRTP_MAX_TRAILER_LEN + 4);
+    if (!hdr) {
+        return NULL;
+    }
 
-  buffer = (octet_t *)hdr;
-  buffer += bytes_in_hdr;
+    hdr->version = 2;            /* RTP version two     */
+    hdr->p = 0;                  /* no padding needed   */
+    hdr->x = 0;                  /* no header extension */
+    hdr->cc = 0;                 /* no CSRCs            */
+    hdr->m = 0;                  /* marker bit          */
+    hdr->pt = 0xf;               /* payload type        */
+    hdr->seq = htons(0x1234);    /* sequence number     */
+    hdr->ts = htonl(0xdecafbad); /* timestamp           */
+    hdr->ssrc = htonl(ssrc);     /* synch. source       */
 
-  /* set RTP data to 0xab */
-  for (i=0; i < pkt_octet_len; i++)
-    *buffer++ = 0xab;
+    buffer = (uint8_t *)hdr;
+    buffer += bytes_in_hdr;
 
-  /* set post-data value to 0xffff to enable overrun checking */
-  for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
-    *buffer++ = 0xff;
+    /* set RTP data to 0xab */
+    for (i = 0; i < pkt_octet_len; i++) {
+        *buffer++ = 0xab;
+    }
 
-  return hdr;
+    /* set post-data value to 0xffff to enable overrun checking */
+    for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
+        *buffer++ = 0xff;
+    }
+
+    *pkt_len = bytes_in_hdr + pkt_octet_len;
+
+    return hdr;
 }
 
-void
-srtp_do_timing(const srtp_policy_t *policy) {
-  int len;
+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;
 
-  /*
-   * 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");  
+    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;
 }
 
-void
-srtp_do_rejection_timing(const srtp_policy_t *policy) {
-  int len;
+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
+    };
 
-  /*
-   * 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");  
+    /* 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 len;
-  uint32_t ssrc;
-  err_status_t status;
+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);
-  if (mesg == NULL)
-    return 0.0;   /* indicate failure by returning zero */
-  
-  timer = clock();
-  for (i=0; i < num_trials; i++) {
-    err_status_t status;
-    len = msg_len_octets;
-    
-    /* srtp protect message */
-    status = srtp_protect(srtp, mesg, &len);
+    /*
+     * allocate and initialize an srtp session
+     */
+    status = srtp_create(&srtp, policy);
     if (status) {
-      printf("error: srtp_protect() failed with error code %d\n", status);
-      exit(1);
+        printf("error: srtp_create() failed with error code %d\n", status);
+        exit(1);
     }
 
-    /* increment message number */
-    mesg->seq = htons(ntohs(mesg->seq) + 1);
+    /*
+     * if the ssrc is unspecified, use a predetermined one
+     */
+    if (policy->ssrc.type != ssrc_specific) {
+        ssrc = 0xdeadbeef;
+    } else {
+        ssrc = policy->ssrc.value;
+    }
 
-  }
-  timer = clock() - timer;
+    /*
+     * 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);
+        }
 
-  free(mesg);
-  
-  return (double) (msg_len_octets) * 8 *
-                  num_trials * CLOCKS_PER_SEC / timer;   
+        /* 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;
-  err_status_t status;
+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);
+    /*
+     * 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);
-  } 
-
-  mesg = srtp_create_test_packet(msg_len_octets, ssrc);
-  if (mesg == NULL)
-    return 0.0;  /* indicate failure by returning zero */
-  
-  len = msg_len_octets;  
-  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);
-  
-  return (double) num_trials * CLOCKS_PER_SEC / timer;   
 }
 
-
-void
-err_check(err_status_t s) {
-  if (s == 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);
+    }
 }
 
-err_status_t
-srtp_test(const srtp_policy_t *policy) {
-  int i;
-  srtp_t srtp_sender;
-  srtp_t srtp_rcvr;
-  err_status_t status = err_status_ok;
-  srtp_hdr_t *hdr, *hdr2;
-  octet_t *pkt_end;
-  int msg_len_octets;
-  int len;
-  int tag_length = policy->rtp.auth_tag_len; 
-  uint32_t ssrc;
-  srtp_policy_t *rcvr_policy;
+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);
+    }
+}
 
-  err_check(srtp_create(&srtp_sender, policy));
+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);
+    }
+}
 
-  /* print out policy */
-  err_check(srtp_session_print_policy(srtp_sender)); 
+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);
+    }
+}
 
-  /*
-   * 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);
+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 (hdr == NULL)
-    return err_status_alloc_fail;
-  hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
-  if (hdr2 == NULL) {
-    free(hdr);
-    return err_status_alloc_fail;
-  }
+    if (mki_index >= 0)
+        use_mki = 1;
 
-  /* set message length */
-  len = msg_len_octets;
+    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));
+    }
 
-  debug_print(mod_driver, "before protection:\n%s", 	      
-	      srtp_packet_to_string(hdr, len));
+    /* 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((octet_t *)hdr, len));
+    debug_print(mod_driver, "reference packet before protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
 #endif
-  err_check(srtp_protect(srtp_sender, hdr, &len));
+    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));
+    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((octet_t *)hdr, len));
+    debug_print(mod_driver, "after protection:\n%s",
+                octet_string_hex_string((uint8_t *)hdr, len));
 #endif
 
-  /* 
-   * 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.
-   */
-  pkt_end = (octet_t *)hdr + sizeof(srtp_hdr_t) 
-    + msg_len_octets + 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, ((octet_t *)hdr)[i], i);
-      free(hdr);
-      free(hdr2);
-      return err_status_algo_fail;
-    }  
+    /* save protected message and length */
+    memcpy(hdr_enc, hdr, len);
+    msg_len_enc = len;
 
-  /*
-   * 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 = err_status_algo_fail;
-    for (i=12; i < msg_len_octets+12; i++)
-      if (((octet_t *)hdr)[i] != ((octet_t *)hdr2)[i]) {
-	status = err_status_ok;
-      }
+    /*
+     * 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.
+     */
+    err_check(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) {
-      printf("failed\n");
-      free(hdr);
-      free(hdr2);
-      return status;
+        free(hdr);
+        free(hdr2);
+        free(rcvr_policy);
+        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 = malloc(sizeof(srtp_policy_t));
-  if (rcvr_policy == NULL)
-    return 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(&srtp_rcvr, rcvr_policy));
-   
-  err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
+    /*
+     * 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);
 
-  debug_print(mod_driver, "after unprotection:\n%s", 	      
-	      srtp_packet_to_string(hdr, len));
+        printf("testing for false positives in replay check...");
 
-  /* verify that the unprotected packet matches the origial one */
-  for (i=0; i < msg_len_octets; i++)
-    if (((octet_t *)hdr)[i] != ((octet_t *)hdr2)[i]) {
-      fprintf(stdout, "mismatch at octet %d\n", i);
-      status = err_status_algo_fail;
+        /* 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");
+        }
     }
-  if (status) {
+
+    err_check(srtp_dealloc(srtp_sender));
+    err_check(srtp_dealloc(srtp_rcvr));
+
     free(hdr);
     free(hdr2);
-    return status;
-  }
+    free(rcvr_policy);
+    return srtp_err_status_ok;
+}
 
-  /* 
-   * 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...");
+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;
 
-    /* unprotect a second time - should fail with a replay error */
-    status = srtp_unprotect(srtp_rcvr, hdr, &len);
-    if (status != err_status_replay_fail) {
-      printf("failed with error code %d\n", status);
-      free(hdr); 
-      free(hdr2);
-      return status;
+    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 {
-      printf("passed\n");
+        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;
     }
 
-    printf("testing for false positives in auth check...");
+    debug_print(mod_driver, "before protection:\n%s",
+                srtp_packet_to_string(hdr, len));
 
-    /* increment sequence number in header */
-    hdr->seq++; 
+#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));
 
-    /* apply protection */
-    err_check(srtp_protect(srtp_sender, hdr, &len));
-    
-    /* flip bits in packet */
-    data[0] ^= 0xff;
+    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
 
-    /* unprotect, and check for authentication failure */
-    status = srtp_unprotect(srtp_rcvr, hdr, &len);
-    if (status != err_status_auth_fail) {
-      printf("failed\n");
-      free(hdr); 
-      free(hdr2);
-      return status;
-    } else {
-      printf("passed\n");
+    /* 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;
+        }
     }
-            
-  }
 
-  err_check(srtp_dealloc(srtp_sender));
-  err_check(srtp_dealloc(srtp_rcvr));
+    /*
+     * 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");
+    }
 
-  free(hdr);
-  free(hdr2);
-  return err_status_ok;
+    /*
+     * 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;
+    }
+    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;
 
-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;
+    /* sanity checking */
+    if (srtp == NULL) {
+        return srtp_err_status_fail;
+    }
 
-  /* sanity checking */
-  if (srtp == NULL)
-    return 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");
 
-  /* if there's a template stream, print it out */
-  if (srtp->stream_template != NULL) {
-    stream = srtp->stream_template;
-    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",
-	   direction[stream->direction],
-	   stream->rtp_cipher->type->description,
-	   stream->rtp_auth->type->description,
-	   serv_descr[stream->rtp_services],
-	   stream->rtcp_cipher->type->description,
-	   stream->rtcp_auth->type->description,
-	   serv_descr[stream->rtcp_services]);
-  }
+        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 err_status_bad_param;
-    
-    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",
-	   stream->ssrc,
-	   stream->rtp_cipher->type->description,
-	   stream->rtp_auth->type->description,
-	   serv_descr[stream->rtp_services],
-	   stream->rtcp_cipher->type->description,
-	   stream->rtcp_auth->type->description,
-	   serv_descr[stream->rtcp_services]);
+    /* 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];
 
-    /* advance to next stream in the list */
-    stream = stream->next;
-  } 
-  return err_status_ok;
+        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;
 }
 
-err_status_t
-srtp_print_policy(const srtp_policy_t *policy) {
-  err_status_t status;
-  srtp_t session;
+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 err_status_ok;
+    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 
+/*
+ * srtp_print_packet(...) is for debugging only
  * it prints an RTP packet to the stdout
  *
  * note that this function is *not* threadsafe
@@ -822,43 +1556,35 @@
 
 char packet_string[MTU];
 
-char *
-srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
-  int octets_in_rtp_header = 12;
-  octet_t *data = ((octet_t *)hdr)+octets_in_rtp_header;
-  int hex_len = pkt_octet_len-octets_in_rtp_header;
+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;
+    /* 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);
+    /* 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;
+    return packet_string;
 }
 
 /*
@@ -871,341 +1597,2185 @@
  * optimize away the function
  */
 
-double
-mips_estimate(int num_trials, int *ignore) {
-  clock_t t;
-  int i, sum;
+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;
+    sum = 0;
+    t = clock();
+    for (i = 0; i < num_trials; i++) {
+        sum += i;
+    }
+    t = clock() - t;
+    if (t < 1) {
+        t = 1;
+    }
 
-/*   printf("%d\n", sum); */
-  *ignore = sum;
+    /*   printf("%d\n", sum); */
+    *ignore = sum;
 
-  return (double) num_trials * CLOCKS_PER_SEC / t;
+    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
 
-err_status_t
-srtp_validate() {
-  unsigned char test_key[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
-  };
-  octet_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
-  };
-  octet_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
-  };
-  octet_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
-  };
-  srtp_t srtp_snd, srtp_recv;
-  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
-   */
-  crypto_policy_set_rtp_default(&policy.rtp);
-  crypto_policy_set_rtcp_default(&policy.rtcp);
-  policy.ssrc.type  = ssrc_specific;
-  policy.ssrc.value = 0xcafebabe;
-  policy.key  = test_key;
-  policy.next = NULL;
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
 
-  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 err_status_fail;
+    /*
+     * 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;
 
-  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));
+    status = srtp_create(&srtp_snd, &policy);
+    if (status) {
+        return status;
+    }
 
-  if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
-    return 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;
+    /*
+     * 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;
+    }
 
-  /*
-   * 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 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));
 
-  return err_status_ok;
+    if (srtp_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 (srtp_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 (srtp_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 (srtp_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 GCM
+/*
+ * 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
 
-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;
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
 
-  /* sanity checking */
-  if ((list == NULL) || (policy_array[0] == NULL))
-    return err_status_bad_param;
+    /*
+     * 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;
 
-  /* 
-   * 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 = malloc(sizeof(srtp_policy_t));
-    if (p == NULL)
-      return 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 err_status_ok;
+    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 (srtp_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 (srtp_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 (srtp_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 (srtp_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 (srtp_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 (srtp_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;
 }
 
-err_status_t
-srtp_test_remove_stream() { 
-  err_status_t status;
-  srtp_policy_t *policy_list;
-  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);
-  
+#ifdef GCM
 
-  status = srtp_create_big_policy(&policy_list);
-  if (status)
-    return status;
+/*
+ * 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
 
-  status = srtp_create(&session, policy_list);
-  if (status)
-    return status;
+    srtp_t srtp_snd, srtp_recv;
+    srtp_err_status_t status;
+    int len;
+    srtp_policy_t policy;
+    int headers[3] = { 1, 3, 4 };
 
-  /*
-   * 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 != err_status_no_ctx)
-    return 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 != err_status_ok)
-    return err_status_fail;
-  stream = srtp_get_stream(session, htonl(0x0));
-  if (stream == NULL)
-    return err_status_fail;
-  stream = srtp_get_stream(session, htonl(0x2));
-  if (stream == NULL)
-    return err_status_fail;  
+    /*
+     * 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;
 
-  return err_status_ok;  
+    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 (srtp_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 (srtp_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 (srtp_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 (srtp_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 GCM
+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 // GCM
+
+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 GCM
+    srtp_policy_t policy_aes_gcm;
+    srtp_policy_t policy_aes_gcm_mki;
+#endif // GCM
+
+    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 GCM
+    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 // GCM
+
+    /* 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 GCM
+    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 // GCM
+
+    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 GCM
+    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 // GCM
+
+    srtp_dealloc(srtp_send);
+    srtp_dealloc(srtp_send_mki);
+#ifdef GCM
+    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 GCM
+    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 // GCM
+
+    srtp_dealloc(srtp_send);
+    srtp_dealloc(srtp_send_mki);
+#ifdef GCM
+    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
  */
 
-unsigned char test_key[30] = {
+// 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                    */                  
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    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                   */
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    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
-};
-
-const srtp_policy_t aes_tmmh_policy = {
-  { ssrc_any_outbound, 0 },     /* SSRC                        */
-  { 
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    UST_TMMHv2,             /* authentication func type    */
-    94,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_conf_and_auth  /* security services flag      */
-  },
-  { 
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    UST_TMMHv2,             /* authentication func type    */
-    94,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_conf_and_auth  /* security services flag      */
-  },
-  test_key,
-  NULL
-};
-
-const srtp_policy_t tmmh_only_policy = {
-  { ssrc_any_outbound, 0 },     /* SSRC                        */
-  {
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    UST_TMMHv2,             /* authentication func type    */
-    94,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_auth           /* security services flag      */
-  },
-  {
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    UST_TMMHv2,             /* authentication func type    */
-    94,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_auth           /* security services flag      */
-  },
-  test_key,
-  NULL
+    { 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                        */ 
-  {
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    NULL_AUTH,              /* authentication func type    */
-    0,                      /* auth key length in octets   */
-    0,                      /* auth tag length in octets   */
-    sec_serv_conf           /* security services flag      */
-  },
-  {
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    NULL_AUTH,              /* authentication func type    */
-    0,                      /* auth key length in octets   */
-    0,                      /* auth tag length in octets   */
-    sec_serv_conf           /* security services flag      */
-  },
-  test_key,
-  NULL
+    { 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                        */
-  {
-    NULL_CIPHER,            /* cipher type                 */
-    0,                      /* cipher key length in octets */
-    HMAC_SHA1,              /* authentication func type    */
-    20,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_auth           /* security services flag      */
-  },  
-  {
-    NULL_CIPHER,            /* cipher type                 */
-    0,                      /* cipher key length in octets */
-    HMAC_SHA1,              /* authentication func type    */
-    20,                     /* auth key length in octets   */
-    4,                      /* auth tag length in octets   */
-    sec_serv_auth           /* security services flag      */
-  },
-  test_key,
-  NULL
+    { 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 GCM
+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                        */ 
-  {
-    NULL_CIPHER,            /* cipher type                 */
-    0,                      /* cipher key length in octets */
-    NULL_AUTH,              /* authentication func type    */
-    0,                      /* auth key length in octets   */
-    0,                      /* auth tag length in octets   */
-    sec_serv_none           /* security services flag      */  
-  },
-  {
-    NULL_CIPHER,            /* cipher type                 */
-    0,                      /* cipher key length in octets */
-    NULL_AUTH,              /* authentication func type    */
-    0,                      /* auth key length in octets   */
-    0,                      /* auth tag length in octets   */
-    sec_serv_none           /* security services flag      */  
-  },
-  test_key,
-  NULL
+    { 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
@@ -1213,45 +3783,55 @@
  * 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 
+ * in a plot (see the gnuplot script file 'timing').  If you
  * add to this list, you should do it at the end.
  */
 
-#define USE_TMMH 0
-
-const srtp_policy_t *
-policy_array[] = {
-  &hmac_only_policy,
-#if USE_TMMH
-  &tmmh_only_policy,
+// clang-format off
+const srtp_policy_t *policy_array[] = {
+    &hmac_only_policy,
+    &aes_only_policy,
+    &default_policy,
+#ifdef GCM
+    &aes128_gcm_8_policy,
+    &aes128_gcm_8_cauth_policy,
+    &aes256_gcm_8_policy,
+    &aes256_gcm_8_cauth_policy,
 #endif
-  &aes_only_policy,
-#if USE_TMMH
-  &aes_tmmh_policy,
-#endif
-  &default_policy,
-  &null_policy,
-  NULL
+    &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                    */                  
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    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                   */
-    AES_128_ICM,            /* cipher type                 */
-    30,                     /* cipher key length in octets */
-    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
+    { 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
 };
diff --git a/test/stat_driver.c b/test/stat_driver.c
deleted file mode 100644
index b5e55ce..0000000
--- a/test/stat_driver.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * stat-driver.c
- *
- * test driver for the stat_test functions
- *
- * David A. McGrew
- * Cisco Systems, Inc.
- */
-
-
-#include <stdio.h>         /* for printf() */
-
-#include "err.h"
-#include "stat.h"
-
-#include "cipher.h"
-
-typedef struct {
-  void *state;
-} random_source_t;
-
-err_status_t
-random_source_alloc();
-
-void
-err_check(err_status_t s) {
-  if (s) {
-    printf("error (code %d)\n", s);
-    exit(1);
-  }
-}
-
-int
-main (int argc, char *argv[]) {
-  octet_t buffer[2500];
-  unsigned int buf_len = 2500;
-  int i, j;
-  extern cipher_type_t aes_icm;
-  cipher_t *c;
-  octet_t key[30] = {
-    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 = 10000;
-  int num_fail;
-
-  printf("statistical tests driver\n");
-
-  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));
-
-  for (i=0; i < 2500; i++)
-    buffer[i] = random();
-  printf("running stat_tests on random(), 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(cipher_type_alloc(&aes_icm, &c, 30));
-  err_check(cipher_init(c, key, direction_any));
-  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(cipher_set_iv(c, &nonce));
-    err_check(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");
-
-  return 0;
-}
diff --git a/test/test_srtp.c b/test/test_srtp.c
new file mode 100644
index 0000000..0cea1f3
--- /dev/null
+++ b/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.
+ *
+ */
+
+/*
+ * libSRTP specific.
+ */
+#include "../srtp/srtp.c" // Get access to static functions
+
+/*
+ * Test specific.
+ */
+#include "cutest.h"
+
+/*
+ * 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];
+    uint32_t sequence_num[SAMPLE_COUNT];
+    v128_t final_iv[SAMPLE_COUNT];
+    size_t i = 0;
+    memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
+    sequence_num[0] = 0xFF;
+    sequence_num[1] = 0xFF00;
+    sequence_num[2] = 0xFF0000;
+
+    // Postconditions
+    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
+    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
+}
diff --git a/test/util.c b/test/util.c
new file mode 100644
index 0000000..2abc28e
--- /dev/null
+++ b/test/util.c
@@ -0,0 +1,212 @@
+/*
+ * 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 "config.h"
+#include "util.h"
+
+#include <string.h>
+#include <stdint.h>
+
+/* include space for null terminator */
+char bit_string[MAX_PRINT_STRING_LEN + 1];
+
+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;
+    }
+
+    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;
+}
diff --git a/test/util.h b/test/util.h
new file mode 100644
index 0000000..d04b279
--- /dev/null
+++ b/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
diff --git a/test/words.txt b/test/words.txt
new file mode 100644
index 0000000..fe99c2d
--- /dev/null
+++ b/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
diff --git a/update.sh b/update.sh
index d116f82..595b647 100755
--- a/update.sh
+++ b/update.sh
@@ -6,7 +6,7 @@
 
 a=`find . -name "*.[ch]"`
 for x in $a; do 
-    sed 's/(c) 2001-2004/(c) 2001-2005/' $x > $x.tmp; 
+    sed 's/(c) 2001-2005/(c) 2001-2006/' $x > $x.tmp; 
     mv $x.tmp $x; 
 done