From 0745b128daaee80d5ba1c3ac29b43ca1dd8db6ee Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Wed, 9 Feb 2022 21:40:22 +0000 Subject: [PATCH] Bug 1754211: Update libsrtp to release 2.4.2 r=bwc Differential Revision: https://phabricator.services.mozilla.com/D138146 --- dom/media/webrtc/transport/SrtpFlow.cpp | 1 - third_party/libsrtp/src/CHANGES | 321 ++++++++++++++ third_party/libsrtp/src/README.md | 87 +++- third_party/libsrtp/src/VERSION | 2 +- third_party/libsrtp/src/crypto/.cvsignore | 1 + third_party/libsrtp/src/crypto/Makefile.in | 9 +- third_party/libsrtp/src/crypto/VERSION | 1 + third_party/libsrtp/src/crypto/cipher/aes.c | 24 +- .../src/crypto/cipher/aes_gcm_mbedtls.c | 412 ++++++++++++++++++ .../libsrtp/src/crypto/cipher/aes_gcm_nss.c | 193 +------- .../libsrtp/src/crypto/cipher/aes_gcm_ossl.c | 214 ++------- .../libsrtp/src/crypto/cipher/aes_icm.c | 99 +---- .../src/crypto/cipher/aes_icm_mbedtls.c | 371 ++++++++++++++++ .../libsrtp/src/crypto/cipher/aes_icm_nss.c | 178 +------- .../libsrtp/src/crypto/cipher/aes_icm_ossl.c | 169 +------ .../libsrtp/src/crypto/cipher/cipher.c | 57 +-- .../src/crypto/cipher/cipher_test_cases.c | 365 ++++++++++++++++ .../src/crypto/cipher/cipher_test_cases.h | 53 +++ .../libsrtp/src/crypto/cipher/null_cipher.c | 2 +- third_party/libsrtp/src/crypto/hash/auth.c | 6 + .../libsrtp/src/crypto/hash/auth_test_cases.c | 70 +++ .../libsrtp/src/crypto/hash/auth_test_cases.h | 48 ++ third_party/libsrtp/src/crypto/hash/hmac.c | 36 +- .../libsrtp/src/crypto/hash/hmac_mbedtls.c | 221 ++++++++++ .../libsrtp/src/crypto/hash/hmac_nss.c | 290 ++++++++++++ .../libsrtp/src/crypto/hash/hmac_ossl.c | 39 +- third_party/libsrtp/src/crypto/hash/sha1.c | 21 +- .../libsrtp/src/crypto/include/.cvsignore | 1 + .../libsrtp/src/crypto/include/aes_gcm.h | 23 + .../libsrtp/src/crypto/include/aes_icm_ext.h | 18 + .../libsrtp/src/crypto/include/cipher_priv.h | 62 +++ .../libsrtp/src/crypto/include/cipher_types.h | 8 +- .../libsrtp/src/crypto/include/datatypes.h | 164 +------ third_party/libsrtp/src/crypto/include/err.h | 5 + third_party/libsrtp/src/crypto/include/key.h | 2 - .../libsrtp/src/crypto/include/null_auth.h | 11 - third_party/libsrtp/src/crypto/include/rdb.h | 2 - third_party/libsrtp/src/crypto/include/sha1.h | 94 ---- third_party/libsrtp/src/crypto/kernel/alloc.c | 2 +- .../libsrtp/src/crypto/kernel/crypto_kernel.c | 10 +- third_party/libsrtp/src/crypto/kernel/err.c | 2 +- third_party/libsrtp/src/crypto/kernel/key.c | 8 - .../libsrtp/src/crypto/math/datatypes.c | 209 +-------- third_party/libsrtp/src/crypto/replay/rdb.c | 2 + .../libsrtp/src/crypto/test/.cvsignore | 8 + .../libsrtp/src/crypto/test/aes_calc.c | 43 +- .../libsrtp/src/crypto/test/cipher_driver.c | 20 +- .../src/crypto/test/datatypes_driver.c | 34 -- .../libsrtp/src/crypto/test/kernel_driver.c | 12 - .../libsrtp/src/crypto/test/meson.build | 41 ++ third_party/libsrtp/src/include/srtp.h | 88 ++-- .../libsrtp/src/include/srtp2/meson.build | 8 + third_party/libsrtp/src/include/srtp_priv.h | 4 +- third_party/libsrtp/src/moz.build | 6 +- third_party/libsrtp/src/srtp/srtp.c | 245 +++++------ third_party/libsrtp/src/test/.cvsignore | 13 + third_party/libsrtp/src/test/getopt_s.h | 67 +++ third_party/libsrtp/src/test/meson.build | 77 ++++ third_party/libsrtp/src/test/rdbx_driver.c | 13 +- third_party/libsrtp/src/test/replay_driver.c | 10 +- third_party/libsrtp/src/test/rtp.c | 4 +- third_party/libsrtp/src/test/rtp_decoder.c | 352 +++++++++++---- third_party/libsrtp/src/test/rtp_decoder.h | 32 +- third_party/libsrtp/src/test/rtpw.c | 6 +- third_party/libsrtp/src/test/rtpw_test.sh | 13 +- third_party/libsrtp/src/test/rtpw_test_gcm.sh | 13 +- third_party/libsrtp/src/test/srtp_driver.c | 283 +++++++++--- third_party/libsrtp/src/test/test_srtp.c | 16 +- third_party/libsrtp/src/test/ut_sim.c | 107 +++++ third_party/libsrtp/src/test/ut_sim.h | 83 ++++ third_party/libsrtp/src/test/util.c | 3 +- third_party/libsrtp/srtp_update.log | 1 + third_party/libsrtp/update_srtp.sh | 6 +- 73 files changed, 3649 insertions(+), 1872 deletions(-) create mode 100644 third_party/libsrtp/src/CHANGES create mode 100644 third_party/libsrtp/src/crypto/.cvsignore create mode 100644 third_party/libsrtp/src/crypto/VERSION create mode 100644 third_party/libsrtp/src/crypto/cipher/aes_gcm_mbedtls.c create mode 100644 third_party/libsrtp/src/crypto/cipher/aes_icm_mbedtls.c create mode 100644 third_party/libsrtp/src/crypto/cipher/cipher_test_cases.c create mode 100644 third_party/libsrtp/src/crypto/cipher/cipher_test_cases.h create mode 100644 third_party/libsrtp/src/crypto/hash/auth_test_cases.c create mode 100644 third_party/libsrtp/src/crypto/hash/auth_test_cases.h create mode 100644 third_party/libsrtp/src/crypto/hash/hmac_mbedtls.c create mode 100644 third_party/libsrtp/src/crypto/hash/hmac_nss.c create mode 100644 third_party/libsrtp/src/crypto/include/.cvsignore create mode 100644 third_party/libsrtp/src/crypto/include/cipher_priv.h create mode 100644 third_party/libsrtp/src/crypto/test/.cvsignore create mode 100644 third_party/libsrtp/src/crypto/test/meson.build create mode 100644 third_party/libsrtp/src/include/srtp2/meson.build create mode 100644 third_party/libsrtp/src/test/.cvsignore create mode 100644 third_party/libsrtp/src/test/getopt_s.h create mode 100644 third_party/libsrtp/src/test/meson.build create mode 100644 third_party/libsrtp/src/test/ut_sim.c create mode 100644 third_party/libsrtp/src/test/ut_sim.h diff --git a/dom/media/webrtc/transport/SrtpFlow.cpp b/dom/media/webrtc/transport/SrtpFlow.cpp index 97634b7a126b..827d1a0f6d43 100644 --- a/dom/media/webrtc/transport/SrtpFlow.cpp +++ b/dom/media/webrtc/transport/SrtpFlow.cpp @@ -92,7 +92,6 @@ RefPtr SrtpFlow::Create(int cipher_suite, bool inbound, const_cast(static_cast(key)); policy.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound; policy.ssrc.value = 0; - policy.ekt = nullptr; policy.window_size = 1024; // Use the Chrome value. Needs to be revisited. Default is 128 policy.allow_repeat_tx = 1; // Use Chrome value; needed for NACK mode to work diff --git a/third_party/libsrtp/src/CHANGES b/third_party/libsrtp/src/CHANGES new file mode 100644 index 000000000000..74ec4143ea5b --- /dev/null +++ b/third_party/libsrtp/src/CHANGES @@ -0,0 +1,321 @@ +Changelog + +2.4.2 + +#563 - Fix typo introduced by PR 559 + +2.4.1 + +Major changes + +#560 - Merge PR 559, Use a full-length key even with null ciphers + +2.4.0 + +Major changes + +#529 - Remove EKT files, this was never completed and the draft has since changed. + +#512 - Adds suport for Mbedtls as a crypto backend. + +#503 - Support apple silicon build. + +#495 - Adds support for the Meson build system. This is an alternative to Cmake and auto tools. + +Other changes + +#546 - Improve OpenSSL KDF check. + +#542 - Add void to function declarations for EVP_EncryptInit check. + +#531 - Remove dead code. + +#524 - Support running against nss >= 3.52. + +#521 - Remove references to dtls from libsrtp. + +#520 - Use nss based hmac when nss enabled. + +#519 - Move selftest vectors form backends to common files. + +#515 - Extend cmake support. + +#514 - Fix gcc11 warning by defining output length. + +#502 - Remove visual studio build files. + +#501 - cmake: Set the VERSION property of the srtp2 library. + +#500 - Fixed issue #499 with buffer overflow. + +#498 - Feature/additional error checks. + +#496 - Rework check for OPENSSL_cleanse(). + +#492 - Avoid non-existing compiler flag -O4. + +#491 - Fix two-byte RTP header extension encryption. + +#478 - Modify cmake to install crypto_types.h instead of cipher_types.h + +2.3.0 + +Major changes + +A fuzzer was added to the project based on libFuzzer. This is run as part of Google oss-fuzz, the current status can be found at https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libsrtp . Details available in PR #442 and issue #393. + +CMake support was added as an alternative build system. This was primarily added to replace the Visual Studio project files currently checked in but has been extend to support building on all platforms. Initial PR #449 and #455 but has been support has been continuously improved. + +NSS support for crypto backend was added. This is can be used as an alternative to openssl. Initial PR #413 but there has been numerous improvements. + +Other changes + +PR #474 - Add flag to disable pcap dependency when build test apps. + +PR #472 - Add ci builds for ios and android. + +PR #463 - problem on srtp_aes_icm_openssl_encrypt. + +PR #471 - Allow the pcap file to be read from a physical file. + +PR #457 - Fix docs crypto_policy_* -> srtp_crypto_policy_* . + +PR #452 - crypto/cipher: Reset the EVP_CIPHER_CTX structure before each test. + +PR #444 - Extend rtp_ecoder to support RTCP and multiplexed SSRC's. + +PR #443 - rtp_decoder avoid crash when no packets found. + +PR #429 - Rand for test only. + +PR #421 - Fix GCM IV logging. + +PR #415 - Fixes unaligned trailer access. + +PR #414 - Detect and handle broken "OPENSSL_cleanse". + +2.2.0 + +Major changes + +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. + +Other changes + +PR #409 - Compatibilty with LibreSSL + +PR #406 - Fix unprotect when pktlen < (2*mki_size + tag_len) + +PR #405 - Prevent potential double free + +PR #404 - Add back extern to global variables + +PR #403 - Set gcm IV directly with EVP_CipherInit_ex + +PR #401 - Fix memory access issue in srtp_get_session_keys() + +PR #398 - Fix memory access fixes when invalid profiles where used + +PR #391 - Return NULL when allocating memory of size zero + +PR #390 - Bitvector of length zero is not valid + +PR #385 - Treat warnings as errors on travis builds + +PR #388 - Moved externs from crypto_kernel into its own header + +PR #379 - Fixed several compiler warnings from Firefox builds + +PR #377 - Removed variable init code in rdbx which never gets used + +PR #381 - Added error in case the platform is not detected + +PR #376 - Add coverity scan to travis builds + +PR #374 - Add a big endian build on travis + +PR #373 - Fixed buffer size issue in test/srtp_driver.c + +PR #372 - Make rtp_decoder compile on MinGW + +PR #367 - Rename configure.in to configure.ac + +PR #365 - Replace calls to free() with srtp_crypto_free() + +PR #364 - Add valgrind to travis and fix leaks in tests + +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' + + PR #174 - Avoid warning 'The macro AC_TRY_LINK is obsolete.' + + PR #175 - Remove 2nd -fPIC + + PR #182 - Add a length check before reading packet data + + PR #191 - On debug, output correct endianness of SSRC + + PR #192 - Replace octet_string_is_eq with a constant-time implementation + + PR #195 - Add missing __cplusplus header guards + + PR #198 - Update sha1_driver.c to avoid memory leaks + + PR #202 - Add an explicit cast to avoid a printf format warning on macOS + + PR #205 - Update Windows build files to Visual Studio 2015 + + PR #207 - Fix to install-win.bat syntax, and add installation of x64 libraries + + PR #208 - Make replace_cipher and replace_auth public again + + PR #211 - Changes for OpenSSL 1.1.0 compatibility + + PR #213 - Add cast to `unsigned int` in call to printf in test + + PR #214 - Avoid empty initializer braces + + PR #222 - Fix issue: No consistency when use some srtp_* functions + + PR #231 - Advance version on master in preparation for 2.1 release + + 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 + + PR #236 - test/rtp_decoder.c: Removed superfluous conditional + + PR #237 - test/rtp_decoder.c: spring cleaning + + PR #239 - octet_string_set_to_zero() delegates to OPENSSL_cleanse() if + available, if not it will use srtp_cleanse() to zero memory + + PR #243 - EKT is not really supported yet, remove from install + + PR #244 - Add simple error checking in timing test to avoid false results + + PR #245 - Add missing srtp_cipher_dealloc calls when test fails + + PR #246 - test/rtp_decoder: Add missing conditional + + PR #248 - New README.md that integrates intro, credits and references from + /doc/ and is used to generate documentation + + PR #249 - Remove support for generic aesicm from configure.in + + PR #250 - Update README.md, incorrect tag for link + + PR #255 - Cleanup outdated comment related to MKI + + PR #258 - Add AES-GCM to DTLS-SRTP Protection Profiles + + PR #263 - Cleaning up and removing duplicated and outdated code + + PR #265 - Introduction of unit test framework: CUTest + + PR #267 - crypto/kernel/err.c: Include datatypes.h + + PR #272 - Reduce literal constants + + PR #273 - SRTP AEAD SRTCP initialization vector regression tests + + PR #274 - Update Travis build - add ccache + + PR #276 - Reference and docs updates + + PR #278 - Removed crypto/test/auth_driver.c and test/lfsr.c + + PR #279 - Bump copyright year + + PR #283 - Add missing docs in srtp.h + + PR #284 - Add strict-prototypes warning if supported + + PR #291 - Use const char * for srtp_set_debug_module() + + PR #294 - Fix incorrect result of rdb_increment on overflow + + PR #300 - Standalone tests + + PR #301 - Configure fixes + + PR #302 - Fix warning regarding unused variable + + PR #303 - Makefile.in: Add gnu as match for shared lib suffix diff --git a/third_party/libsrtp/src/README.md b/third_party/libsrtp/src/README.md index 3f1e5bbfdebb..b7072414b13a 100644 --- a/third_party/libsrtp/src/README.md +++ b/third_party/libsrtp/src/README.md @@ -1,5 +1,7 @@ +[![CMake Build](https://github.com/cisco/libsrtp/actions/workflows/cmake.yml/badge.svg)](https://github.com/cisco/libsrtp/actions/workflows/cmake.yml) [![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) +[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/systemd.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#libsrtp) # Introduction to libSRTP @@ -12,10 +14,10 @@ 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). +audio, and video, defined by [RFC 3550](https://tools.ietf.org/html/rfc3550). 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 +defined in [RFC 3711](https://tools.ietf.org/html/rfc3711), 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. @@ -31,7 +33,7 @@ because it does its work behind the scenes. -------------------------------------------------------------------------------- - + # Contact Us - [libsrtp@lists.packetizer.com](mailto:libsrtp@lists.packetizer.com) general mailing list for news / announcements / discussions. This is an open list, see @@ -46,7 +48,7 @@ because it does its work behind the scenes. ## Contents - [Introduction to libSRTP](#introduction-to-libsrtp) - - [Contact Us](#contact) +- [Contact Us](#contact-us) - [Contents](#contents) - [License and Disclaimer](#license-and-disclaimer) - [libSRTP Overview](#libsrtp-overview) @@ -55,6 +57,7 @@ because it does its work behind the scenes. - [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) @@ -137,16 +140,16 @@ can also be linked together to form an entire session policy. A linked list of `srtp_policy_t` structures is equivalent to a session policy. In such a policy, we refer to a single `srtp_policy_t` as an *element*. -An `srtp_policy_t` strucutre contains two `crypto_policy_t` structures +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 `crypto_policy_t` structures +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 -`crypto_policy_t` structure can be initialized by using either the -`crypto_policy_set_rtp_default()` or `crypto_policy_set_rtcp_default()` +`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. @@ -195,7 +198,7 @@ in which a key is used for both inbound and outbound data. ## 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 +SRTP (as defined in [RFC 3711](https://tools.ietf.org/html/rfc3711)). 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 @@ -212,7 +215,7 @@ supported. This includes 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). +will want to read the Security Considerations section of [RFC 3711](https://tools.ietf.org/html/rfc3711#section-9). In addition, it is important that you read and understand the terms outlined in the [License and Disclaimer](#license-and-disclaimer) section. @@ -313,6 +316,56 @@ brew install automake pkgconfig autoremake -ivf ``` +-------------------------------------------------------------------------------- + +## 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" +``` + +-------------------------------------------------------------------------------- + +## Using Meson + +On all platforms including Windows, one can build using [Meson](https://mesonbuild.org). +Steps to download Meson are here: https://mesonbuild.com/Getting-meson.html + +To build with Meson, you can do something like: + +``` +# Setup the build subdirectory +meson setup --prefix=/path/to/prefix builddir + +# Build the project +meson compile -C builddir + +# Run tests +meson test -C builddir + +# Optionally, install +meson install -C builddir +``` + +To build with Visual Studio, run the above commands from inside a Visual Studio +command prompt, or run `vcvarsall.bat` with the appropriate arguments inside +a Command Prompt. + +Note that you can also replace the above commands with the appropriate `ninja` +targets: `ninja -C build`, `ninja -C build test`, `ninja -C build install`. + -------------------------------------------------------------------------------- @@ -425,8 +478,8 @@ srtp_init(); memset(&policy, 0x0, sizeof(srtp_policy_t)); // set policy to describe a policy for an SRTP stream -crypto_policy_set_rtp_default(&policy.rtp); -crypto_policy_set_rtcp_default(&policy.rtcp); +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; @@ -475,13 +528,13 @@ Copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc. 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. +Secure RTP is defined in [RFC 3711](https://tools.ietf.org/html/rfc3711). +The counter mode definition is in [Section 4.1.1](https://tools.ietf.org/html/rfc3711#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) +HMAC is defined in [RFC 2104](https://tools.ietf.org/html/rfc2104) and HMAC-SHA1 test vectors are available -in [RFC 2202](https://www.ietf.org/rfc/rfc2202.txt). +in [RFC 2202](https://tools.ietf.org/html/rfc2202#section-3). -AES-GCM usage in SRTP is defined in [RFC 7714](https://www.ietf.org/html/rfc7714) +AES-GCM usage in SRTP is defined in [RFC 7714](https://tools.ietf.org/html/rfc7714) diff --git a/third_party/libsrtp/src/VERSION b/third_party/libsrtp/src/VERSION index 5432261487f5..8e8299dcc068 100644 --- a/third_party/libsrtp/src/VERSION +++ b/third_party/libsrtp/src/VERSION @@ -1 +1 @@ -2.2.0-pre +2.4.2 diff --git a/third_party/libsrtp/src/crypto/.cvsignore b/third_party/libsrtp/src/crypto/.cvsignore new file mode 100644 index 000000000000..f3c7a7c5da68 --- /dev/null +++ b/third_party/libsrtp/src/crypto/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/third_party/libsrtp/src/crypto/Makefile.in b/third_party/libsrtp/src/crypto/Makefile.in index 44f29ad2cf1e..8c2c4fabef95 100644 --- a/third_party/libsrtp/src/crypto/Makefile.in +++ b/third_party/libsrtp/src/crypto/Makefile.in @@ -61,12 +61,12 @@ dummy : all runtest # test applications ifneq (1, $(USE_EXTERNAL_CRYPTO)) AES_CALC = test/aes_calc$(EXE) +SHA1_DRIVER = test/sha1_driver$(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) + $(SHA1_DRIVER) test/kernel_driver$(EXE) \ + $(AES_CALC) test/env$(EXE) # data values used to test the aes_calc application for AES-128 k128=000102030405060708090a0b0c0d0e0f @@ -86,11 +86,10 @@ runtest: $(testapp) ifneq (1, $(USE_EXTERNAL_CRYPTO)) $(FIND_LIBRARIES) test `test/aes_calc $(k128) $(p128)` = $(c128) $(FIND_LIBRARIES) test `test/aes_calc $(k256) $(p256)` = $(c256) + $(FIND_LIBRARIES) test/sha1_driver$(EXE) -v >/dev/null 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." diff --git a/third_party/libsrtp/src/crypto/VERSION b/third_party/libsrtp/src/crypto/VERSION new file mode 100644 index 000000000000..3eefcb9dd5b3 --- /dev/null +++ b/third_party/libsrtp/src/crypto/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/third_party/libsrtp/src/crypto/cipher/aes.c b/third_party/libsrtp/src/crypto/cipher/aes.c index c9cd77420171..a2060c53e89f 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes.c +++ b/third_party/libsrtp/src/crypto/cipher/aes.c @@ -1414,11 +1414,6 @@ static void aes_128_expand_encryption_key(const uint8_t *key, 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 */ @@ -1445,11 +1440,6 @@ static void aes_128_expand_encryption_key(const uint8_t *key, 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); } @@ -1469,13 +1459,6 @@ static void aes_256_expand_encryption_key(const unsigned char *key, v128_copy_octet_string(&expanded_key->round[0], key); v128_copy_octet_string(&expanded_key->round[1], key + 16); -#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 - /* loop over rest of round keys */ for (i = 2; i < 15; i++) { /* munge first word of round key */ @@ -1515,11 +1498,6 @@ static void aes_256_expand_encryption_key(const unsigned char *key, 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 } } @@ -1796,7 +1774,7 @@ static inline void aes_inv_final_round(v128_t *state, const v128_t *round_key) v128_xor_eq(state, round_key); } -#elif CPU_RISC +#elif defined(CPU_RISC) static inline void aes_round(v128_t *state, const v128_t *round_key) { diff --git a/third_party/libsrtp/src/crypto/cipher/aes_gcm_mbedtls.c b/third_party/libsrtp/src/crypto/cipher/aes_gcm_mbedtls.c new file mode 100644 index 000000000000..d7d4b61cdf47 --- /dev/null +++ b/third_party/libsrtp/src/crypto/cipher/aes_gcm_mbedtls.c @@ -0,0 +1,412 @@ +/* + * aes_gcm_mbedtls.c + * + * AES Galois Counter Mode + * + * YongCheng Yang + * + */ + +/* + * + * 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 +#endif +#include +#include "aes_gcm.h" +#include "alloc.h" +#include "err.h" /* for srtp_debug */ +#include "crypto_types.h" +#include "cipher_types.h" +#include "cipher_test_cases.h" + +srtp_debug_module_t srtp_mod_aes_gcm = { + 0, /* debugging is off by default */ + "aes gcm mbedtls" /* printable module name */ +}; + +/** + * SRTP IV Formation for AES-GCM + * https://tools.ietf.org/html/rfc7714#section-8.1 + * 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 |<--+ + * +--+--+--+--+--+--+--+--+--+--+--+--+ + * + * SRTCP IV Formation for AES-GCM + * https://tools.ietf.org/html/rfc7714#section-9.1 + * + */ + +/* + * 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 + +#define FUNC_ENTRY() debug_print(srtp_mod_aes_gcm, "%s entry", __func__); +/* + * 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_mbedtls_alloc(srtp_cipher_t **c, + int key_len, + int tlen) +{ + FUNC_ENTRY(); + 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 = + (mbedtls_gcm_context *)srtp_crypto_alloc(sizeof(mbedtls_gcm_context)); + if (gcm->ctx == NULL) { + srtp_crypto_free(gcm); + srtp_crypto_free(*c); + *c = NULL; + return srtp_err_status_alloc_fail; + } + mbedtls_gcm_init(gcm->ctx); + + /* 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_mbedtls_dealloc(srtp_cipher_t *c) +{ + srtp_aes_gcm_ctx_t *ctx; + FUNC_ENTRY(); + ctx = (srtp_aes_gcm_ctx_t *)c->state; + if (ctx) { + mbedtls_gcm_free(ctx->ctx); + srtp_crypto_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); +} + +static srtp_err_status_t srtp_aes_gcm_mbedtls_context_init(void *cv, + const uint8_t *key) +{ + FUNC_ENTRY(); + srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; + uint32_t key_len_in_bits; + int errCode = 0; + c->dir = srtp_direction_any; + c->aad_size = 0; + + debug_print(srtp_mod_aes_gcm, "key: %s", + srtp_octet_string_hex_string(key, c->key_size)); + key_len_in_bits = (c->key_size << 3); + switch (c->key_size) { + case SRTP_AES_256_KEY_LEN: + case SRTP_AES_128_KEY_LEN: + break; + default: + return (srtp_err_status_bad_param); + break; + } + + errCode = mbedtls_gcm_setkey(c->ctx, MBEDTLS_CIPHER_ID_AES, + (const unsigned char *)key, key_len_in_bits); + if (errCode != 0) { + debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode); + return srtp_err_status_init_fail; + } + + return (srtp_err_status_ok); +} + +static srtp_err_status_t srtp_aes_gcm_mbedtls_set_iv( + void *cv, + uint8_t *iv, + srtp_cipher_direction_t direction) +{ + FUNC_ENTRY(); + 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)); + c->iv_len = GCM_IV_LEN; + memcpy(c->iv, iv, c->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_mbedtls_set_aad(void *cv, + const uint8_t *aad, + uint32_t aad_len) +{ + FUNC_ENTRY(); + int errCode = 0; + 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); +} + +/* + * 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_mbedtls_encrypt(void *cv, + unsigned char *buf, + unsigned int *enc_len) +{ + FUNC_ENTRY(); + srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; + int errCode = 0; + + if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + return (srtp_err_status_bad_param); + } + + errCode = mbedtls_gcm_crypt_and_tag(c->ctx, MBEDTLS_GCM_ENCRYPT, *enc_len, + c->iv, c->iv_len, c->aad, c->aad_size, + buf, buf, c->tag_len, c->tag); + + c->aad_size = 0; + if (errCode != 0) { + debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode); + return srtp_err_status_bad_param; + } + + 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_mbedtls_get_tag(void *cv, + uint8_t *buf, + uint32_t *len) +{ + FUNC_ENTRY(); + srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; + debug_print(srtp_mod_aes_gcm, "appended tag size: %d", c->tag_len); + *len = c->tag_len; + memcpy(buf, c->tag, 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_mbedtls_decrypt(void *cv, + unsigned char *buf, + unsigned int *enc_len) +{ + FUNC_ENTRY(); + srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; + int errCode = 0; + int len = *enc_len; + + if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { + return (srtp_err_status_bad_param); + } + + debug_print(srtp_mod_aes_gcm, "AAD: %s", + srtp_octet_string_hex_string(c->aad, c->aad_size)); + + errCode = mbedtls_gcm_auth_decrypt( + c->ctx, (*enc_len - c->tag_len), c->iv, c->iv_len, c->aad, c->aad_size, + buf + (*enc_len - c->tag_len), c->tag_len, buf, buf); + c->aad_size = 0; + if (errCode != 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_mbedtls_description[] = + "AES-128 GCM using mbedtls"; +static const char srtp_aes_gcm_256_mbedtls_description[] = + "AES-256 GCM using mbedtls"; + +/* + * This is the vector function table for this crypto engine. + */ +const srtp_cipher_type_t srtp_aes_gcm_128 = { + srtp_aes_gcm_mbedtls_alloc, + srtp_aes_gcm_mbedtls_dealloc, + srtp_aes_gcm_mbedtls_context_init, + srtp_aes_gcm_mbedtls_set_aad, + srtp_aes_gcm_mbedtls_encrypt, + srtp_aes_gcm_mbedtls_decrypt, + srtp_aes_gcm_mbedtls_set_iv, + srtp_aes_gcm_mbedtls_get_tag, + srtp_aes_gcm_128_mbedtls_description, + &srtp_aes_gcm_128_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_mbedtls_alloc, + srtp_aes_gcm_mbedtls_dealloc, + srtp_aes_gcm_mbedtls_context_init, + srtp_aes_gcm_mbedtls_set_aad, + srtp_aes_gcm_mbedtls_encrypt, + srtp_aes_gcm_mbedtls_decrypt, + srtp_aes_gcm_mbedtls_set_iv, + srtp_aes_gcm_mbedtls_get_tag, + srtp_aes_gcm_256_mbedtls_description, + &srtp_aes_gcm_256_test_case_0, + SRTP_AES_GCM_256 +}; diff --git a/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c b/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c index 2be2ce932ddf..23b6e0946a02 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c +++ b/third_party/libsrtp/src/crypto/cipher/aes_gcm_nss.c @@ -53,7 +53,7 @@ #include "err.h" /* for srtp_debug */ #include "crypto_types.h" #include "cipher_types.h" -#include +#include "cipher_test_cases.h" #include #include @@ -82,6 +82,7 @@ static srtp_err_status_t srtp_aes_gcm_nss_alloc(srtp_cipher_t **c, int tlen) { srtp_aes_gcm_ctx_t *gcm; + NSSInitContext *nss; debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d", key_len); @@ -99,24 +100,32 @@ static srtp_err_status_t srtp_aes_gcm_nss_alloc(srtp_cipher_t **c, return (srtp_err_status_bad_param); } - /* Initialize NSS */ - if (!NSS_IsInitialized() && NSS_NoDB_Init(NULL) != SECSuccess) { + /* 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; @@ -161,6 +170,11 @@ static srtp_err_status_t srtp_aes_gcm_nss_dealloc(srtp_cipher_t *c) 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); @@ -271,7 +285,6 @@ static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv, c->params.pIv = c->iv; c->params.ulIvLen = GCM_IV_LEN; - c->params.ulIvBits = GCM_IV_LEN * 8; c->params.pAAD = c->aad; c->params.ulAADLen = c->aad_size; @@ -390,174 +403,6 @@ static srtp_err_status_t srtp_aes_gcm_nss_decrypt(void *cv, 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. */ @@ -572,7 +417,7 @@ const srtp_cipher_type_t srtp_aes_gcm_128 = { 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_test_case_0, SRTP_AES_GCM_128 }; /* clang-format on */ @@ -591,7 +436,7 @@ const srtp_cipher_type_t srtp_aes_gcm_256 = { 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_test_case_0, SRTP_AES_GCM_256 }; /* clang-format on */ diff --git a/third_party/libsrtp/src/crypto/cipher/aes_gcm_ossl.c b/third_party/libsrtp/src/crypto/cipher/aes_gcm_ossl.c index 578cad5ee953..3e2d6bb1138b 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes_gcm_ossl.c +++ b/third_party/libsrtp/src/crypto/cipher/aes_gcm_ossl.c @@ -54,6 +54,7 @@ #include "err.h" /* for srtp_debug */ #include "crypto_types.h" #include "cipher_types.h" +#include "cipher_test_cases.h" srtp_debug_module_t srtp_mod_aes_gcm = { 0, /* debugging is off by default */ @@ -192,6 +193,7 @@ static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv, break; } + EVP_CIPHER_CTX_cleanup(c->ctx); if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) { return (srtp_err_status_init_fail); } @@ -250,19 +252,27 @@ static srtp_err_status_t srtp_aes_gcm_openssl_set_aad(void *cv, srtp_octet_string_hex_string(aad, aad_len)); /* - * Set dummy tag, OpenSSL requires the Tag to be set before - * processing AAD + * EVP_CTRL_GCM_SET_TAG can only be used when decrypting */ + if (c->dir == srtp_direction_decrypt) { + /* + * 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); + /* + * 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); + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, + &dummy_tag)) { + return (srtp_err_status_algo_fail); + } + } rv = EVP_Cipher(c->ctx, NULL, aad, aad_len); if (rv != aad_len) { @@ -321,7 +331,9 @@ static srtp_err_status_t srtp_aes_gcm_openssl_get_tag(void *cv, /* * Retreive the tag */ - EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf); + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf)) { + return (srtp_err_status_algo_fail); + } /* * Increase encryption length by desired tag size @@ -351,8 +363,10 @@ static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv, /* * 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)); + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, + buf + (*enc_len - c->tag_len))) { + return (srtp_err_status_auth_fail); + } EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len); /* @@ -379,174 +393,6 @@ static const char srtp_aes_gcm_128_openssl_description[] = 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. */ @@ -560,7 +406,7 @@ const srtp_cipher_type_t srtp_aes_gcm_128 = { 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_test_case_0, SRTP_AES_GCM_128 }; @@ -577,6 +423,6 @@ const srtp_cipher_type_t srtp_aes_gcm_256 = { 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_test_case_0, SRTP_AES_GCM_256 }; diff --git a/third_party/libsrtp/src/crypto/cipher/aes_icm.c b/third_party/libsrtp/src/crypto/cipher/aes_icm.c index 7551c75148f9..e05d9e45a36c 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes_icm.c +++ b/third_party/libsrtp/src/crypto/cipher/aes_icm.c @@ -52,6 +52,7 @@ #include "aes_icm.h" #include "alloc.h" #include "cipher_types.h" +#include "cipher_test_cases.h" srtp_debug_module_t srtp_mod_aes_icm = { 0, /* debugging is off by default */ @@ -399,104 +400,6 @@ static const char srtp_aes_icm_128_description[] = 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 */ - -/* 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 */ -}; - -/* 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 */ -}; - /* * note: the encrypt function is identical to the decrypt function */ diff --git a/third_party/libsrtp/src/crypto/cipher/aes_icm_mbedtls.c b/third_party/libsrtp/src/crypto/cipher/aes_icm_mbedtls.c new file mode 100644 index 000000000000..9893ded7023b --- /dev/null +++ b/third_party/libsrtp/src/crypto/cipher/aes_icm_mbedtls.c @@ -0,0 +1,371 @@ +/* + * aes_icm_mbedtls.c + * + * AES Integer Counter Mode + * + * YongCheng Yang + */ + +/* + * + * 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 +#endif +#include +#include "aes_icm_ext.h" +#include "crypto_types.h" +#include "err.h" /* for srtp_debug */ +#include "alloc.h" +#include "cipher_types.h" +#include "cipher_test_cases.h" + +srtp_debug_module_t srtp_mod_aes_icm = { + 0, /* debugging is off by default */ + "aes icm mbedtls" /* printable module name */ +}; + +/* + * integer counter mode works as follows: + * + * https://tools.ietf.org/html/rfc3711#section-4.1.1 + * + * E(k, IV) || E(k, IV + 1 mod 2^128) || E(k, IV + 2 mod 2^128) ... + * IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16) + * + * IV SHALL be defined by the SSRC, the SRTP packet index i, + * and the SRTP session salting key k_s. + * + * SSRC: 32bits. + * Sequence number: 16bits. + * nonce is 64bits. . + * packet index = ROC || SEQ. (ROC: Rollover counter) + * + * 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_mbedtls_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 = + (mbedtls_aes_context *)srtp_crypto_alloc(sizeof(mbedtls_aes_context)); + if (icm->ctx == NULL) { + srtp_crypto_free(icm); + srtp_crypto_free(*c); + *c = NULL; + return srtp_err_status_alloc_fail; + } + + mbedtls_aes_init(icm->ctx); + + /* 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_mbedtls_dealloc(srtp_cipher_t *c) +{ + srtp_aes_icm_ctx_t *ctx; + + if (c == NULL) { + return srtp_err_status_bad_param; + } + + /* + * Free the aes context + */ + ctx = (srtp_aes_icm_ctx_t *)c->state; + if (ctx != NULL) { + mbedtls_aes_free(ctx->ctx); + srtp_crypto_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; +} + +static srtp_err_status_t srtp_aes_icm_mbedtls_context_init(void *cv, + const uint8_t *key) +{ + srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; + uint32_t key_size_in_bits = (c->key_size << 3); + int errcode = 0; + + /* + * 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: + case SRTP_AES_192_KEY_LEN: + case SRTP_AES_128_KEY_LEN: + break; + default: + return srtp_err_status_bad_param; + break; + } + + errcode = mbedtls_aes_setkey_enc(c->ctx, key, key_size_in_bits); + if (errcode != 0) { + debug_print(srtp_mod_aes_icm, "errCode: %d", errcode); + } + + 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_mbedtls_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; + c->nc_off = 0; + /* 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)); + + 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_mbedtls_encrypt(void *cv, + unsigned char *buf, + unsigned int *enc_len) +{ + srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; + + int errCode = 0; + debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); + + errCode = + mbedtls_aes_crypt_ctr(c->ctx, *enc_len, &(c->nc_off), c->counter.v8, + c->stream_block.v8, buf, buf); + if (errCode != 0) { + debug_print(srtp_mod_aes_icm, "encrypt error: %d", errCode); + return srtp_err_status_cipher_fail; + } + + return srtp_err_status_ok; +} + +/* + * Name of this crypto engine + */ +static const char srtp_aes_icm_128_mbedtls_description[] = + "AES-128 counter mode using mbedtls"; +static const char srtp_aes_icm_192_mbedtls_description[] = + "AES-192 counter mode using mbedtls"; +static const char srtp_aes_icm_256_mbedtls_description[] = + "AES-256 counter mode using mbedtls"; + +/* + * 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_mbedtls_alloc, /* */ + srtp_aes_icm_mbedtls_dealloc, /* */ + srtp_aes_icm_mbedtls_context_init, /* */ + 0, /* set_aad */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_set_iv, /* */ + 0, /* get_tag */ + srtp_aes_icm_128_mbedtls_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_mbedtls_alloc, /* */ + srtp_aes_icm_mbedtls_dealloc, /* */ + srtp_aes_icm_mbedtls_context_init, /* */ + 0, /* set_aad */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_set_iv, /* */ + 0, /* get_tag */ + srtp_aes_icm_192_mbedtls_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_mbedtls_alloc, /* */ + srtp_aes_icm_mbedtls_dealloc, /* */ + srtp_aes_icm_mbedtls_context_init, /* */ + 0, /* set_aad */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_encrypt, /* */ + srtp_aes_icm_mbedtls_set_iv, /* */ + 0, /* get_tag */ + srtp_aes_icm_256_mbedtls_description, /* */ + &srtp_aes_icm_256_test_case_0, /* */ + SRTP_AES_ICM_256 /* */ +}; diff --git a/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c b/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c index c64335f41600..04323b4fef60 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c +++ b/third_party/libsrtp/src/crypto/cipher/aes_icm_nss.c @@ -52,7 +52,7 @@ #include "err.h" /* for srtp_debug */ #include "alloc.h" #include "cipher_types.h" -#include +#include "cipher_test_cases.h" srtp_debug_module_t srtp_mod_aes_icm = { 0, /* debugging is off by default */ @@ -106,6 +106,7 @@ static srtp_err_status_t srtp_aes_icm_nss_alloc(srtp_cipher_t **c, int tlen) { srtp_aes_icm_ctx_t *icm; + NSSInitContext *nss; debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d", key_len); @@ -119,19 +120,25 @@ static srtp_err_status_t srtp_aes_icm_nss_alloc(srtp_cipher_t **c, return srtp_err_status_bad_param; } - /* Initialize NSS */ - if (!NSS_IsInitialized() && NSS_NoDB_Init(NULL) != SECSuccess) { + /* 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; @@ -139,6 +146,7 @@ static srtp_err_status_t srtp_aes_icm_nss_alloc(srtp_cipher_t **c, icm->key = NULL; icm->ctx = NULL; + icm->nss = nss; /* set pointers */ (*c)->state = icm; @@ -188,6 +196,11 @@ static srtp_err_status_t srtp_aes_icm_nss_dealloc(srtp_cipher_t *c) 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); @@ -336,165 +349,6 @@ static const char srtp_aes_icm_192_nss_description[] = 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 diff --git a/third_party/libsrtp/src/crypto/cipher/aes_icm_ossl.c b/third_party/libsrtp/src/crypto/cipher/aes_icm_ossl.c index a9b14d3972ab..f960a33ecf68 100644 --- a/third_party/libsrtp/src/crypto/cipher/aes_icm_ossl.c +++ b/third_party/libsrtp/src/crypto/cipher/aes_icm_ossl.c @@ -58,6 +58,7 @@ #include "err.h" /* for srtp_debug */ #include "alloc.h" #include "cipher_types.h" +#include "cipher_test_cases.h" srtp_debug_module_t srtp_mod_aes_icm = { 0, /* debugging is off by default */ @@ -78,9 +79,9 @@ srtp_debug_module_t srtp_mod_aes_icm = { * +------+------+------+------+------+------+------+------+ | * | * +---------+ - * | encrypt | - * +---------+ - * | + * | encrypt | + * +---------+ + * | * +------+------+------+------+------+------+------+------+ | * | keystream block |<--+ * +------+------+------+------+------+------+------+------+ @@ -248,6 +249,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv, break; } + EVP_CIPHER_CTX_cleanup(c->ctx); if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) { return srtp_err_status_fail; } else { @@ -308,7 +310,7 @@ static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv, } *enc_len = len; - if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) { + if (!EVP_EncryptFinal_ex(c->ctx, buf + len, &len)) { return srtp_err_status_cipher_fail; } *enc_len += len; @@ -326,165 +328,6 @@ static const char srtp_aes_icm_192_openssl_description[] = 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 diff --git a/third_party/libsrtp/src/crypto/cipher/cipher.c b/third_party/libsrtp/src/crypto/cipher/cipher.c index 19f00abc55be..de93bc90d8f3 100644 --- a/third_party/libsrtp/src/crypto/cipher/cipher.c +++ b/third_party/libsrtp/src/crypto/cipher/cipher.c @@ -49,6 +49,7 @@ #endif #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() */ @@ -165,24 +166,11 @@ int srtp_cipher_get_key_length(const srtp_cipher_t *c) } /* - * A trivial platform independent random source. The random - * data is used for some of the cipher self-tests. + * A trivial platform independent random source. + * For use in test only. */ -static srtp_err_status_t srtp_cipher_rand(void *dest, uint32_t len) +void srtp_cipher_rand_for_tests(void *dest, uint32_t len) { -#if defined(HAVE_RAND_S) - uint8_t *dst = (uint8_t *)dest; - while (len) { - unsigned int val; - errno_t err = rand_s(&val); - - if (err != 0) - return srtp_err_status_fail; - - *dst++ = val & 0xff; - len--; - } -#else /* Generic C-library (rand()) version */ /* This is a random source of last resort */ uint8_t *dst = (uint8_t *)dest; @@ -194,8 +182,17 @@ static srtp_err_status_t srtp_cipher_rand(void *dest, uint32_t len) *dst++ = val & 0xff; len--; } -#endif - return srtp_err_status_ok; +} + +/* + * 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 @@ -246,7 +243,7 @@ srtp_err_status_t srtp_cipher_type_test( /* * test the encrypt function */ - debug_print(srtp_mod_cipher, "testing encryption", NULL); + debug_print0(srtp_mod_cipher, "testing encryption"); /* initialize cipher */ status = srtp_cipher_init(c, test_case->key); @@ -350,7 +347,7 @@ srtp_err_status_t srtp_cipher_type_test( /* * test the decrypt function */ - debug_print(srtp_mod_cipher, "testing decryption", NULL); + debug_print0(srtp_mod_cipher, "testing decryption"); /* re-initialize cipher for decryption */ status = srtp_cipher_init(c, test_case->key); @@ -465,13 +462,9 @@ srtp_err_status_t srtp_cipher_type_test( uint8_t iv[MAX_KEY_LEN]; /* choose a length at random (leaving room for IV and padding) */ - length = rand() % (SELF_TEST_BUF_OCTETS - 64); + length = srtp_cipher_rand_u32_for_tests() % (SELF_TEST_BUF_OCTETS - 64); debug_print(srtp_mod_cipher, "random plaintext length %d\n", length); - status = srtp_cipher_rand(buffer, length); - if (status) { - srtp_cipher_dealloc(c); - return status; - } + srtp_cipher_rand_for_tests(buffer, length); debug_print(srtp_mod_cipher, "plaintext: %s", srtp_octet_string_hex_string(buffer, length)); @@ -486,18 +479,10 @@ srtp_err_status_t srtp_cipher_type_test( srtp_cipher_dealloc(c); return srtp_err_status_cant_check; } - status = srtp_cipher_rand(key, test_case->key_length_octets); - if (status) { - srtp_cipher_dealloc(c); - return status; - } + srtp_cipher_rand_for_tests(key, test_case->key_length_octets); /* chose a random initialization vector */ - status = srtp_cipher_rand(iv, MAX_KEY_LEN); - if (status) { - srtp_cipher_dealloc(c); - return status; - } + srtp_cipher_rand_for_tests(iv, MAX_KEY_LEN); /* initialize cipher */ status = srtp_cipher_init(c, key); diff --git a/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.c b/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.c new file mode 100644 index 000000000000..e4b8f0fcd818 --- /dev/null +++ b/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.c @@ -0,0 +1,365 @@ +/* + * + * Copyright (c) 2013-2021, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "cipher_test_cases.h" +#include + +/* + * 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 */ + +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 */ + +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 */ + +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 */ +}; + +/* + * 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_128_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_128_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_128_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_128_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_128_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_128_test_case_0a = { + SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */ + srtp_aes_gcm_128_test_case_0_key, /* key */ + srtp_aes_gcm_128_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + srtp_aes_gcm_128_test_case_0_plaintext, /* plaintext */ + 68, /* octets in ciphertext */ + srtp_aes_gcm_128_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + srtp_aes_gcm_128_test_case_0_aad, /* AAD */ + 8, /* */ + NULL /* pointer to next testcase */ +}; + +const srtp_cipher_test_case_t srtp_aes_gcm_128_test_case_0 = { + SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */ + srtp_aes_gcm_128_test_case_0_key, /* key */ + srtp_aes_gcm_128_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + srtp_aes_gcm_128_test_case_0_plaintext, /* plaintext */ + 76, /* octets in ciphertext */ + srtp_aes_gcm_128_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + srtp_aes_gcm_128_test_case_0_aad, /* AAD */ + 16, /* */ + &srtp_aes_gcm_128_test_case_0a /* pointer to next testcase */ +}; + +/* clang-format off */ +static const uint8_t srtp_aes_gcm_256_test_case_0_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_256_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_256_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 on */ + +/* clang-format off */ +static const uint8_t srtp_aes_gcm_256_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_256_test_case_0_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_256_test_case_0a = { + SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */ + srtp_aes_gcm_256_test_case_0_key, /* key */ + srtp_aes_gcm_256_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + srtp_aes_gcm_256_test_case_0_plaintext, /* plaintext */ + 68, /* octets in ciphertext */ + srtp_aes_gcm_256_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + srtp_aes_gcm_256_test_case_0_aad, /* AAD */ + 8, /* */ + NULL /* pointer to next testcase */ +}; + +const srtp_cipher_test_case_t srtp_aes_gcm_256_test_case_0 = { + SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */ + srtp_aes_gcm_256_test_case_0_key, /* key */ + srtp_aes_gcm_256_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + srtp_aes_gcm_256_test_case_0_plaintext, /* plaintext */ + 76, /* octets in ciphertext */ + srtp_aes_gcm_256_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + srtp_aes_gcm_256_test_case_0_aad, /* AAD */ + 16, /* */ + &srtp_aes_gcm_256_test_case_0a /* pointer to next testcase */ +}; diff --git a/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.h b/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.h new file mode 100644 index 000000000000..c8a92840023f --- /dev/null +++ b/third_party/libsrtp/src/crypto/cipher/cipher_test_cases.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2013-2021, 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 CHIPHER_TEST_CASES_H +#define CHIPHER_TEST_CASES_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cipher.h" + +extern const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0; +extern const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0; +extern const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0; + +extern const srtp_cipher_test_case_t srtp_aes_gcm_128_test_case_0; +extern const srtp_cipher_test_case_t srtp_aes_gcm_256_test_case_0; + +#endif diff --git a/third_party/libsrtp/src/crypto/cipher/null_cipher.c b/third_party/libsrtp/src/crypto/cipher/null_cipher.c index 659add0d476d..969724611c42 100644 --- a/third_party/libsrtp/src/crypto/cipher/null_cipher.c +++ b/third_party/libsrtp/src/crypto/cipher/null_cipher.c @@ -97,7 +97,7 @@ 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(srtp_mod_cipher, "initializing null cipher", NULL); + debug_print0(srtp_mod_cipher, "initializing null cipher"); return srtp_err_status_ok; } diff --git a/third_party/libsrtp/src/crypto/hash/auth.c b/third_party/libsrtp/src/crypto/hash/auth.c index f19327dc8e99..9be0ccfd3690 100644 --- a/third_party/libsrtp/src/crypto/hash/auth.c +++ b/third_party/libsrtp/src/crypto/hash/auth.c @@ -123,6 +123,12 @@ srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at, return status; } + status = srtp_auth_start(a); + 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, diff --git a/third_party/libsrtp/src/crypto/hash/auth_test_cases.c b/third_party/libsrtp/src/crypto/hash/auth_test_cases.c new file mode 100644 index 000000000000..22b9418434ba --- /dev/null +++ b/third_party/libsrtp/src/crypto/hash/auth_test_cases.c @@ -0,0 +1,70 @@ +/* + * + * Copyright (c) 2013-2021, 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 "auth_test_cases.h" +#include + +/* 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 */ + +/* 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[20] = { + 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, + 0xf1, 0x46, 0xbe, 0x00 +}; +/* clang-format on */ + +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 */ +}; diff --git a/third_party/libsrtp/src/crypto/hash/auth_test_cases.h b/third_party/libsrtp/src/crypto/hash/auth_test_cases.h new file mode 100644 index 000000000000..9f37718205cc --- /dev/null +++ b/third_party/libsrtp/src/crypto/hash/auth_test_cases.h @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2013-2021, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AUTH_TEST_CASES_H +#define AUTH_TEST_CASES_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "auth.h" + +extern const srtp_auth_test_case_t srtp_hmac_test_case_0; + +#endif diff --git a/third_party/libsrtp/src/crypto/hash/hmac.c b/third_party/libsrtp/src/crypto/hash/hmac.c index 6e91468f36ce..269c3f6a7128 100644 --- a/third_party/libsrtp/src/crypto/hash/hmac.c +++ b/third_party/libsrtp/src/crypto/hash/hmac.c @@ -49,6 +49,7 @@ #include "hmac.h" #include "alloc.h" #include "cipher_types.h" +#include "auth_test_cases.h" /* the debug module for authentiation */ @@ -228,41 +229,6 @@ static srtp_err_status_t srtp_hmac_compute(void *statev, return srtp_err_status_ok; } -/* begin test case 0 */ -/* clang-format off */ -static const uint8_t srtp_hmac_test_case_0_key[20] = { - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b -}; -/* clang-format on */ - -/* 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[20] = { - 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 = { - 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 */ - static const char srtp_hmac_description[] = "hmac sha-1 authentication function"; diff --git a/third_party/libsrtp/src/crypto/hash/hmac_mbedtls.c b/third_party/libsrtp/src/crypto/hash/hmac_mbedtls.c new file mode 100644 index 000000000000..f710be9c7869 --- /dev/null +++ b/third_party/libsrtp/src/crypto/hash/hmac_mbedtls.c @@ -0,0 +1,221 @@ +/* + * hmac_mbedtls.c + * + * Implementation of hmac srtp_auth_type_t that leverages Mbedtls + * + * YongCheng Yang + */ +/* + * + * 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 +#endif + +#include "auth.h" +#include "alloc.h" +#include "err.h" /* for srtp_debug */ +#include "auth_test_cases.h" +#include + +#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 mbedtls" /* printable name for module */ +}; + +static srtp_err_status_t srtp_hmac_mbedtls_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 (key_len > SHA1_DIGEST_SIZE) { + return srtp_err_status_bad_param; + } + /* check output length - should be less than 20 bytes */ + if (out_len > SHA1_DIGEST_SIZE) { + return srtp_err_status_bad_param; + } + + *a = (srtp_auth_t *)srtp_crypto_alloc(sizeof(srtp_auth_t)); + if (*a == NULL) { + return srtp_err_status_alloc_fail; + } + // allocate the buffer of mbedtls context. + (*a)->state = srtp_crypto_alloc(sizeof(mbedtls_md_context_t)); + if ((*a)->state == NULL) { + srtp_crypto_free(*a); + *a = NULL; + return srtp_err_status_alloc_fail; + } + mbedtls_md_init((mbedtls_md_context_t *)(*a)->state); + + /* 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_mbedtls_dealloc(srtp_auth_t *a) +{ + mbedtls_md_context_t *hmac_ctx; + hmac_ctx = (mbedtls_md_context_t *)a->state; + mbedtls_md_free(hmac_ctx); + srtp_crypto_free(hmac_ctx); + /* zeroize entire state*/ + octet_string_set_to_zero(a, sizeof(srtp_auth_t)); + + /* free memory */ + srtp_crypto_free(a); + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_hmac_mbedtls_start(void *statev) +{ + mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; + if (mbedtls_md_hmac_reset(state) != 0) + return srtp_err_status_auth_fail; + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_hmac_mbedtls_init(void *statev, + const uint8_t *key, + int key_len) +{ + mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; + const mbedtls_md_info_t *info = NULL; + + info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + if (info == NULL) + return srtp_err_status_auth_fail; + + if (mbedtls_md_setup(state, info, 1) != 0) + return srtp_err_status_auth_fail; + + debug_print(srtp_mod_hmac, "mbedtls setup, name: %s", + mbedtls_md_get_name(info)); + debug_print(srtp_mod_hmac, "mbedtls setup, size: %d", + mbedtls_md_get_size(info)); + + if (mbedtls_md_hmac_starts(state, key, key_len) != 0) + return srtp_err_status_auth_fail; + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_hmac_mbedtls_update(void *statev, + const uint8_t *message, + int msg_octets) +{ + mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; + + debug_print(srtp_mod_hmac, "input: %s", + srtp_octet_string_hex_string(message, msg_octets)); + + if (mbedtls_md_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_mbedtls_compute(void *statev, + const uint8_t *message, + int msg_octets, + int tag_len, + uint8_t *result) +{ + mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; + uint8_t hash_value[SHA1_DIGEST_SIZE]; + int i; + + /* 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 (mbedtls_md_hmac_update(statev, message, msg_octets) != 0) + return srtp_err_status_auth_fail; + + if (mbedtls_md_hmac_finish(state, hash_value) != 0) + 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; +} + +/* end test case 0 */ + +static const char srtp_hmac_mbedtls_description[] = + "hmac sha-1 authentication function using mbedtls"; + +/* + * srtp_auth_type_t hmac is the hmac metaobject + */ + +const srtp_auth_type_t srtp_hmac = { + srtp_hmac_mbedtls_alloc, /* */ + srtp_hmac_mbedtls_dealloc, /* */ + srtp_hmac_mbedtls_init, /* */ + srtp_hmac_mbedtls_compute, /* */ + srtp_hmac_mbedtls_update, /* */ + srtp_hmac_mbedtls_start, /* */ + srtp_hmac_mbedtls_description, /* */ + &srtp_hmac_test_case_0, /* */ + SRTP_HMAC_SHA1 /* */ +}; diff --git a/third_party/libsrtp/src/crypto/hash/hmac_nss.c b/third_party/libsrtp/src/crypto/hash/hmac_nss.c new file mode 100644 index 000000000000..8d1e42f620de --- /dev/null +++ b/third_party/libsrtp/src/crypto/hash/hmac_nss.c @@ -0,0 +1,290 @@ +/* + * + * 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 +#endif + +#include "auth.h" +#include "alloc.h" +#include "err.h" /* for srtp_debug */ +#include "auth_test_cases.h" + +#define NSS_PKCS11_2_0_COMPAT 1 + +#include +#include + +#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 nss" /* printable name for module */ +}; + +typedef struct { + NSSInitContext *nss; + PK11SymKey *key; + PK11Context *ctx; +} srtp_hmac_nss_ctx_t; + +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; + srtp_hmac_nss_ctx_t *hmac; + NSSInitContext *nss; + + 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; + } + + /* 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_auth_fail; + } + + *a = (srtp_auth_t *)srtp_crypto_alloc(sizeof(srtp_auth_t)); + if (*a == NULL) { + NSS_ShutdownContext(nss); + return srtp_err_status_alloc_fail; + } + + hmac = + (srtp_hmac_nss_ctx_t *)srtp_crypto_alloc(sizeof(srtp_hmac_nss_ctx_t)); + if (hmac == NULL) { + NSS_ShutdownContext(nss); + srtp_crypto_free(*a); + *a = NULL; + return srtp_err_status_alloc_fail; + } + + hmac->nss = nss; + hmac->key = NULL; + hmac->ctx = NULL; + + /* set pointers */ + (*a)->state = hmac; + (*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) +{ + srtp_hmac_nss_ctx_t *hmac; + + hmac = (srtp_hmac_nss_ctx_t *)a->state; + if (hmac) { + /* free any PK11 values that have been created */ + if (hmac->key) { + PK11_FreeSymKey(hmac->key); + hmac->key = NULL; + } + + if (hmac->ctx) { + PK11_DestroyContext(hmac->ctx, PR_TRUE); + hmac->ctx = NULL; + } + + if (hmac->nss) { + NSS_ShutdownContext(hmac->nss); + hmac->nss = NULL; + } + + /* zeroize everything */ + octet_string_set_to_zero(hmac, sizeof(srtp_hmac_nss_ctx_t)); + srtp_crypto_free(hmac); + } + + /* free memory */ + srtp_crypto_free(a); + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_hmac_start(void *statev) +{ + srtp_hmac_nss_ctx_t *hmac; + hmac = (srtp_hmac_nss_ctx_t *)statev; + + if (PK11_DigestBegin(hmac->ctx) != SECSuccess) { + 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) +{ + srtp_hmac_nss_ctx_t *hmac; + hmac = (srtp_hmac_nss_ctx_t *)statev; + PK11SymKey *sym_key; + PK11Context *ctx; + + if (hmac->ctx) { + PK11_DestroyContext(hmac->ctx, PR_TRUE); + hmac->ctx = NULL; + } + + if (hmac->key) { + PK11_FreeSymKey(hmac->key); + hmac->key = NULL; + } + + PK11SlotInfo *slot = PK11_GetBestSlot(CKM_SHA_1_HMAC, NULL); + if (!slot) { + return srtp_err_status_bad_param; + } + + SECItem key_item = { siBuffer, (unsigned char *)key, key_len }; + sym_key = PK11_ImportSymKey(slot, CKM_SHA_1_HMAC, PK11_OriginUnwrap, + CKA_SIGN, &key_item, NULL); + PK11_FreeSlot(slot); + + if (!sym_key) { + return srtp_err_status_auth_fail; + } + + SECItem param_item = { siBuffer, NULL, 0 }; + ctx = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC, CKA_SIGN, sym_key, + ¶m_item); + if (!ctx) { + PK11_FreeSymKey(sym_key); + return srtp_err_status_auth_fail; + } + + hmac->key = sym_key; + hmac->ctx = ctx; + + return srtp_err_status_ok; +} + +static srtp_err_status_t srtp_hmac_update(void *statev, + const uint8_t *message, + int msg_octets) +{ + srtp_hmac_nss_ctx_t *hmac; + hmac = (srtp_hmac_nss_ctx_t *)statev; + + debug_print(srtp_mod_hmac, "input: %s", + srtp_octet_string_hex_string(message, msg_octets)); + + if (PK11_DigestOp(hmac->ctx, message, msg_octets) != SECSuccess) { + 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) +{ + srtp_hmac_nss_ctx_t *hmac; + hmac = (srtp_hmac_nss_ctx_t *)statev; + uint8_t hash_value[SHA1_DIGEST_SIZE]; + int i; + unsigned int len; + + debug_print(srtp_mod_hmac, "input: %s", + srtp_octet_string_hex_string(message, msg_octets)); + + /* 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; + } + + if (PK11_DigestOp(hmac->ctx, message, msg_octets) != SECSuccess) { + return srtp_err_status_auth_fail; + } + + if (PK11_DigestFinal(hmac->ctx, hash_value, &len, SHA1_DIGEST_SIZE) != + SECSuccess) { + 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; +} + +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/third_party/libsrtp/src/crypto/hash/hmac_ossl.c b/third_party/libsrtp/src/crypto/hash/hmac_ossl.c index 8146438b051b..ee6b0b5851c8 100644 --- a/third_party/libsrtp/src/crypto/hash/hmac_ossl.c +++ b/third_party/libsrtp/src/crypto/hash/hmac_ossl.c @@ -49,6 +49,7 @@ #include "auth.h" #include "alloc.h" #include "err.h" /* for srtp_debug */ +#include "auth_test_cases.h" #include #include @@ -192,6 +193,9 @@ static srtp_err_status_t srtp_hmac_compute(void *statev, int i; unsigned int len; + debug_print(srtp_mod_hmac, "input: %s", + srtp_octet_string_hex_string(message, msg_octets)); + /* 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; @@ -218,41 +222,6 @@ static srtp_err_status_t srtp_hmac_compute(void *statev, 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"; diff --git a/third_party/libsrtp/src/crypto/hash/sha1.c b/third_party/libsrtp/src/crypto/hash/sha1.c index 91ebd1e396ca..901a933250b2 100644 --- a/third_party/libsrtp/src/crypto/hash/sha1.c +++ b/third_party/libsrtp/src/crypto/hash/sha1.c @@ -76,15 +76,6 @@ 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 srtp_sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) -{ - srtp_sha1_ctx_t ctx; - - srtp_sha1_init(&ctx); - srtp_sha1_update(&ctx, msg, octets_in_msg); - srtp_sha1_final(&ctx, hash_value); -} - /* * 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 @@ -261,14 +252,13 @@ void srtp_sha1_update(srtp_sha1_ctx_t *ctx, /* process a whole block */ - debug_print(srtp_mod_sha1, "(update) running srtp_sha1_core()", - NULL); + debug_print0(srtp_mod_sha1, "(update) running srtp_sha1_core()"); srtp_sha1_core(ctx->M, ctx->H); } else { - debug_print(srtp_mod_sha1, "(update) not running srtp_sha1_core()", - NULL); + debug_print0(srtp_mod_sha1, + "(update) not running srtp_sha1_core()"); for (i = ctx->octets_in_buffer; i < (ctx->octets_in_buffer + octets_in_msg); i++) { @@ -391,11 +381,10 @@ void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t output[5]) ctx->H[4] += E; } - debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core()", NULL); + debug_print0(srtp_mod_sha1, "(final) running srtp_sha1_core()"); if (ctx->octets_in_buffer >= 56) { - debug_print(srtp_mod_sha1, "(final) running srtp_sha1_core() again", - NULL); + debug_print0(srtp_mod_sha1, "(final) running srtp_sha1_core() again"); /* we need to do one final run of the compression algo */ diff --git a/third_party/libsrtp/src/crypto/include/.cvsignore b/third_party/libsrtp/src/crypto/include/.cvsignore new file mode 100644 index 000000000000..0e56cf2f8c1e --- /dev/null +++ b/third_party/libsrtp/src/crypto/include/.cvsignore @@ -0,0 +1 @@ +config.h diff --git a/third_party/libsrtp/src/crypto/include/aes_gcm.h b/third_party/libsrtp/src/crypto/include/aes_gcm.h index f59d04dbca58..cd0dceed3eec 100644 --- a/third_party/libsrtp/src/crypto/include/aes_gcm.h +++ b/third_party/libsrtp/src/crypto/include/aes_gcm.h @@ -64,8 +64,30 @@ typedef struct { #endif /* OPENSSL */ +#ifdef MBEDTLS +#define MAX_AD_SIZE 2048 +#include +#include + +typedef struct { + int key_size; + int tag_len; + int aad_size; + int iv_len; + uint8_t iv[12]; + uint8_t tag[16]; + uint8_t aad[MAX_AD_SIZE]; + mbedtls_gcm_context *ctx; + srtp_cipher_direction_t dir; +} srtp_aes_gcm_ctx_t; + +#endif /* MBEDTLS */ + #ifdef NSS +#define NSS_PKCS11_2_0_COMPAT 1 + +#include #include #define MAX_AD_SIZE 2048 @@ -74,6 +96,7 @@ 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]; diff --git a/third_party/libsrtp/src/crypto/include/aes_icm_ext.h b/third_party/libsrtp/src/crypto/include/aes_icm_ext.h index 6518d40b06b3..5b21c95dded1 100644 --- a/third_party/libsrtp/src/crypto/include/aes_icm_ext.h +++ b/third_party/libsrtp/src/crypto/include/aes_icm_ext.h @@ -63,8 +63,25 @@ typedef struct { #endif /* OPENSSL */ +#ifdef MBEDTLS + +#include +typedef struct { + v128_t counter; /* holds the counter value */ + v128_t offset; /* initial offset value */ + v128_t stream_block; + size_t nc_off; + int key_size; + mbedtls_aes_context *ctx; +} srtp_aes_icm_ctx_t; + +#endif /* MBEDTLS */ + #ifdef NSS +#define NSS_PKCS11_2_0_COMPAT 1 + +#include #include typedef struct { @@ -72,6 +89,7 @@ typedef struct { v128_t offset; int key_size; uint8_t iv[16]; + NSSInitContext *nss; PK11SymKey *key; PK11Context *ctx; } srtp_aes_icm_ctx_t; diff --git a/third_party/libsrtp/src/crypto/include/cipher_priv.h b/third_party/libsrtp/src/crypto/include/cipher_priv.h new file mode 100644 index 000000000000..46848ea7c642 --- /dev/null +++ b/third_party/libsrtp/src/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/third_party/libsrtp/src/crypto/include/cipher_types.h b/third_party/libsrtp/src/crypto/include/cipher_types.h index 18f0328fbb6c..28250d1624fa 100644 --- a/third_party/libsrtp/src/crypto/include/cipher_types.h +++ b/third_party/libsrtp/src/crypto/include/cipher_types.h @@ -66,19 +66,15 @@ extern const srtp_auth_type_t srtp_hmac; 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 + +#if defined(OPENSSL) || defined(MBEDTLS) || defined(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/third_party/libsrtp/src/crypto/include/datatypes.h b/third_party/libsrtp/src/crypto/include/datatypes.h index 182cca25b9d1..5164cf002158 100644 --- a/third_party/libsrtp/src/crypto/include/datatypes.h +++ b/third_party/libsrtp/src/crypto/include/datatypes.h @@ -66,27 +66,6 @@ extern "C" { #endif -/* if DATATYPES_USE_MACROS is defined, then little functions are macros */ -#define DATATYPES_USE_MACROS - -typedef union { - uint8_t v8[2]; - uint16_t value; -} v16_t; - -typedef union { - uint8_t v8[4]; - uint16_t v16[2]; - uint32_t value; -} v32_t; - -typedef union { - uint8_t v8[8]; - uint16_t v16[4]; - uint32_t v32[2]; - uint64_t value; -} v64_t; - typedef union { uint8_t v8[16]; uint16_t v16[8]; @@ -94,26 +73,6 @@ typedef union { 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_minus_one(X) ((X) ? -1 : 1) /* (-1)^X */ - -/* - * octet_get_weight(x) returns the hamming weight (number of bits equal to - * one) in the octet x - */ - -int octet_get_weight(uint8_t octet); - #define MAX_PRINT_STRING_LEN 1024 char *srtp_octet_string_hex_string(const void *str, int length); @@ -126,56 +85,31 @@ void v128_copy_octet_string(v128_t *x, const uint8_t s[16]); void v128_left_shift(v128_t *x, int shift_index); -void v128_right_shift(v128_t *x, int shift_index); - /* * 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) \ +#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) \ +#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) \ +#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]) - /* 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])) - #ifdef NO_64BIT_MATH -#define _v128_xor_eq(z, x) \ +#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) \ +#define v128_xor_eq(z, x) \ ((z)->v64[0] ^= (x)->v64[0], (z)->v64[1] ^= (x)->v64[1]) #endif @@ -188,66 +122,22 @@ void v128_right_shift(v128_t *x, int shift_index); 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) \ +#define v128_set_bit(x, bit) \ ((((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit)&31)))) -#define _v128_clear_bit(x, bit) \ +#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)) - -#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. It returns 0 otherwise. The running time of the + * 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(uint8_t *a, uint8_t *b, int len); +int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len); /* * A portable way to zero out memory as recommended by @@ -278,7 +168,7 @@ void octet_string_set_to_zero(void *s, size_t len); #define be64_to_cpu(x) bswap_64((x)) #else /* WORDS_BIGENDIAN */ -#if defined(__GNUC__) && defined(HAVE_X86) +#if defined(__GNUC__) && (defined(HAVE_X86) || defined(__x86_64__)) /* Fall back. */ static inline uint32_t be32_to_cpu(uint32_t v) { @@ -331,35 +221,13 @@ typedef struct { uint32_t *word; } bitvector_t; -#define _bitvector_get_bit(v, bit_index) \ +#define bitvector_get_bit(v, bit_index) \ (((((v)->word[((bit_index) >> 5)]) >> ((bit_index)&31)) & 1)) -#define _bitvector_set_bit(v, bit_index) \ +#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 +#define bitvector_get_length(v) (((v)->length)) int bitvector_alloc(bitvector_t *v, unsigned long length); @@ -369,8 +237,6 @@ 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 diff --git a/third_party/libsrtp/src/crypto/include/err.h b/third_party/libsrtp/src/crypto/include/err.h index 66a1023ec869..326f5e96b77c 100644 --- a/third_party/libsrtp/src/crypto/include/err.h +++ b/third_party/libsrtp/src/crypto/include/err.h @@ -109,6 +109,8 @@ typedef struct { #ifdef ENABLE_DEBUG_LOGGING +#define debug_print0(mod, format) \ + srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name) #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) \ @@ -117,6 +119,9 @@ typedef struct { #else +#define debug_print0(mod, format) \ + if (mod.on) \ + srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name) #define debug_print(mod, format, arg) \ if (mod.on) \ srtp_err_report(srtp_err_level_debug, ("%s: " format "\n"), mod.name, arg) diff --git a/third_party/libsrtp/src/crypto/include/key.h b/third_party/libsrtp/src/crypto/include/key.h index 3498114b0502..4164722c7cc6 100644 --- a/third_party/libsrtp/src/crypto/include/key.h +++ b/third_party/libsrtp/src/crypto/include/key.h @@ -66,8 +66,6 @@ srtp_err_status_t srtp_key_limit_set(srtp_key_limit_t key, srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original, srtp_key_limit_t *new_key); -srtp_err_status_t srtp_key_limit_check(const srtp_key_limit_t key); - srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key); typedef enum { diff --git a/third_party/libsrtp/src/crypto/include/null_auth.h b/third_party/libsrtp/src/crypto/include/null_auth.h index 490dd7bc0f8d..0e57d6706164 100644 --- a/third_party/libsrtp/src/crypto/include/null_auth.h +++ b/third_party/libsrtp/src/crypto/include/null_auth.h @@ -55,17 +55,6 @@ typedef struct { char foo; } srtp_null_auth_ctx_t; -#if 0 -srtp_err_status_t srtp_null_auth_alloc(srtp_auth_t **a, int key_len, int out_len); - -srtp_err_status_t srtp_null_auth_dealloc(srtp_auth_t *a); - -srtp_err_status_t srtp_null_auth_init(srtp_null_auth_ctx_t *state, const uint8_t *key, int key_len); - -srtp_err_status_t srtp_null_auth_compute(srtp_null_auth_ctx_t *state, uint8_t *message, int msg_octets, int tag_len, uint8_t *result); - -#endif - #ifdef __cplusplus } #endif diff --git a/third_party/libsrtp/src/crypto/include/rdb.h b/third_party/libsrtp/src/crypto/include/rdb.h index 98314c1f3ee0..208dff3ff10d 100644 --- a/third_party/libsrtp/src/crypto/include/rdb.h +++ b/third_party/libsrtp/src/crypto/include/rdb.h @@ -64,8 +64,6 @@ typedef struct { v128_t bitmask; } srtp_rdb_t; -#define rdb_bits_in_bitmask (8 * sizeof(v128_t)) - /* * srtp_rdb_init * diff --git a/third_party/libsrtp/src/crypto/include/sha1.h b/third_party/libsrtp/src/crypto/include/sha1.h index 933c1466a3cf..c9bf592dff35 100644 --- a/third_party/libsrtp/src/crypto/include/sha1.h +++ b/third_party/libsrtp/src/crypto/include/sha1.h @@ -52,88 +52,12 @@ #endif #include "err.h" -#ifdef OPENSSL -#include -#include -#else #include "datatypes.h" -#endif #ifdef __cplusplus extern "C" { #endif -#ifdef OPENSSL - -/* - * srtp_sha1_init(&ctx) initializes the SHA1 context ctx - * - * srtp_sha1_update(&ctx, msg, len) hashes the len octets starting at msg - * into the SHA1 context - * - * srtp_sha1_final(&ctx, output) performs the final processing of the SHA1 - * context and writes the result to the 20 octets at output - * - * Return values are ignored on the EVP functions since all three - * of these functions return void. - * - */ - -/* 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 - -typedef EVP_MD_CTX srtp_sha1_ctx_t; - -static inline void srtp_sha1_init(srtp_sha1_ctx_t *ctx) -{ - EVP_MD_CTX_init(ctx); - EVP_DigestInit(ctx, EVP_sha1()); -} - -static inline void srtp_sha1_update(srtp_sha1_ctx_t *ctx, - const uint8_t *M, - int octets_in_msg) -{ - EVP_DigestUpdate(ctx, M, octets_in_msg); -} - -static inline void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output) -{ - unsigned int len = 0; - - EVP_DigestFinal(ctx, (unsigned char *)output, &len); - EVP_MD_CTX_cleanup(ctx); -} - -#else - -typedef EVP_MD_CTX *srtp_sha1_ctx_t; - -static inline void srtp_sha1_init(srtp_sha1_ctx_t *ctx) -{ - *ctx = EVP_MD_CTX_new(); - EVP_DigestInit(*ctx, EVP_sha1()); -} - -static inline void srtp_sha1_update(srtp_sha1_ctx_t *ctx, - const uint8_t *M, - int octets_in_msg) -{ - EVP_DigestUpdate(*ctx, M, octets_in_msg); -} - -static inline void srtp_sha1_final(srtp_sha1_ctx_t *ctx, uint32_t *output) -{ - unsigned int len = 0; - - EVP_DigestFinal(*ctx, (unsigned char *)output, &len); - EVP_MD_CTX_free(*ctx); -} -#endif - -#else - typedef struct { uint32_t H[5]; /* state vector */ uint32_t M[16]; /* message buffer */ @@ -159,24 +83,6 @@ void srtp_sha1_update(srtp_sha1_ctx_t *ctx, 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. - */ - -/* - * 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]); - -#endif /* else OPENSSL */ - #ifdef __cplusplus } #endif diff --git a/third_party/libsrtp/src/crypto/kernel/alloc.c b/third_party/libsrtp/src/crypto/kernel/alloc.c index dbe58266f43a..3ebc31525911 100644 --- a/third_party/libsrtp/src/crypto/kernel/alloc.c +++ b/third_party/libsrtp/src/crypto/kernel/alloc.c @@ -80,7 +80,7 @@ void *srtp_crypto_alloc(size_t 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", + debug_print(srtp_mod_alloc, "allocation failed (asked for %zu bytes)\n", size); } diff --git a/third_party/libsrtp/src/crypto/kernel/crypto_kernel.c b/third_party/libsrtp/src/crypto/kernel/crypto_kernel.c index df6af7da889f..764e7ecfa00e 100644 --- a/third_party/libsrtp/src/crypto/kernel/crypto_kernel.c +++ b/third_party/libsrtp/src/crypto/kernel/crypto_kernel.c @@ -101,10 +101,6 @@ srtp_err_status_t srtp_crypto_kernel_init() 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; @@ -277,7 +273,8 @@ static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type( srtp_cipher_type_id_t id, int replace) { - srtp_kernel_cipher_type_t *ctype, *new_ctype; + srtp_kernel_cipher_type_t *ctype; + srtp_kernel_cipher_type_t *new_ctype = NULL; srtp_err_status_t status; /* defensive coding */ @@ -354,7 +351,8 @@ srtp_err_status_t srtp_crypto_kernel_do_load_auth_type( srtp_auth_type_id_t id, int replace) { - srtp_kernel_auth_type_t *atype, *new_atype; + srtp_kernel_auth_type_t *atype; + srtp_kernel_auth_type_t *new_atype = NULL; srtp_err_status_t status; /* defensive coding */ diff --git a/third_party/libsrtp/src/crypto/kernel/err.c b/third_party/libsrtp/src/crypto/kernel/err.c index f443549e5a44..9db5bfb43276 100644 --- a/third_party/libsrtp/src/crypto/kernel/err.c +++ b/third_party/libsrtp/src/crypto/kernel/err.c @@ -80,6 +80,7 @@ srtp_err_status_t srtp_install_err_report_handler( 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); @@ -88,7 +89,6 @@ void srtp_err_report(srtp_err_reporting_level_t level, const char *format, ...) } if (srtp_err_report_handler != NULL) { va_start(args, format); - char msg[512]; if (vsnprintf(msg, sizeof(msg), format, args) > 0) { /* strip trailing \n, callback should not have one */ size_t l = strlen(msg); diff --git a/third_party/libsrtp/src/crypto/kernel/key.c b/third_party/libsrtp/src/crypto/kernel/key.c index 04661950461f..5e6a18872657 100644 --- a/third_party/libsrtp/src/crypto/kernel/key.c +++ b/third_party/libsrtp/src/crypto/kernel/key.c @@ -77,14 +77,6 @@ srtp_err_status_t srtp_key_limit_clone(srtp_key_limit_t original, return srtp_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; -} - srtp_key_event_t srtp_key_limit_update(srtp_key_limit_t key) { #ifdef NO_64BIT_MATH diff --git a/third_party/libsrtp/src/crypto/math/datatypes.c b/third_party/libsrtp/src/crypto/math/datatypes.c index 85c1cbf29265..0eb9d919b5f1 100644 --- a/third_party/libsrtp/src/crypto/math/datatypes.c +++ b/third_party/libsrtp/src/crypto/math/datatypes.c @@ -53,33 +53,14 @@ #include "datatypes.h" -static const int8_t octet_weight[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, - 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, - 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, - 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -int octet_get_weight(uint8_t octet) -{ - return (int)octet_weight[octet]; -} - /* * bit_string is a buffer that is used to hold output strings, e.g. * for printing. */ /* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */ - -char bit_string[MAX_PRINT_STRING_LEN]; +/* include space for null terminator */ +static char bit_string[MAX_PRINT_STRING_LEN + 1]; uint8_t srtp_nibble_to_hex_char(uint8_t nibble) { @@ -172,104 +153,6 @@ void v128_copy_octet_string(v128_t *x, const uint8_t s[16]) #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_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_xor_eq(v128_t *x, const v128_t *y) -{ - return _v128_xor_eq(x, y); -} - -int v128_get_bit(const v128_t *x, int i) -{ - return _v128_get_bit(x, i); -} - -void v128_set_bit(v128_t *x, int i) -{ - _v128_set_bit(x, i); -} - -void v128_clear_bit(v128_t *x, int i) -{ - _v128_clear_bit(x, i); -} - -void v128_set_bit_to(v128_t *x, int i, int y) -{ - _v128_set_bit_to(x, i, y); -} - -#endif /* DATATYPES_USE_MACROS */ - -void v128_right_shift(v128_t *x, int shift) -{ - const int base_index = shift >> 5; - const int bit_index = shift & 31; - int i, from; - uint32_t b; - - if (shift > 127) { - v128_set_to_zero(x); - return; - } - - 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 shift) { int i; @@ -298,25 +181,6 @@ void v128_left_shift(v128_t *x, int shift) /* functions manipulating bitvector_t */ -#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 bitvector_set_bit(bitvector_t *v, int bit_index) -{ - _bitvector_set_bit(v, bit_index); -} - -void bitvector_clear_bit(bitvector_t *v, int bit_index) -{ - _bitvector_clear_bit(v, bit_index); -} - -#endif /* DATATYPES_USE_MACROS */ - int bitvector_alloc(bitvector_t *v, unsigned long length) { unsigned long l; @@ -361,27 +225,6 @@ void bitvector_set_to_zero(bitvector_t *x) 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; @@ -410,7 +253,7 @@ void bitvector_left_shift(bitvector_t *x, int shift) x->word[i] = 0; } -int octet_string_is_eq(uint8_t *a, uint8_t *b, int len) +int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { uint8_t *end = b + len; uint8_t accumulator = 0; @@ -442,49 +285,3 @@ void octet_string_set_to_zero(void *s, size_t len) 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/third_party/libsrtp/src/crypto/replay/rdb.c b/third_party/libsrtp/src/crypto/replay/rdb.c index ab1c7b55b6d8..d8c2b3838e47 100644 --- a/third_party/libsrtp/src/crypto/replay/rdb.c +++ b/third_party/libsrtp/src/crypto/replay/rdb.c @@ -49,6 +49,8 @@ #include "rdb.h" +#define rdb_bits_in_bitmask (8 * sizeof(v128_t)) + /* * this implementation of a replay database works as follows: * diff --git a/third_party/libsrtp/src/crypto/test/.cvsignore b/third_party/libsrtp/src/crypto/test/.cvsignore new file mode 100644 index 000000000000..888bf597e1ea --- /dev/null +++ b/third_party/libsrtp/src/crypto/test/.cvsignore @@ -0,0 +1,8 @@ +aes_calc +cipher_driver +datatypes_driver +env +kernel_driver +rand_gen +sha1_driver +stat_driver diff --git a/third_party/libsrtp/src/crypto/test/aes_calc.c b/third_party/libsrtp/src/crypto/test/aes_calc.c index b362fd57fccb..3d0d5cf36b89 100644 --- a/third_party/libsrtp/src/crypto/test/aes_calc.c +++ b/third_party/libsrtp/src/crypto/test/aes_calc.c @@ -67,7 +67,7 @@ void usage(char *prog_name) { - printf("usage: %s [-v]\n", prog_name); + printf("usage: %s <key> <plaintext> [<ciphertext>] [-v]\n", prog_name); exit(255); } @@ -75,6 +75,8 @@ void usage(char *prog_name) int main(int argc, char *argv[]) { + const char *expected_ciphertext = NULL; + const char *ciphertext = NULL; v128_t data; uint8_t key[AES_MAX_KEY_LEN]; srtp_aes_expanded_key_t exp_key; @@ -82,22 +84,26 @@ int main(int argc, char *argv[]) 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; - } else { - /* unrecognized flag, complain and exit */ - usage(argv[0]); - } - } else { + /* -v must be last if it's passed */ + if (argc > 0 && strncmp(argv[argc - 1], "-v", 2) == 0) { + /* we're in verbose mode */ + verbose = 1; + --argc; + } + + if (argc < 3 || argc > 4) { /* we've been fed the wrong number of arguments - compain and exit */ usage(argv[0]); } + if (argc == 4) { + /* we're being passed the ciphertext to check (in unit test mode) */ + expected_ciphertext = argv[3]; + if (strlen(expected_ciphertext) != 16 * 2) { + usage(argv[0]); + } + } + /* read in key, checking length */ if (strlen(argv[1]) > AES_MAX_KEY_LEN * 2) { fprintf(stderr, "error: too many digits in key " @@ -151,7 +157,16 @@ int main(int argc, char *argv[]) printf("key:\t\t%s\n", octet_string_hex_string(key, key_len)); printf("ciphertext:\t"); } - printf("%s\n", v128_hex_string(&data)); + + ciphertext = v128_hex_string(&data); + printf("%s\n", ciphertext); + + if (expected_ciphertext && strcmp(ciphertext, expected_ciphertext) != 0) { + fprintf(stderr, "error: calculated ciphertext %s does not match " + "expected ciphertext %s\n", + ciphertext, expected_ciphertext); + exit(1); + } return 0; } diff --git a/third_party/libsrtp/src/crypto/test/cipher_driver.c b/third_party/libsrtp/src/crypto/test/cipher_driver.c index 4959c90c02b8..4fbcd95e3930 100644 --- a/third_party/libsrtp/src/crypto/test/cipher_driver.c +++ b/third_party/libsrtp/src/crypto/test/cipher_driver.c @@ -47,16 +47,11 @@ #include <config.h> #endif -#include <stdio.h> /* for printf() */ -#include <stdlib.h> /* for rand() */ +#include <stdio.h> /* for printf() */ #include "getopt_s.h" #include "cipher.h" -#ifdef GCM -#include "aes_icm_ext.h" -#include "aes_gcm.h" -#else -#include "aes_icm.h" -#endif +#include "cipher_priv.h" +#include "datatypes.h" #define PRINT_DEBUG 0 @@ -390,7 +385,7 @@ srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c) end = buffer1 + buflen; while (current < end) { /* choose a short length */ - len = rand() & 0x01f; + len = srtp_cipher_rand_u32_for_tests() & 0x01f; /* make sure that len doesn't cause us to overreach the buffer */ if (current + len > end) @@ -473,9 +468,8 @@ srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***ca, return status; /* generate random key and initialize cipher */ - for (j = 0; j < klen; j++) - key[j] = (uint8_t)rand(); - for (; j < klen_pad; j++) + 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) @@ -529,7 +523,7 @@ uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[], v128_t nonce; clock_t timer; unsigned char *enc_buf; - int cipher_index = rand() % num_cipher; + int cipher_index = srtp_cipher_rand_u32_for_tests() % num_cipher; /* Over-alloc, for NIST CBC padding */ enc_buf = srtp_crypto_alloc(octets_in_buffer + 17); diff --git a/third_party/libsrtp/src/crypto/test/datatypes_driver.c b/third_party/libsrtp/src/crypto/test/datatypes_driver.c index 96379befe15d..db1be7f6680e 100644 --- a/third_party/libsrtp/src/crypto/test/datatypes_driver.c +++ b/third_party/libsrtp/src/crypto/test/datatypes_driver.c @@ -100,13 +100,6 @@ int main(void) } 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); @@ -148,33 +141,6 @@ void byte_order(void) { int i; v128_t e; -#if 0 - v16_t b; - v32_t c; - v64_t d; - - for (i=0; i < sizeof(b); i++) - b.octet[i] = i; - for (i=0; i < sizeof(c); i++) - 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++) diff --git a/third_party/libsrtp/src/crypto/test/kernel_driver.c b/third_party/libsrtp/src/crypto/test/kernel_driver.c index d29405a9717d..929a2470af5a 100644 --- a/third_party/libsrtp/src/crypto/test/kernel_driver.c +++ b/third_party/libsrtp/src/crypto/test/kernel_driver.c @@ -113,15 +113,3 @@ int main(int argc, char *argv[]) return 0; } - -/* - * crypto_kernel_cipher_test() is a test of the cipher interface - * of the crypto_kernel - */ - -srtp_err_status_t crypto_kernel_cipher_test(void) -{ - /* not implemented yet! */ - - return srtp_err_status_ok; -} diff --git a/third_party/libsrtp/src/crypto/test/meson.build b/third_party/libsrtp/src/crypto/test/meson.build new file mode 100644 index 000000000000..533431c54e16 --- /dev/null +++ b/third_party/libsrtp/src/crypto/test/meson.build @@ -0,0 +1,41 @@ +# crypto test suite + +test_apps = [ + 'cipher_driver', + 'datatypes_driver', + 'kernel_driver', + 'env', +] + +if not use_openssl and not use_nss + test_apps += ['sha1_driver'] +endif + +foreach test_name : test_apps + test_exe = executable(test_name, + '@0@.c'.format(test_name), '../../test/getopt_s.c', '../../test/util.c', + include_directories: [config_incs, crypto_incs, srtp2_incs, test_incs], + dependencies: [srtp2_deps, syslibs], + link_with: libsrtp2_for_tests) + test(test_name, test_exe, args: ['-v']) +endforeach + +if not use_openssl and not use_nss + test_exe = executable('aes_calc', + 'aes_calc.c', '../../test/getopt_s.c', '../../test/util.c', + include_directories: [config_incs, crypto_incs, srtp2_incs, test_incs], + dependencies: [srtp2_deps, syslibs], + link_with: libsrtp2_for_tests) + + # data values used to test the aes_calc application for AES-128 + k128 = '000102030405060708090a0b0c0d0e0f' + p128 = '00112233445566778899aabbccddeeff' + c128 = '69c4e0d86a7b0430d8cdb78070b4c55a' + test('aes_calc_128', test_exe, args: [k128, p128, c128]) + + # data values used to test the aes_calc application for AES-256 + k256 = '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' + p256 = '00112233445566778899aabbccddeeff' + c256 = '8ea2b7ca516745bfeafc49904b496089' + test('aes_calc_256', test_exe, args: [k256, p256, c256]) +endif diff --git a/third_party/libsrtp/src/include/srtp.h b/third_party/libsrtp/src/include/srtp.h index 1fdd6c3affd8..fa34daf6413c 100644 --- a/third_party/libsrtp/src/include/srtp.h +++ b/third_party/libsrtp/src/include/srtp.h @@ -86,7 +86,7 @@ extern "C" { /** * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer * (authentication tag and MKI) supported by libSRTP. This value is - * the maixmum number of octets that will be added to an RTP packet by + * the maximum number of octets that will be added to an RTP packet by * srtp_protect(). * * @brief the maximum number of octets added by srtp_protect(). @@ -130,7 +130,7 @@ extern "C" { * * 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, + * SRTP_NULL_CIPHER is available; this cipher leaves the data unchanged, * and can be selected to indicate that no encryption is to take * place. * @@ -145,7 +145,7 @@ typedef uint32_t srtp_cipher_type_id_t; * * 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, + * available; this authentication function performs no computation, * and can be selected to indicate that no authentication is to take * place. * @@ -242,7 +242,7 @@ typedef struct srtp_crypto_policy_t { * @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. + * @ref srtp_policy_t for more information. */ typedef enum { ssrc_undefined = 0, /**< Indicates an undefined SSRC type. */ @@ -270,16 +270,6 @@ typedef struct { /**< wildcard */ } srtp_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 srtp_master_key_t represents a master key. There will * be a Master Key Index and the Master Key associated with the @@ -329,8 +319,8 @@ typedef struct srtp_policy_t { /**< 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) */ + void *deprecated_ekt; /**< DEPRECATED: pointer to the EKT */ + /**< policy structure for this stream */ unsigned long window_size; /**< The window size to use for replay */ /**< protection. */ int allow_repeat_tx; /**< Whether retransmissions of */ @@ -350,7 +340,7 @@ typedef struct 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 intentionally opaque in * order to separate the interface from the implementation. * * An SRTP session consists of all of the traffic sent to the RTP and @@ -581,7 +571,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_t ctx, * have its `next' field set to NULL. * * @return - * - srtp_err_status_ok if creation succeded. + * - srtp_err_status_ok if creation succeeded. * - srtp_err_status_alloc_fail if allocation failed. * - srtp_err_status_init_fail if initialization failed. */ @@ -597,7 +587,7 @@ srtp_err_status_t srtp_create(srtp_t *session, const srtp_policy_t *policy); * stream. * * @return values: - * - srtp_err_status_ok if stream creation succeded. + * - srtp_err_status_ok if stream creation succeeded. * - srtp_err_status_alloc_fail if stream allocation failed * - srtp_err_status_init_fail if stream initialization failed. */ @@ -620,18 +610,18 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy); * session. * * @return - * - srtp_err_status_ok if the stream deallocation succeded. + * - srtp_err_status_ok if the stream deallocation succeeded. * - [other] otherwise. * */ srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc); /** - * @brief srtp_update() udpates all streams in the session. + * @brief srtp_update() updates 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 + * and key. The existing ROC value of all streams will be * preserved. * * @param session is the SRTP session that contains the streams @@ -644,7 +634,7 @@ srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc); * have its `next' field set to NULL. * * @return - * - srtp_err_status_ok if stream creation succeded. + * - srtp_err_status_ok if stream creation succeed. * - srtp_err_status_alloc_fail if stream allocation failed * - srtp_err_status_init_fail if stream initialization failed. * - [other] otherwise. @@ -653,11 +643,11 @@ srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc); srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy); /** - * @brief srtp_update_stream() udpates a SRTP stream. + * @brief srtp_update_stream() updates 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 + * policy and key. The existing ROC value of all stream(s) will * be preserved. * * @param session is the SRTP session that contains the streams @@ -667,7 +657,7 @@ srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy); * for the session. * * @return - * - srtp_err_status_ok if stream creation succeded. + * - srtp_err_status_ok if stream creation succeeded. * - srtp_err_status_alloc_fail if stream allocation failed * - srtp_err_status_init_fail if stream initialization failed. * - [other] otherwise. @@ -682,14 +672,14 @@ srtp_err_status_t srtp_update_stream(srtp_t session, * * @param p is a pointer to the policy structure to be set * - * The function call crypto_policy_set_rtp_default(&p) sets the - * crypto_policy_t at location p to the SRTP default policy for RTP + * 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. * @@ -802,7 +792,7 @@ void srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *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. + * there is a requirement to forgo encryption. * * This function is a convenience that helps to avoid dealing directly * with the policy data structure. You are encouraged to initialize @@ -811,7 +801,7 @@ void srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p); * 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. + * requirement to forgo encryption. * * @return void. * @@ -827,7 +817,7 @@ void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p); * 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. + * troubleshooting. * * This function is a convenience that helps to avoid dealing directly * with the policy data structure. You are encouraged to initialize @@ -836,7 +826,7 @@ void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p); * 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. + * requirement to forgo encryption and authentication. * * @return void. * @@ -934,7 +924,7 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p); * @param p is a pointer to the policy structure to be set * * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&p) - * sets the crypto_policy_t at location p to use policy + * 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. @@ -943,7 +933,7 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p); * with the policy data structure. You are encouraged to initialize * policy elements with this function call. Doing so may allow your * code to be forward compatible with later versions of libSRTP that - * include more elements in the crypto_policy_t datatype. + * include more elements in the srtp_crypto_policy_t datatype. * * @return void. * @@ -958,7 +948,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p); * @param p is a pointer to the policy structure to be set * * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&p) - * sets the crypto_policy_t at location p to use policy + * 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 @@ -970,7 +960,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p); * with the policy data structure. You are encouraged to initialize * policy elements with this function call. Doing so may allow your * code to be forward compatible with later versions of libSRTP that - * include more elements in the crypto_policy_t datatype. + * include more elements in the srtp_crypto_policy_t datatype. * * @warning This crypto policy is intended for use in SRTP, but not in * SRTCP. It is recommended that a policy that uses longer @@ -989,7 +979,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p); * @param p is a pointer to the policy structure to be set * * The function call srtp_crypto_policy_set_aes_cm_192_null_auth(&p) sets - * the crypto_policy_t at location p to use the SRTP default cipher + * 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). @@ -998,7 +988,7 @@ void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p); * with the policy data structure. You are encouraged to initialize * policy elements with this function call. Doing so may allow your * code to be forward compatible with later versions of libSRTP that - * include more elements in the crypto_policy_t datatype. + * include more elements in the srtp_crypto_policy_t datatype. * * @warning This policy is NOT RECOMMENDED for SRTP unless it is * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see @@ -1160,7 +1150,7 @@ void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p); * * @return * - srtp_err_status_ok if there no problems. - * - srtp_err_status_dealloc_fail a memory deallocation failure occured. + * - srtp_err_status_dealloc_fail a memory deallocation failure occurred. */ srtp_err_status_t srtp_dealloc(srtp_t s); @@ -1168,9 +1158,7 @@ srtp_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 + * profile (that is, a set of algorithms and parameters). */ typedef enum { srtp_profile_reserved = 0, @@ -1363,7 +1351,7 @@ srtp_err_status_t srtp_protect_rtcp(srtp_t ctx, * will * use the session keys identified by the mki_index * - * @param mki_index integer value specifying which set of session kesy should be + * @param mki_index integer value specifying which set of session keys should be * used if use_mki is set to true. * * @return @@ -1560,7 +1548,7 @@ void *srtp_get_user_data(srtp_t ctx); * latter case, all of the streams in the session will expire. */ typedef enum { - event_ssrc_collision, /**< An SSRC collision occured. */ + event_ssrc_collision, /**< An SSRC collision occurred. */ 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 */ @@ -1577,9 +1565,9 @@ typedef enum { * handler function. */ typedef struct srtp_event_data_t { - srtp_t session; /**< The session in which the event happend. */ + srtp_t session; /**< The session in which the event happened. */ uint32_t ssrc; /**< The ssrc in host order of the stream in which */ - /**< the event happend */ + /**< the event happened */ srtp_event_t event; /**< An enum indicating the type of event. */ } srtp_event_data_t; @@ -1603,7 +1591,7 @@ typedef void(srtp_event_handler_func_t)(srtp_event_data_t *data); * as an argument; in this case, events will be ignored rather than * handled. * - * @param func is a pointer to a fuction that takes an srtp_event_data_t + * @param func is a pointer to a function that takes an srtp_event_data_t * pointer as an argument and returns void. This function * will be used by libSRTP to handle events. */ @@ -1671,10 +1659,10 @@ typedef void(srtp_log_handler_func_t)(srtp_log_level_t level, * 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 + * This function can be called before srtp_init() in order to capture * any logging during start up. * - * @param func is a pointer to a fuction of type srtp_log_handler_func_t. + * @param func is a pointer to a function 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. diff --git a/third_party/libsrtp/src/include/srtp2/meson.build b/third_party/libsrtp/src/include/srtp2/meson.build new file mode 100644 index 000000000000..88d068a338c3 --- /dev/null +++ b/third_party/libsrtp/src/include/srtp2/meson.build @@ -0,0 +1,8 @@ +# Copy public headers scattered across the source tree into a single directory +# so that we can use it in declare_dependency() +foreach h : public_headers + configure_file(input: h, + output: '@BASENAME@.h', + copy: true) +endforeach +public_incs = include_directories('.') diff --git a/third_party/libsrtp/src/include/srtp_priv.h b/third_party/libsrtp/src/include/srtp_priv.h index 988efc4164d3..48dc65c7d81d 100644 --- a/third_party/libsrtp/src/include/srtp_priv.h +++ b/third_party/libsrtp/src/include/srtp_priv.h @@ -55,7 +55,6 @@ #include "cipher.h" #include "auth.h" #include "aes.h" -#include "key.h" #include "crypto_kernel.h" #ifdef __cplusplus @@ -147,7 +146,6 @@ typedef struct srtp_stream_ctx_t_ { 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; @@ -215,7 +213,7 @@ typedef struct { * srtcp_hdr_t represents a secure rtcp header * * in this implementation, an srtcp header is assumed to be 32-bit - * alinged + * aligned */ #ifndef WORDS_BIGENDIAN diff --git a/third_party/libsrtp/src/moz.build b/third_party/libsrtp/src/moz.build index a2e5a6d3e54a..3024bcc5dda8 100644 --- a/third_party/libsrtp/src/moz.build +++ b/third_party/libsrtp/src/moz.build @@ -4,12 +4,16 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +# we don't use mbedtls + UNIFIED_SOURCES += [ 'crypto/cipher/aes_gcm_nss.c', 'crypto/cipher/aes_icm_nss.c', 'crypto/cipher/cipher.c', + 'crypto/cipher/cipher_test_cases.c', 'crypto/cipher/null_cipher.c', 'crypto/hash/auth.c', + 'crypto/hash/auth_test_cases.c', 'crypto/hash/hmac.c', 'crypto/hash/null_auth.c', 'crypto/hash/sha1.c', @@ -18,11 +22,9 @@ UNIFIED_SOURCES += [ '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', ] diff --git a/third_party/libsrtp/src/srtp/srtp.c b/third_party/libsrtp/src/srtp/srtp.c index 5d9da7b2ecf2..fc0b1b0ad13c 100644 --- a/third_party/libsrtp/src/srtp/srtp.c +++ b/third_party/libsrtp/src/srtp/srtp.c @@ -48,7 +48,6 @@ #include "srtp_priv.h" #include "crypto_types.h" #include "err.h" -#include "ekt.h" /* for SRTP Encrypted Key Transport */ #include "alloc.h" /* for srtp_crypto_alloc() */ #ifdef GCM @@ -82,13 +81,14 @@ srtp_debug_module_t mod_srtp = { 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; + if (*pkt_octet_len < octets_in_rtp_header) return srtp_err_status_bad_param; - srtp_hdr_t *hdr = (srtp_hdr_t *)rtp_hdr; - /* Check RTP header length */ - int rtp_header_len = octets_in_rtp_header + 4 * hdr->cc; + rtp_header_len = octets_in_rtp_header + 4 * hdr->cc; if (hdr->x == 1) rtp_header_len += octets_in_rtp_extn_hdr; @@ -265,8 +265,6 @@ srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream, if (status) return status; - /* DAM - need to deallocate EKT here */ - if (stream_template && stream->enc_xtn_hdr == stream_template->enc_xtn_hdr) { /* do nothing */ @@ -280,6 +278,15 @@ srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream, return srtp_err_status_ok; } +static srtp_err_status_t srtp_valid_policy(const srtp_policy_t *p) +{ + if (p != NULL && p->deprecated_ekt != NULL) { + return srtp_err_status_bad_param; + } + + return srtp_err_status_ok; +} + srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, const srtp_policy_t *p) { @@ -288,6 +295,11 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, unsigned int i = 0; srtp_session_keys_t *session_keys = NULL; + stat = srtp_valid_policy(p); + if (stat != srtp_err_status_ok) { + return stat; + } + /* * This function allocates the stream context, rtp and rtcp ciphers * and auth functions, and key limit structure. If there is a @@ -374,13 +386,6 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, } } - /* 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; @@ -540,9 +545,6 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template, 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; @@ -678,6 +680,8 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf, 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; @@ -693,7 +697,6 @@ static srtp_err_status_t srtp_kdf_init(srtp_kdf_t *kdf, break; } - srtp_err_status_t stat; stat = srtp_crypto_kernel_alloc_cipher(cipher_id, &kdf->cipher, key_len, 0); if (stat) return stat; @@ -754,22 +757,40 @@ static inline int base_key_length(const srtp_cipher_type_t *cipher, int key_length) { switch (cipher->id) { + case SRTP_NULL_CIPHER: + return 0; 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; + } +} + +/* Get the key length that the application should supply for the given cipher */ +static inline int full_key_length(const srtp_cipher_type_t *cipher) +{ + switch (cipher->id) { + case SRTP_NULL_CIPHER: + case SRTP_AES_ICM_128: + return SRTP_AES_ICM_128_KEY_LEN_WSALT; + case SRTP_AES_ICM_192: + return SRTP_AES_ICM_192_KEY_LEN_WSALT; + case SRTP_AES_ICM_256: + return SRTP_AES_ICM_256_KEY_LEN_WSALT; + case SRTP_AES_GCM_128: + return SRTP_AES_GCM_128_KEY_LEN_WSALT; + case SRTP_AES_GCM_256: + return SRTP_AES_GCM_256_KEY_LEN_WSALT; + default: + return 0; } } @@ -867,6 +888,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, srtp_err_status_t stat; srtp_kdf_t kdf; uint8_t tmp_key[MAX_SRTP_KEY_LEN]; + int input_keylen, input_keylen_rtcp; int kdf_keylen = 30, rtp_keylen, rtcp_keylen; int rtp_base_key_len, rtp_salt_len; int rtcp_base_key_len, rtcp_salt_len; @@ -903,6 +925,12 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, session_keys->mki_size = master_key->mki_size; + input_keylen = full_key_length(session_keys->rtp_cipher->type); + input_keylen_rtcp = full_key_length(session_keys->rtcp_cipher->type); + if (input_keylen_rtcp > input_keylen) { + input_keylen = input_keylen_rtcp; + } + 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 = @@ -917,6 +945,11 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, kdf_keylen = 46; /* AES-CTR mode is always used for KDF */ } + if (input_keylen > kdf_keylen) { + kdf_keylen = 46; /* AES-CTR mode is always used for KDF */ + } + + debug_print(mod_srtp, "input key len: %d", input_keylen); 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); @@ -929,7 +962,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, * 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)); + memcpy(tmp_key, key, input_keylen); /* initialize KDF state */ #if defined(OPENSSL) && defined(OPENSSL_KDF) @@ -960,7 +993,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, * to generate the salt value */ if (rtp_salt_len > 0) { - debug_print(mod_srtp, "found rtp_salt_len > 0, generating salt", NULL); + debug_print0(mod_srtp, "found rtp_salt_len > 0, generating salt"); /* generate encryption salt, put after encryption key */ stat = srtp_kdf_generate(&kdf, label_rtp_salt, @@ -1069,9 +1102,8 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, * 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); + debug_print0(mod_srtp, + "found rtp_xtn_hdr_salt_len > 0, generating salt"); /* generate encryption salt, put after encryption key */ stat = srtp_kdf_generate(xtn_hdr_kdf, label_rtp_header_salt, @@ -1152,8 +1184,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, * to generate the salt value */ if (rtcp_salt_len > 0) { - debug_print(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt", - NULL); + debug_print0(mod_srtp, "found rtcp_salt_len > 0, generating rtcp salt"); /* generate encryption salt, put after encryption key */ stat = srtp_kdf_generate(&kdf, label_rtcp_salt, @@ -1218,6 +1249,11 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp, { srtp_err_status_t err; + err = srtp_valid_policy(p); + if (err != srtp_err_status_ok) { + return err; + } + debug_print(mod_srtp, "initializing stream (SSRC: 0x%08x)", p->ssrc.value); /* initialize replay database */ @@ -1277,16 +1313,6 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp, 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; } @@ -1423,7 +1449,7 @@ static srtp_err_status_t srtp_process_header_encryption( xtn_hdr_data++; } } - } else if ((ntohs(xtn_hdr->profile_specific) & 0x1fff) == 0x100) { + } else if ((ntohs(xtn_hdr->profile_specific) & 0xfff0) == 0x1000) { /* RFC 5285, section 4.3. Two-Byte Header */ while (xtn_hdr_data + 1 < xtn_hdr_end) { uint8_t xid = *xtn_hdr_data; @@ -1669,7 +1695,7 @@ static srtp_err_status_t srtp_get_est_pkt_index(srtp_hdr_t *hdr, 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); + debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, *est); #endif return result; } @@ -1699,7 +1725,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, unsigned int mki_size = 0; uint8_t *mki_location = NULL; - debug_print(mod_srtp, "function srtp_protect_aead", NULL); + debug_print0(mod_srtp, "function srtp_protect_aead"); /* * update the key usage limit, and check it to make sure that we @@ -1758,7 +1784,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est), low32(est)); #else - debug_print(mod_srtp, "estimated packet index: %016llx", est); + debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est); #endif /* @@ -1860,13 +1886,13 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, unsigned int aad_len; srtp_hdr_xtnd_t *xtn_hdr = NULL; - debug_print(mod_srtp, "function srtp_unprotect_aead", NULL); + debug_print0(mod_srtp, "function srtp_unprotect_aead"); #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); + debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est); #endif /* get tag length from stream */ @@ -2061,7 +2087,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, uint8_t *mki_location = NULL; int advance_packet_index = 0; - debug_print(mod_srtp, "function srtp_protect", NULL); + debug_print0(mod_srtp, "function srtp_protect"); /* we assume the hdr is 32-bit aligned to start */ @@ -2232,7 +2258,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, debug_print2(mod_srtp, "estimated packet index: %08x%08x", high32(est), low32(est)); #else - debug_print(mod_srtp, "estimated packet index: %016llx", est); + debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est); #endif /* @@ -2338,7 +2364,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, return status; /* run auth func over ROC, put result into auth_tag */ - debug_print(mod_srtp, "estimated packet index: %016llx", est); + debug_print(mod_srtp, "estimated packet index: %016" PRIx64, est); status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4, auth_tag); debug_print(mod_srtp, "srtp auth tag: %s", @@ -2391,7 +2417,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, uint32_t roc_to_set = 0; uint16_t seq_to_set = 0; - debug_print(mod_srtp, "function srtp_unprotect", NULL); + debug_print0(mod_srtp, "function srtp_unprotect"); /* we assume the hdr is 32-bit aligned to start */ @@ -2460,7 +2486,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, 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); + debug_print(mod_srtp, "estimated u_packet index: %016" PRIx64, est); #endif /* Determine if MKI is being used and what session keys should be used */ @@ -2604,6 +2630,8 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* 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); + if (status) + return status; /* run auth func over ROC, then write tmp tag */ status = srtp_auth_compute(session_keys->rtp_auth, (uint8_t *)&est, 4, @@ -2616,7 +2644,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, if (status) return srtp_err_status_auth_fail; - if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len)) return srtp_err_status_auth_fail; } @@ -2752,25 +2780,6 @@ srtp_err_status_t srtp_shutdown() return srtp_err_status_ok; } -/* - * The following code is under consideration for removal. See - * SRTP_MAX_TRAILER_LEN - */ -#if 0 - -/* - * srtp_get_trailer_length(&a) returns the number of octets that will - * be added to an RTP packet by the SRTP processing. This value - * is constant for a given srtp_stream_t (i.e. between initializations). - */ - -int -srtp_get_trailer_length(const srtp_stream_t s) { - return srtp_auth_get_tag_length(s->rtp_auth); -} - -#endif - /* * srtp_get_stream(ssrc) returns a pointer to the stream corresponding * to ssrc, or NULL if no stream exists for that ssrc @@ -2833,6 +2842,11 @@ srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy) srtp_err_status_t status; srtp_stream_t tmp; + status = srtp_valid_policy(policy); + if (status != srtp_err_status_ok) { + return status; + } + /* sanity check arguments */ if ((session == NULL) || (policy == NULL) || (!srtp_validate_policy_master_keys(policy))) @@ -2895,6 +2909,11 @@ srtp_err_status_t srtp_create(srtp_t *session, /* handle for session */ srtp_err_status_t stat; srtp_ctx_t *ctx; + stat = srtp_valid_policy(policy); + if (stat != srtp_err_status_ok) { + return stat; + } + /* sanity check arguments */ if (session == NULL) return srtp_err_status_bad_param; @@ -2965,6 +2984,11 @@ srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy) { srtp_err_status_t stat; + stat = srtp_valid_policy(policy); + if (stat != srtp_err_status_ok) { + return stat; + } + /* sanity check arguments */ if ((session == NULL) || (policy == NULL) || (!srtp_validate_policy_master_keys(policy))) { @@ -2990,6 +3014,11 @@ static srtp_err_status_t update_template_streams(srtp_t session, srtp_stream_t new_stream_template; srtp_stream_t new_stream_list = NULL; + status = srtp_valid_policy(policy); + if (status != srtp_err_status_ok) { + return status; + } + if (session->stream_template == NULL) { return srtp_err_status_bad_param; } @@ -3088,6 +3117,11 @@ static srtp_err_status_t update_stream(srtp_t session, srtp_rdb_t old_rtcp_rdb; srtp_stream_t stream; + status = srtp_valid_policy(policy); + if (status != srtp_err_status_ok) { + return status; + } + stream = srtp_get_stream(session, htonl(policy->ssrc.value)); if (stream == NULL) { return srtp_err_status_bad_param; @@ -3124,6 +3158,11 @@ srtp_err_status_t srtp_update_stream(srtp_t session, { srtp_err_status_t status; + status = srtp_valid_policy(policy); + if (status != srtp_err_status_ok) { + return status; + } + /* sanity check arguments */ if ((session == NULL) || (policy == NULL) || (!srtp_validate_policy_master_keys(policy))) @@ -3223,7 +3262,7 @@ void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p) */ p->cipher_type = SRTP_NULL_CIPHER; - p->cipher_key_len = 0; + p->cipher_key_len = 16; p->auth_type = SRTP_HMAC_SHA1; p->auth_key_len = 20; p->auth_tag_len = 10; @@ -3237,7 +3276,7 @@ void srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p) */ p->cipher_type = SRTP_NULL_CIPHER; - p->cipher_key_len = 0; + p->cipher_key_len = 16; p->auth_type = SRTP_NULL_AUTH; p->auth_key_len = 0; p->auth_tag_len = 0; @@ -3287,7 +3326,6 @@ void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p) p->sec_serv = sec_serv_conf; } -#ifdef GCM void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p) { /* @@ -3409,8 +3447,6 @@ void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p) p->sec_serv = sec_serv_conf_and_auth; } -#endif - /* * secure rtcp functions */ @@ -3985,10 +4021,6 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx, 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 @@ -4059,7 +4091,9 @@ srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx, } /* initialize auth func context */ - srtp_auth_start(session_keys->rtcp_auth); + status = srtp_auth_start(session_keys->rtcp_auth); + if (status) + return status; /* * run auth func over packet (including trailer), and write the @@ -4102,7 +4136,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, 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; @@ -4140,23 +4173,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, 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)); @@ -4246,21 +4262,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, 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 */ @@ -4301,7 +4302,9 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, return srtp_err_status_cipher_fail; /* initialize auth func context */ - srtp_auth_start(session_keys->rtcp_auth); + status = srtp_auth_start(session_keys->rtcp_auth); + if (status) + return status; /* run auth func over packet, put result into tmp_tag */ status = srtp_auth_compute(session_keys->rtcp_auth, (uint8_t *)auth_start, @@ -4314,7 +4317,7 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, /* compare the tag just computed with the one in the packet */ debug_print(mod_srtp, "srtcp tag from packet: %s", srtp_octet_string_hex_string(auth_tag, tag_len)); - if (octet_string_is_eq(tmp_tag, auth_tag, tag_len)) + if (srtp_octet_string_is_eq(tmp_tag, auth_tag, tag_len)) return srtp_err_status_auth_fail; /* @@ -4345,12 +4348,6 @@ srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, /* 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 @@ -4417,10 +4414,6 @@ 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) @@ -4551,10 +4544,10 @@ srtp_err_status_t stream_get_protect_trailer_length(srtp_stream_ctx_t *stream, uint32_t mki_index, uint32_t *length) { - *length = 0; - srtp_session_keys_t *session_key; + *length = 0; + if (use_mki) { if (mki_index >= stream->num_master_keys) { return srtp_err_status_bad_mki; diff --git a/third_party/libsrtp/src/test/.cvsignore b/third_party/libsrtp/src/test/.cvsignore new file mode 100644 index 000000000000..8c839af318bd --- /dev/null +++ b/third_party/libsrtp/src/test/.cvsignore @@ -0,0 +1,13 @@ +aes_calc +cipher_driver +datatypes_driver +dtls_srtp_driver +kernel_driver +rand_gen +rdbx_driver +replay_driver +roc_driver +rtpw +sha1_driver +srtp_driver +stat_driver diff --git a/third_party/libsrtp/src/test/getopt_s.h b/third_party/libsrtp/src/test/getopt_s.h new file mode 100644 index 000000000000..53fb25ba7100 --- /dev/null +++ b/third_party/libsrtp/src/test/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/third_party/libsrtp/src/test/meson.build b/third_party/libsrtp/src/test/meson.build new file mode 100644 index 000000000000..4a67912ebb54 --- /dev/null +++ b/third_party/libsrtp/src/test/meson.build @@ -0,0 +1,77 @@ +# test suite + +# XXX: Makefile only runs test_srtp and srtp_driver with valgrind +add_test_setup('valgrind', + exe_wrapper: ['valgrind', '--leak-check=full'], + timeout_multiplier: 10) + +test_apps = [ + ['srtp_driver', {'extra_sources': 'util.c', 'run_args': '-v'}], + ['replay_driver', {'extra_sources': 'ut_sim.c', 'run_args': '-v'}], + ['roc_driver', {'extra_sources': 'ut_sim.c', 'run_args': '-v'}], + ['rdbx_driver', {'extra_sources': 'ut_sim.c', 'run_args': '-v'}], + ['test_srtp', {'run_args': '-v'}], + ['rtpw', {'extra_sources': ['rtp.c', 'util.c', '../crypto/math/datatypes.c'], 'define_test': false}], +] + +foreach t : test_apps + test_name = t.get(0) + test_dict = t.get(1, {}) + test_extra_sources = test_dict.get('extra_sources', []) + test_run_args = test_dict.get('run_args', []) + + test_exe = executable(test_name, + '@0@.c'.format(test_name), 'getopt_s.c', test_extra_sources, + include_directories: [config_incs, crypto_incs, srtp2_incs, test_incs], + dependencies: [srtp2_deps, syslibs], + link_with: libsrtp2_for_tests) + + if test_dict.get('define_test', true) + test(test_name, test_exe, args: test_run_args) + else + set_variable(test_name + '_exe', test_exe) + endif +endforeach + +# rtpw test needs to be run using shell scripts +can_run_rtpw = find_program('sh', 'bash', required: false).found() + +# Meson only passes the exe_wrapper to shell scripts starting 0.55 +if meson.is_cross_build() and meson.version().version_compare('<0.55') + can_run_rtpw = false +endif + +if can_run_rtpw + words_txt = files('words.txt') + + rtpw_test_sh = find_program('rtpw_test.sh', required: false) + if rtpw_test_sh.found() + test('rtpw_test', rtpw_test_sh, + args: ['-w', words_txt], + depends: rtpw_exe, + is_parallel: false, + workdir: meson.current_build_dir()) + endif + + rtpw_test_gcm_sh = find_program('rtpw_test_gcm.sh', required: false) + if (use_openssl or use_nss) and rtpw_test_gcm_sh.found() + test('rtpw_test_gcm', rtpw_test_gcm_sh, + args: ['-w', words_txt], + depends: rtpw_exe, + is_parallel: false, + workdir: meson.current_build_dir()) + endif +endif + +# rtp_decoder +pcap_dep = dependency('libpcap', required: get_option('pcap-tests')) + +if pcap_dep.found() + executable('rtp_decoder', + 'rtp_decoder.c', 'getopt_s.c', 'rtp.c', 'util.c', 'getopt_s.c', + '../crypto/math/datatypes.c', + include_directories: [config_incs, crypto_incs, srtp2_incs, test_incs], + dependencies: [srtp2_deps, pcap_dep, syslibs], + link_with: libsrtp2, + install: false) +endif diff --git a/third_party/libsrtp/src/test/rdbx_driver.c b/third_party/libsrtp/src/test/rdbx_driver.c index 3da65037193b..430e28389a0e 100644 --- a/third_party/libsrtp/src/test/rdbx_driver.c +++ b/third_party/libsrtp/src/test/rdbx_driver.c @@ -50,6 +50,7 @@ #include "getopt_s.h" /* for local getopt() */ #include "rdbx.h" +#include "cipher_priv.h" #ifdef ROC_TEST #error "srtp_rdbx_t won't work with ROC_TEST - bitmask same size as seq_median" @@ -129,13 +130,6 @@ int main(int argc, char *argv[]) return 0; } -void print_rdbx(srtp_rdbx_t *rdbx) -{ - char buf[2048]; - printf("rdbx: {%llu, %s}\n", (unsigned long long)(rdbx->index), - bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf))); -} - /* * rdbx_check_add(rdbx, idx) checks a known-to-be-good idx against * rdbx, then adds it. if a failure is detected (i.e., the check @@ -305,7 +299,7 @@ srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws) */ printf("\ttesting insertion with large gaps..."); for (idx = 0, ircvd = 0; (int)idx < num_trials; - idx++, ircvd += (1 << (rand() % 12))) { + idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 12))) { status = rdbx_check_add(&rdbx, ircvd); if (status) return status; @@ -320,8 +314,7 @@ srtp_err_status_t test_replay_dbx(int num_trials, unsigned long ws) return srtp_err_status_ok; } -#include <time.h> /* for clock() */ -#include <stdlib.h> /* for random() */ +#include <time.h> /* for clock() */ double rdbx_check_adds_per_second(int num_trials, unsigned long ws) { diff --git a/third_party/libsrtp/src/test/replay_driver.c b/third_party/libsrtp/src/test/replay_driver.c index a88224684f6a..9807e50c127d 100644 --- a/third_party/libsrtp/src/test/replay_driver.c +++ b/third_party/libsrtp/src/test/replay_driver.c @@ -52,6 +52,8 @@ #include "rdb.h" #include "ut_sim.h" +#include "cipher_priv.h" + /* * num_trials defines the number of trials that are used in the * validation functions below @@ -80,12 +82,6 @@ int main(void) return 0; } -void print_rdb(srtp_rdb_t *rdb) -{ - printf("rdb: {%u, %s}\n", rdb->window_start, - v128_bit_string(&rdb->bitmask)); -} - srtp_err_status_t rdb_check_add(srtp_rdb_t *rdb, uint32_t idx) { if (srtp_rdb_check(rdb, idx) != srtp_err_status_ok) { @@ -189,7 +185,7 @@ srtp_err_status_t test_rdb_db() /* test insertion with large gaps */ for (idx = 0, ircvd = 0; idx < num_trials; - idx++, ircvd += (1 << (rand() % 10))) { + idx++, ircvd += (1 << (srtp_cipher_rand_u32_for_tests() % 10))) { err = rdb_check_add(&rdb, ircvd); if (err) return err; diff --git a/third_party/libsrtp/src/test/rtp.c b/third_party/libsrtp/src/test/rtp.c index f60a9b11b288..70248ee2b5a1 100644 --- a/third_party/libsrtp/src/test/rtp.c +++ b/third_party/libsrtp/src/test/rtp.c @@ -53,6 +53,8 @@ #include <sys/socket.h> #endif +#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 */ @@ -148,7 +150,7 @@ int rtp_sender_init(rtp_sender_t sender, /* set header values */ sender->message.header.ssrc = htonl(ssrc); sender->message.header.ts = 0; - sender->message.header.seq = (uint16_t)rand(); + 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; diff --git a/third_party/libsrtp/src/test/rtp_decoder.c b/third_party/libsrtp/src/test/rtp_decoder.c index d718a2b3ad18..137e7e6b3915 100644 --- a/third_party/libsrtp/src/test/rtp_decoder.c +++ b/third_party/libsrtp/src/test/rtp_decoder.c @@ -83,23 +83,76 @@ #define MAX_KEY_LEN 96 #define MAX_FILTER 256 +#define MAX_FILE 255 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[] = { - {.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 }, #if 0 - {.can_name = "F8_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4}, + {.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", .key_size = 128, .tag_size = 4 }, - {.can_name = "AES_CM_128_HMAC_SHA1_80", .key_size = 128, .tag_size = 10 }, + {.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]; @@ -112,15 +165,18 @@ int main(int argc, char *argv[]) int c; struct srtp_crypto_suite scs, *i_scsp; scs.key_size = 128; - scs.tag_size = 8; + 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] = ""; + char pcap_file[MAX_FILE] = "-"; + int rtp_packet_offset = DEFAULT_RTP_OFFSET; rtp_decoder_t dec; - srtp_policy_t policy; + srtp_policy_t policy = { { 0 } }; + rtp_decoder_mode_t mode = mode_rtp; srtp_err_status_t status; int len; int expected_len; @@ -138,9 +194,15 @@ int main(int argc, char *argv[]) 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:"); + c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:"); if (c == -1) { break; } @@ -153,10 +215,12 @@ int main(int argc, char *argv[]) break; case 'e': scs.key_size = atoi(optarg_s); - if (scs.key_size != 128 && scs.key_size != 256) { - fprintf(stderr, - "error: encryption key size must be 128 or 256 (%d)\n", - scs.key_size); + 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); @@ -173,7 +237,7 @@ int main(int argc, char *argv[]) sec_servs |= sec_serv_auth; break; case 'd': - status = srtp_crypto_kernel_set_debug_module(optarg_s, 1); + status = srtp_set_debug_module(optarg_s, 1); if (status) { fprintf(stderr, "error: set debug module (%s) failed\n", optarg_s); @@ -207,20 +271,59 @@ int main(int argc, char *argv[]) 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; + case 'p': + if (strlen(optarg_s) > MAX_FILE) { + fprintf(stderr, + "error: pcap file path bigger than %d characters\n", + MAX_FILE); + exit(1); + } + strcpy(pcap_file, optarg_s); + break; + case 'o': + rtp_packet_offset = atoi(optarg_s); 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); + 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_crypto_kernel_list_debug_modules(); + status = srtp_list_debug_modules(); if (status) { fprintf(stderr, "error: list of debug modules failed\n"); exit(1); @@ -266,12 +369,24 @@ int main(int argc, char *argv[]) #ifdef OPENSSL switch (scs.key_size) { case 128: - srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp); - srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp); + 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: - srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp); - srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp); + 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 @@ -282,12 +397,51 @@ int main(int argc, char *argv[]) } else { switch (scs.key_size) { case 128: - srtp_crypto_policy_set_rtp_default(&policy.rtp); - srtp_crypto_policy_set_rtcp_default(&policy.rtcp); + 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: - srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp); - srtp_crypto_policy_set_rtcp_default(&policy.rtcp); + 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; } } @@ -302,11 +456,26 @@ int main(int argc, char *argv[]) switch (scs.key_size) { case 128: srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp); - srtp_crypto_policy_set_rtcp_default(&policy.rtcp); + 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_rtcp_default(&policy.rtcp); + srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80( + &policy.rtcp); break; } } @@ -342,7 +511,6 @@ int main(int argc, char *argv[]) } policy.key = (uint8_t *)key; - policy.ekt = NULL; policy.next = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; @@ -353,7 +521,7 @@ int main(int argc, char *argv[]) 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); + fprintf(stderr, "set tag len %d\n", scs.tag_size); policy.rtp.auth_tag_len = scs.tag_size; } @@ -365,11 +533,7 @@ int main(int argc, char *argv[]) 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); - } + strlen(input_key)); } else { expected_len = policy.rtp.cipher_key_len * 2; len = hex_string_to_octet_string(key, input_key, expected_len); @@ -388,17 +552,20 @@ int main(int argc, char *argv[]) exit(1); } + int key_octets = (scs.key_size / 8); + int salt_octets = policy.rtp.cipher_key_len - key_octets; 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)); + octet_string_hex_string(key, key_octets)); + fprintf(stderr, "%s\n", + octet_string_hex_string(key + key_octets, salt_octets)); } else { fprintf(stderr, - "error: neither encryption or authentication were selected"); + "error: neither encryption or authentication were selected\n"); exit(1); } - pcap_handle = pcap_open_offline("-", errbuf); + pcap_handle = pcap_open_offline(pcap_file, errbuf); if (!pcap_handle) { fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf); @@ -421,11 +588,22 @@ int main(int argc, char *argv[]) exit(1); } fprintf(stderr, "Starting decoder\n"); - rtp_decoder_init(dec, policy); + if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) { + fprintf(stderr, "error: init failed\n"); + exit(1); + } pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec); - rtp_decoder_deinit_srtp(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(); @@ -442,7 +620,8 @@ void usage(char *string) { fprintf( stderr, - "usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n" + "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" @@ -454,7 +633,10 @@ void usage(char *string) " -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", + " on RFC4568-style crypto suite specification\n" + " -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\n" + " -p <pcap file> path to pcap file (defaults to stdin)\n" + " -o byte offset of RTP packet in capture (defaults to 42)\n", string, string); exit(1); } @@ -469,27 +651,34 @@ void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx) free(rtp_ctx); } -srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder, - unsigned int ssrc) +int rtp_decoder_deinit(rtp_decoder_t decoder) { - decoder->policy.ssrc.value = htonl(ssrc); - return srtp_create(&decoder->srtp_ctx, &decoder->policy); + if (decoder->srtp_ctx) { + return srtp_dealloc(decoder->srtp_ctx); + } + return 0; } -int rtp_decoder_deinit_srtp(rtp_decoder_t decoder) +int rtp_decoder_init(rtp_decoder_t dcdr, + srtp_policy_t policy, + rtp_decoder_mode_t mode, + int rtp_packet_offset) { - return srtp_dealloc(decoder->srtp_ctx); -} - -int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy) -{ - dcdr->rtp_offset = DEFAULT_RTP_OFFSET; + dcdr->rtp_offset = rtp_packet_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_specific; + dcdr->policy.ssrc.type = ssrc_any_inbound; + + if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) { + return 1; + } return 0; } @@ -516,6 +705,8 @@ void rtp_decoder_handle_pkt(u_char *arg, 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; @@ -531,7 +722,7 @@ void rtp_decoder_handle_pkt(u_char *arg, } const void *rtp_packet = bytes + dcdr->rtp_offset; - memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset); + memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset); pktsize = hdr->caplen - dcdr->rtp_offset; octets_recvd = pktsize; @@ -539,36 +730,41 @@ void rtp_decoder_handle_pkt(u_char *arg, return; } - /* verify rtp header */ - if (dcdr->message.header.version != 2) { - return; - } - if (dcdr->srtp_ctx == NULL) { - status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc); - if (status) { - exit(1); + 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; } } - status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd); - if (status) { - return; + + 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(&dcdr->message, octets_recvd); -} - -void rtp_print_error(srtp_err_status_t status, char *message) -{ - // clang-format off - fprintf(stderr, - "error: %s %d%s\n", message, status, - status == srtp_err_status_replay_fail ? " (replay check failed)" : - status == srtp_err_status_bad_param ? " (bad param)" : - status == srtp_err_status_no_ctx ? " (no context)" : - status == srtp_err_status_cipher_fail ? " (cipher failed)" : - status == srtp_err_status_key_expired ? " (key expired)" : - status == srtp_err_status_auth_fail ? " (auth check failed)" : ""); - // clang-format on + hexdump(&message, octets_recvd); } diff --git a/third_party/libsrtp/src/test/rtp_decoder.h b/third_party/libsrtp/src/test/rtp_decoder.h index c8c31dd77337..955caf640efa 100644 --- a/third_party/libsrtp/src/test/rtp_decoder.h +++ b/third_party/libsrtp/src/test/rtp_decoder.h @@ -52,22 +52,26 @@ #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; - rtp_msg_t message; + 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 */ @@ -95,11 +99,19 @@ 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); +int rtp_decoder_init(rtp_decoder_t dcdr, + srtp_policy_t policy, + rtp_decoder_mode_t mode, + int rtp_packet_offset); -srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder, - unsigned int ssrc); +int rtp_decoder_deinit(rtp_decoder_t decoder); -int rtp_decoder_deinit_srtp(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/third_party/libsrtp/src/test/rtpw.c b/third_party/libsrtp/src/test/rtpw.c index 901816e46da4..ad8444829826 100644 --- a/third_party/libsrtp/src/test/rtpw.c +++ b/third_party/libsrtp/src/test/rtpw.c @@ -96,7 +96,7 @@ #ifndef HAVE_USLEEP #ifdef HAVE_WINDOWS_H -#define usleep(us) Sleep((us) / 1000) +#define usleep(us) Sleep(((DWORD)us) / 1000) #else #define usleep(us) sleep((us) / 1000000) #endif @@ -444,7 +444,6 @@ int main(int argc, char *argv[]) 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; @@ -506,7 +505,6 @@ int main(int argc, char *argv[]) policy.ssrc.value = ssrc; policy.window_size = 0; policy.allow_repeat_tx = 0; - policy.ekt = NULL; policy.next = NULL; } @@ -671,7 +669,7 @@ void handle_signal(int signum) int setup_signal_handler(char *name) { -#if HAVE_SIGACTION +#ifdef HAVE_SIGACTION struct sigaction act; memset(&act, 0, sizeof(act)); diff --git a/third_party/libsrtp/src/test/rtpw_test.sh b/third_party/libsrtp/src/test/rtpw_test.sh index 158a39312d8d..8fcb35f363fd 100755 --- a/third_party/libsrtp/src/test/rtpw_test.sh +++ b/third_party/libsrtp/src/test/rtpw_test.sh @@ -43,15 +43,22 @@ case $(uname -s) in ;; *Linux*) EXE="" - export LD_LIBRARY_PATH=$CRYPTO_LIBDIR + if [ -n "$CRYPTO_LIBDIR" ] + then + export LD_LIBRARY_PATH="$CRYPTO_LIBDIR" + fi ;; *Darwin*) EXE="" - export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR + if [ -n "$CRYPTO_LIBDIR" ] + then + export DYLD_LIBRARY_PATH="$CRYPTO_LIBDIR" + fi ;; esac RTPW=./rtpw$EXE +[ -n "$MESON_EXE_WRAPPER" ] && RTPW="$MESON_EXE_WRAPPER $RTPW" DEST_PORT=9999 DURATION=3 @@ -67,7 +74,7 @@ ARGS="-b $key -a -e 128" killall rtpw 2>/dev/null -if test -x $RTPW; then +if test -n $MESON_EXE_WRAPPER || test -x $RTPW; then echo $0 ": starting rtpw receiver process... " diff --git a/third_party/libsrtp/src/test/rtpw_test_gcm.sh b/third_party/libsrtp/src/test/rtpw_test_gcm.sh index 644255e1a172..1722f44ea73f 100755 --- a/third_party/libsrtp/src/test/rtpw_test_gcm.sh +++ b/third_party/libsrtp/src/test/rtpw_test_gcm.sh @@ -43,15 +43,22 @@ case $(uname -s) in ;; *Linux*) EXE="" - export LD_LIBRARY_PATH=$CRYPTO_LIBDIR + if [ -n "$CRYPTO_LIBDIR" ] + then + export LD_LIBRARY_PATH="$CRYPTO_LIBDIR" + fi ;; *Darwin*) EXE="" - export DYLD_LIBRARY_PATH=$CRYPTO_LIBDIR + if [ -n "$CRYPTO_LIBDIR" ] + then + export DYLD_LIBRARY_PATH="$CRYPTO_LIBDIR" + fi ;; esac RTPW=./rtpw$EXE +[ -n "$MESON_EXE_WRAPPER" ] && RTPW="$MESON_EXE_WRAPPER $RTPW" DEST_PORT=9999 DURATION=3 @@ -63,7 +70,7 @@ DURATION=3 killall rtpw 2>/dev/null -if test -x $RTPW; then +if test -n $MESON_EXE_WRAPPER || test -x $RTPW; then GCMARGS128="-k 01234567890123456789012345678901234567890123456789012345 -g -e 128" echo $0 ": starting GCM mode 128-bit rtpw receiver process... " diff --git a/third_party/libsrtp/src/test/srtp_driver.c b/third_party/libsrtp/src/test/srtp_driver.c index a7234539f743..a31f3346ab8f 100644 --- a/third_party/libsrtp/src/test/srtp_driver.c +++ b/third_party/libsrtp/src/test/srtp_driver.c @@ -61,6 +61,8 @@ srtp_err_status_t srtp_validate(void); +srtp_err_status_t srtp_validate_null(void); + #ifdef GCM srtp_err_status_t srtp_validate_gcm(void); #endif @@ -181,11 +183,12 @@ void log_handler(srtp_log_level_t level, const char *msg, void *data) } /* - * The policy_array is a null-terminated array of policy structs. it - * is declared at the end of this file + * The policy_array and invalid_policy_array are null-terminated arrays of + * policy structs. They is declared at the end of this file. */ extern const srtp_policy_t *policy_array[]; +extern const srtp_policy_t *invalid_policy_array[]; /* the wildcard_policy is declared below; it has a wildcard ssrc */ @@ -302,6 +305,7 @@ int main(int argc, char *argv[]) if (do_validation) { const srtp_policy_t **policy = policy_array; srtp_policy_t *big_policy; + srtp_t srtp_sender; /* loop over policy array, testing srtp and srtcp for each policy */ while (*policy != NULL) { @@ -364,6 +368,21 @@ int main(int argc, char *argv[]) policy++; } + /* loop over invalid policy array, testing that an SRTP context cannot + * be created with the policy */ + policy = invalid_policy_array; + while (*policy != NULL) { + printf("testing srtp_create fails with invalid policy\n"); + if (srtp_create(&srtp_sender, *policy) != 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) { @@ -422,6 +441,15 @@ int main(int argc, char *argv[]) exit(1); } + printf("testing srtp_protect and srtp_unprotect against " + "reference packet using null cipher and HMAC\n"); + if (srtp_validate_null() == 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"); @@ -589,7 +617,7 @@ int main(int argc, char *argv[]) policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xdecafbad; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -928,12 +956,10 @@ double srtp_rejections_per_second(int msg_len_octets, void err_check(srtp_err_status_t s) { - if (s == srtp_err_status_ok) { - return; - } else { + if (s != srtp_err_status_ok) { fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s); + exit(1); } - exit(1); } srtp_err_status_t srtp_test_call_protect(srtp_t srtp_sender, @@ -1683,7 +1709,7 @@ srtp_err_status_t srtp_validate() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -1707,7 +1733,7 @@ srtp_err_status_t srtp_validate() debug_print(mod_driver, "ciphertext reference:\n %s", octet_string_hex_string(srtp_ciphertext, len)); - if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) { + if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) { return srtp_err_status_fail; } @@ -1725,7 +1751,7 @@ srtp_err_status_t srtp_validate() debug_print(mod_driver, "srtcp ciphertext reference:\n %s", octet_string_hex_string(srtcp_ciphertext, len)); - if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) { + if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) { return srtp_err_status_fail; } @@ -1747,7 +1773,7 @@ srtp_err_status_t srtp_validate() return status; } - if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) { + if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) { return srtp_err_status_fail; } @@ -1760,7 +1786,167 @@ srtp_err_status_t srtp_validate() return status; } - if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) { + 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; +} + +/* + * srtp_validate_null() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with a policy that applies null encryption + * and HMAC authentication. + */ + +srtp_err_status_t srtp_validate_null() +{ + // 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, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xa1, 0x36, 0x27, + 0x0b, 0x67, 0x91, 0x34, 0xce, 0x9b + }; + 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, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, + 0x00, 0x00, 0x00, 0x01, 0xfe, 0x88, 0xc7, 0xfd, + 0xfd, 0x37, 0xeb, 0xce, 0x61, 0x5d, + }; + // 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_null_cipher_hmac_sha1_80(&policy.rtp); + srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key; + policy.deprecated_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; + } + + /* + * 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; } @@ -1851,7 +2037,7 @@ srtp_err_status_t srtp_validate_gcm() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key_gcm; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -1875,7 +2061,7 @@ srtp_err_status_t srtp_validate_gcm() debug_print(mod_driver, "srtp ciphertext reference:\n %s", octet_string_hex_string(srtp_ciphertext, len)); - if (octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) { + if (srtp_octet_string_is_eq(rtp_plaintext, srtp_ciphertext, len)) { return srtp_err_status_fail; } @@ -1893,7 +2079,7 @@ srtp_err_status_t srtp_validate_gcm() debug_print(mod_driver, "srtcp ciphertext reference:\n %s", octet_string_hex_string(srtcp_ciphertext, len)); - if (octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) { + if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_ciphertext, len)) { return srtp_err_status_fail; } @@ -1916,7 +2102,7 @@ srtp_err_status_t srtp_validate_gcm() return status; } - if (octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) { + if (srtp_octet_string_is_eq(srtp_ciphertext, rtp_plaintext_ref, len)) { return srtp_err_status_fail; } @@ -1929,7 +2115,7 @@ srtp_err_status_t srtp_validate_gcm() return status; } - if (octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) { + if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, len)) { return srtp_err_status_fail; } @@ -2008,7 +2194,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key_ext_headers; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.enc_xtn_hdr = headers; @@ -2032,7 +2218,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers() debug_print(mod_driver, "ciphertext reference:\n %s", srtp_octet_string_hex_string(srtp_ciphertext, len)); - if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) + if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) return srtp_err_status_fail; /* @@ -2054,7 +2240,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers() return srtp_err_status_fail; } - if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) + if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) return srtp_err_status_fail; status = srtp_dealloc(srtp_snd); @@ -2129,7 +2315,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key_ext_headers; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.enc_xtn_hdr = headers; @@ -2153,7 +2339,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm() debug_print(mod_driver, "ciphertext reference:\n %s", srtp_octet_string_hex_string(srtp_ciphertext, len)); - if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) + if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) return srtp_err_status_fail; /* @@ -2175,7 +2361,7 @@ srtp_err_status_t srtp_validate_encrypted_extensions_headers_gcm() return srtp_err_status_fail; } - if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) + if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) return srtp_err_status_fail; status = srtp_dealloc(srtp_snd); @@ -2245,7 +2431,7 @@ srtp_err_status_t srtp_validate_aes_256() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = aes_256_test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2269,7 +2455,7 @@ srtp_err_status_t srtp_validate_aes_256() debug_print(mod_driver, "ciphertext reference:\n %s", octet_string_hex_string(srtp_ciphertext, len)); - if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) { + if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) { return srtp_err_status_fail; } @@ -2291,7 +2477,7 @@ srtp_err_status_t srtp_validate_aes_256() return status; } - if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) { + if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) { return srtp_err_status_fail; } @@ -2311,7 +2497,8 @@ srtp_err_status_t srtp_validate_aes_256() srtp_err_status_t srtp_create_big_policy(srtp_policy_t **list) { extern const srtp_policy_t *policy_array[]; - srtp_policy_t *p, *tmp; + srtp_policy_t *p = NULL; + srtp_policy_t *tmp; int i = 0; uint32_t ssrc = 0; @@ -2372,7 +2559,7 @@ srtp_err_status_t srtp_test_empty_payload() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2448,7 +2635,7 @@ srtp_err_status_t srtp_test_empty_payload_gcm() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2573,7 +2760,7 @@ srtp_err_status_t srtp_test_remove_stream() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2632,7 +2819,7 @@ srtp_err_status_t srtp_test_update() 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.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2796,7 +2983,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams( 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.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.next = NULL; @@ -2806,7 +2993,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams( 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.deprecated_ekt = NULL; policy_mki.window_size = 128; policy_mki.allow_repeat_tx = 0; policy_mki.next = NULL; @@ -2819,7 +3006,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams( 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.deprecated_ekt = NULL; policy_aes_gcm.window_size = 128; policy_aes_gcm.allow_repeat_tx = 0; policy_aes_gcm.next = NULL; @@ -2829,7 +3016,7 @@ srtp_err_status_t srtp_test_setup_protect_trailer_streams( 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.deprecated_ekt = NULL; policy_aes_gcm_mki.window_size = 128; policy_aes_gcm_mki.allow_repeat_tx = 0; policy_aes_gcm_mki.next = NULL; @@ -3730,23 +3917,7 @@ const srtp_policy_t aes_256_hmac_policy = { 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 +char ekt_test_policy = 'x'; const srtp_policy_t hmac_only_with_ekt_policy = { { ssrc_any_outbound, 0 }, /* SSRC */ @@ -3769,7 +3940,7 @@ const srtp_policy_t hmac_only_with_ekt_policy = { NULL, (srtp_master_key_t **)test_keys, 2, /* indicates the number of Master keys */ - &ekt_test_policy, /* indicates that EKT is not in use */ + &ekt_test_policy, /* requests deprecated EKT functionality */ 128, /* replay window size */ 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ @@ -3800,6 +3971,12 @@ const srtp_policy_t *policy_array[] = { #endif &null_policy, &aes_256_hmac_policy, + NULL +}; +// clang-format on + +// clang-format off +const srtp_policy_t *invalid_policy_array[] = { &hmac_only_with_ekt_policy, NULL }; diff --git a/third_party/libsrtp/src/test/test_srtp.c b/third_party/libsrtp/src/test/test_srtp.c index cdc9b5d5b762..0cea1f3c3742 100644 --- a/third_party/libsrtp/src/test/test_srtp.c +++ b/third_party/libsrtp/src/test/test_srtp.c @@ -43,16 +43,16 @@ * */ -/* - * Test specific. - */ -#include "cutest.h" - /* * libSRTP specific. */ #include "../srtp/srtp.c" // Get access to static functions +/* + * Test specific. + */ +#include "cutest.h" + /* * Standard library. */ @@ -152,14 +152,15 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number() srtp_session_keys_t session_keys; srtcp_hdr_t header; v128_t output_iv[SAMPLE_COUNT]; - memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t)); uint32_t sequence_num[SAMPLE_COUNT]; + 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 - v128_t final_iv[SAMPLE_COUNT]; memset(&final_iv, 0, SAMPLE_COUNT * sizeof(v128_t)); final_iv[0].v8[11] = 0xFF; final_iv[1].v8[10] = 0xFF; @@ -170,7 +171,6 @@ void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number() memset(&header, 0, sizeof(srtcp_hdr_t)); // When - size_t i = 0; for (i = 0; i < SAMPLE_COUNT; i++) { TEST_CHECK(srtp_calc_aead_iv_srtcp(&session_keys, &output_iv[i], sequence_num[i], diff --git a/third_party/libsrtp/src/test/ut_sim.c b/third_party/libsrtp/src/test/ut_sim.c new file mode 100644 index 000000000000..2825b68df914 --- /dev/null +++ b/third_party/libsrtp/src/test/ut_sim.c @@ -0,0 +1,107 @@ +/* + * ut_sim.c + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * 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 "ut_sim.h" +#include "cipher_priv.h" + +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; + + for (i = 0; i < UT_BUF; i++) + utc->buffer[i] = i; + + 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; + + tmp = utc->buffer[0]; + utc->index++; + utc->buffer[0] = utc->index; + + 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; + + 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; +} + +#endif diff --git a/third_party/libsrtp/src/test/ut_sim.h b/third_party/libsrtp/src/test/ut_sim.h new file mode 100644 index 000000000000..e678b5fdf7e4 --- /dev/null +++ b/third_party/libsrtp/src/test/ut_sim.h @@ -0,0 +1,83 @@ +/* + * ut-sim.h + * + * an unreliable transport simulator + * (for testing replay databases and suchlike) + * + * 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 UT_SIM_H +#define UT_SIM_H + +#include "integers.h" /* for uint32_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define UT_BUF 160 /* maximum amount of packet reorder */ + +typedef struct { + uint32_t index; + uint32_t buffer[UT_BUF]; +} 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); + +/* + * ut_next_index(&u) returns the next index from the simulated + * unreliable connection + */ + +uint32_t ut_next_index(ut_connection *utc); + +#ifdef __cplusplus +} +#endif + +#endif /* UT_SIM_H */ diff --git a/third_party/libsrtp/src/test/util.c b/third_party/libsrtp/src/test/util.c index 4465e90ccdfa..c0f761490311 100644 --- a/third_party/libsrtp/src/test/util.c +++ b/third_party/libsrtp/src/test/util.c @@ -42,13 +42,14 @@ * */ +#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 char bit_string[MAX_PRINT_STRING_LEN + 1]; static inline int hex_char_to_nibble(uint8_t c) { diff --git a/third_party/libsrtp/srtp_update.log b/third_party/libsrtp/srtp_update.log index 3ebbbfcbe15c..071f60f5629b 100644 --- a/third_party/libsrtp/srtp_update.log +++ b/third_party/libsrtp/srtp_update.log @@ -1,3 +1,4 @@ srtp updated from CVS on Fri Sep 21 14:51:37 EDT 2012 srtp updated to revision 8f38517394a45678cd4468febf69f75722f35d00 from git on Wed Nov 22 14:15:32 PST 2017 srtp updated to revision bb0412ee84ebe3d2916b45b19de72fabb183d9db from git on Tue Sep 11 21:51:05 PDT 2018 +srtp updated to release 2.4.2 from github on Mon Feb 7 06:03:40 PM EST 2022 diff --git a/third_party/libsrtp/update_srtp.sh b/third_party/libsrtp/update_srtp.sh index 61fa7c4518cd..36e1e72a0718 100644 --- a/third_party/libsrtp/update_srtp.sh +++ b/third_party/libsrtp/update_srtp.sh @@ -16,11 +16,11 @@ if [ "$1" ] ; then DATE=`date` REVISION=`(cd $1; git log --pretty=oneline | head -1 | cut -c 1-40)` - cp -rf $1/srtp $1/crypto $1/include $1/test $1/LICENSE $1/README.md netwerk/srtp/src + cp -rf $1/srtp $1/crypto $1/include $1/test $1/LICENSE $1/CHANGES $1/README.md third_party/libsrtp/src - hg addremove netwerk/srtp/src --include "netwerk/srtp/src/VERSION" --include "netwerk/srtp/src/LICENSE" --include "netwerk/srtp/src/README.md" --include "**.c" --include "**.h" --similarity 90 + hg addremove third_party/libsrtp/src --include "third_party/libsrtp/src/VERSION" --include "third_party/libsrtp/src/LICENSE" --include "third_party/libsrtp/src/README.md" --include "**.c" --include "**.h" --similarity 90 - echo "srtp updated to revision $REVISION from git on $DATE" >> netwerk/srtp/srtp_update.log + echo "srtp updated to revision $REVISION from git on $DATE" >> third_party/libsrtp/srtp_update.log echo "srtp updated to revision $REVISION from git on $DATE" echo "WARNING: reapply any local patches!" else