diff --git a/.github/workflows/actions-ci.yml b/.github/workflows/actions-ci.yml index 3f24f4e86a..dfc0686527 100644 --- a/.github/workflows/actions-ci.yml +++ b/.github/workflows/actions-ci.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 - name: Sanity Test Run run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get install ninja-build cmake -GNinja -Btest_build_dir ninja -C test_build_dir run_tests diff --git a/.github/workflows/aws-lc-rs.yml b/.github/workflows/aws-lc-rs.yml index 51f18012c0..129030976a 100644 --- a/.github/workflows/aws-lc-rs.yml +++ b/.github/workflows/aws-lc-rs.yml @@ -32,7 +32,7 @@ jobs: args: rust-script - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc clang ninja-build golang - name: Remove aws-lc submodule from crate directory working-directory: ./aws-lc-rs/aws-lc-sys diff --git a/.github/workflows/codecov-ci.yml b/.github/workflows/codecov-ci.yml index 79b27774d3..51c4c7660f 100644 --- a/.github/workflows/codecov-ci.yml +++ b/.github/workflows/codecov-ci.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Install lcov run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install lcov - uses: actions/checkout@v4 - name: Run Code Coverage Build diff --git a/.github/workflows/cross-test.yml b/.github/workflows/cross-test.yml index 4fb81a8ac2..097e9ae5f6 100644 --- a/.github/workflows/cross-test.yml +++ b/.github/workflows/cross-test.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: PPC64 Build/Test @@ -25,7 +25,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: PPC32 Build/Test @@ -36,7 +36,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: PPC32 Build/Test @@ -47,7 +47,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: PPC64LE Build/Test @@ -58,7 +58,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: RISC-V 64 Build/Test @@ -76,7 +76,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: armv6 Build/Test @@ -86,7 +86,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: loongarch64 Build/Test @@ -97,7 +97,7 @@ jobs: steps: - name: Install qemu run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y install qemu-user qemu-user-binfmt - uses: actions/checkout@v4 - name: s390x Build/Test diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 34f4b1e343..8d5a63107a 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -21,7 +21,7 @@ jobs: - name: Install OS Dependencies run: | which go - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build make sudo rm -rf /usr/local/go sudo rm /usr/bin/go diff --git a/.github/workflows/integrations.yml b/.github/workflows/integrations.yml index 4635bda442..700d4a870a 100644 --- a/.github/workflows/integrations.yml +++ b/.github/workflows/integrations.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Run integration build @@ -28,7 +28,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update && sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang autoconf-archive libcmocka0 libcmocka-dev procps iproute2 build-essential git pkg-config gcc libtool automake libssl-dev uthash-dev autoconf doxygen libjson-c-dev libini-config-dev libcurl4-openssl-dev uuid-dev libltdl-dev libusb-1.0-0-dev libftdi-dev libglib2.0-dev pandoc + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none && sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang autoconf-archive libcmocka0 libcmocka-dev procps iproute2 build-essential git pkg-config gcc libtool automake libssl-dev uthash-dev autoconf doxygen libjson-c-dev libini-config-dev libcurl4-openssl-dev uuid-dev libltdl-dev libusb-1.0-0-dev libftdi-dev libglib2.0-dev pandoc - uses: actions/checkout@v3 - name: Run integration build run: | @@ -45,7 +45,7 @@ jobs: steps: - name: Install OS Dependencies run: | - apt-get update + apt-get update -o Acquire::Languages=none -o Acquire::Translation=none apt-get -y --no-install-recommends install cmake gcc g++ ninja-build golang make python3 python3-sphinx autoconf libtool pkg-config git libc++-dev python3-six - uses: actions/checkout@v3 - name: Run integration build @@ -57,7 +57,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make libpcap-dev binutils-dev - uses: actions/checkout@v3 - name: Run integration build @@ -69,7 +69,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Run trousers build @@ -81,7 +81,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Run ntp build @@ -93,7 +93,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update && sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make autoconf pkg-config openssl + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none && sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make autoconf pkg-config openssl - uses: actions/checkout@v3 - name: Run integration build run: | @@ -105,7 +105,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Build AWS-LC, build python, run tests @@ -127,7 +127,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Build AWS-LC, build python, run tests @@ -143,7 +143,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make - uses: actions/checkout@v3 - name: Build AWS-LC, build openldap, run tests @@ -155,7 +155,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make python3 python3-pytest autoconf pkg-config libcmocka-dev liburcu-dev libuv1-dev libnghttp2-dev libcap-dev libprotobuf-c-dev protobuf-c-compiler libfstrm-dev libjemalloc-dev - uses: actions/checkout@v3 - name: Run bind9 build @@ -167,7 +167,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install \ cmake gcc ninja-build golang make gperf bison flex autogen autoconf \ pkg-config libtool gettext libgmp-dev libsystemd-dev @@ -181,7 +181,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install \ cmake gcc ninja-build golang libnl-3-dev libnl-genl-3-dev \ libcap-ng-dev liblz4-dev liblzo2-dev libpam-dev libcmocka-dev \ @@ -196,7 +196,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install \ cmake gcc ninja-build golang - uses: actions/checkout@v4 @@ -209,7 +209,7 @@ jobs: steps: - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install \ curl gnupg build-essential lcov wget python3-pip cmake gcc ninja-build golang sudo pip3 install gcovr diff --git a/.github/workflows/opensslcomparison.yml b/.github/workflows/opensslcomparison.yml index 0e568555b0..31f6ba021c 100644 --- a/.github/workflows/opensslcomparison.yml +++ b/.github/workflows/opensslcomparison.yml @@ -12,16 +12,11 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Install OS Dependencies run: | - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get -y --no-install-recommends install \ cmake gcc ninja-build golang make autoconf pkg-config openssl - - - name: Make the script executable - run: chmod +x ./tests/ci/run_openssl_comparison_tests.sh - - name: Build AWS-LC & OpenSSL and Run Comparison Tests run: | ./tests/ci/run_openssl_comparison_tests.sh diff --git a/.github/workflows/windows-alt.yml b/.github/workflows/windows-alt.yml index 20a397f919..ccb671eefb 100644 --- a/.github/workflows/windows-alt.yml +++ b/.github/workflows/windows-alt.yml @@ -164,14 +164,14 @@ jobs: - name: Install Tools run: | set -ex - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get install --assume-yes --no-install-recommends software-properties-common sudo add-apt-repository --yes ppa:longsleep/golang-backports sudo dpkg --add-architecture i386 sudo mkdir -pm755 /etc/apt/keyrings sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources - sudo apt-get update + sudo apt-get update -o Acquire::Languages=none -o Acquire::Translation=none sudo apt-get install --assume-yes --no-install-recommends build-essential cmake golang-go nasm clang wget mingw-w64 sudo apt-get install --assume-yes --install-recommends winehq-stable wine-binfmt sudo update-binfmts --display diff --git a/BUILDING.md b/BUILDING.md index 3fb7ea6ecf..a8988a3fd2 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -218,7 +218,7 @@ Both sets of tests may also be run with `ninja -C build run_tests`, but CMake If your project is unable to take on a Go or Perl dependency, the AWS-LC repository provides generated build files. These can be used in place of the files that would -normally be generated by these dependencies. +normally be generated by these dependencies. It is still recommended to have both Go and Perl installed to be able to run the full range of unit tests, as well as running valgrind and SDE tests. Building without Go now @@ -228,12 +228,46 @@ More information on this can be found in [INCORPORATING.md](/INCORPORATING.md). # Snapsafe Detection -AWS-LC supports Snapsafe-type uniqueness breaking event detection -on Linux using SysGenID (https://lkml.org/lkml/2021/3/8/677). This mechanism -is used for security hardening. If a SysGenID interface is not found, then the -mechanism is ignored. +AWS-LC supports Snapsafe-type uniqueness breaking event detection +on Linux using SysGenID (https://lkml.org/lkml/2021/3/8/677). This mechanism +is used for security hardening. If a SysGenID interface is not found, then the +mechanism is ignored. ## Snapsafe Prerequisites -Snapshots taken on active hosts can potentially be unsafe to use. +Snapshots taken on active hosts can potentially be unsafe to use. See "Snapshot Safety Prerequisites" here: https://lkml.org/lkml/2021/3/8/677 + +# Data Independent Timing on AArch64 + +The Data Independent Timing (DIT) flag on Arm64 processors, when +enabled, ensures the following as per [Arm A-profile Architecture +Registers +Document](https://developer.arm.com/documentation/ddi0601/2023-12/AArch64-Registers/DIT--Data-Independent-Timing): +- The timing of every load and store instruction is insensitive to the + value of the data being loaded or stored. +- For certain data processing instructions, the instruction takes a + time which is independent of the data in the registers and the NZCV + flags. + +It is also expected to disable the Data Memory-dependent Prefetcher +(DMP) feature of Apple M-series CPUs starting at M3 as per [this +article](https://appleinsider.com/articles/24/03/21/apple-silicon-vulnerability-leaks-encryption-keys-and-cant-be-patched-easily). + +Building with the option `-DENABLE_DATA_INDEPENDENT_TIMING_AARCH64=ON` +will enable the macro `SET_DIT_AUTO_DISABLE`. This macro is present at +the entry of functions that process/load/store secret data to enable +the DIT flag and then set it to its original value on entry. With +this build option, there is an effect on performance that varies by +function and by processor architecture. The effect is mostly due to +enabling and disabling the DIT flag. If it remains enabled over many +calls, the effect can be largely mitigated. Hence, the macro can be +inserted in the caller's application at the beginning of the code +scope that makes repeated calls to AWS-LC cryptographic +functions. Alternatively, the functions `armv8_enable_dit` and +`armv8_restore_dit` can be placed at the beginning and the end of +the code section, respectively. +An example of that usage is present in the benchmarking function +`Speed()` in `tool/speed.cc` when the `-dit` option is used + + ./tool/bssl speed -dit \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2768cf53fd..81b4fa8822 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.0) +if(POLICY CMP0091) +cmake_policy(SET CMP0091 NEW) +endif() + # Defer enabling C and CXX languages. project(AWSLC NONE) @@ -27,6 +31,7 @@ option(ENABLE_DILITHIUM "Enable Dilithium signatures in the EVP API" OFF) option(DISABLE_PERL "Disable Perl for AWS-LC" OFF) option(DISABLE_GO "Disable Go for AWS-LC" OFF) option(ENABLE_FIPS_ENTROPY_CPU_JITTER "Enable FIPS entropy source: CPU Jitter" OFF) +option(ENABLE_DATA_INDEPENDENT_TIMING_AARCH64 "Enable Data-Independent Timing (DIT) flag on Arm64" OFF) include(cmake/go.cmake) enable_language(C) @@ -173,6 +178,9 @@ foreach(VAR CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_ASM_FLAGS) endforeach() if(BORINGSSL_PREFIX AND BORINGSSL_PREFIX_SYMBOLS AND GO_EXECUTABLE) + + message(STATUS "Prefix build configured: building headers using prefix \"${BORINGSSL_PREFIX}\" and symbols file \"${BORINGSSL_PREFIX_SYMBOLS}\"") + if(IS_ABSOLUTE ${BORINGSSL_PREFIX_SYMBOLS}) set(BORINGSSL_PREFIX_SYMBOLS_PATH ${BORINGSSL_PREFIX_SYMBOLS}) else() @@ -214,6 +222,8 @@ if(BORINGSSL_PREFIX AND BORINGSSL_PREFIX_SYMBOLS AND GO_EXECUTABLE) ) elseif(BORINGSSL_PREFIX AND BORINGSSL_PREFIX_HEADERS) + message(STATUS "Prefix build configured: performing build using prefix \"${BORINGSSL_PREFIX}\" and headers path \"${BORINGSSL_PREFIX_HEADERS}\"") + if(IS_ABSOLUTE ${BORINGSSL_PREFIX_HEADERS}) set(BORINGSSL_PREFIX_HEADERS_PATH ${BORINGSSL_PREFIX_HEADERS}) else() @@ -812,6 +822,10 @@ else() set(ARCH "generic") endif() +if(ENABLE_DATA_INDEPENDENT_TIMING_AARCH64) + add_definitions(-DMAKE_DIT_AVAILABLE) +endif() + if(USE_CUSTOM_LIBCXX) if(NOT CLANG) message(FATAL_ERROR "USE_CUSTOM_LIBCXX only supported with Clang") diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc index d738e59071..830605086c 100644 --- a/crypto/asn1/asn1_test.cc +++ b/crypto/asn1/asn1_test.cc @@ -2462,9 +2462,13 @@ TEST(ASN1Test, ASN1Dup) { 0); bssl::UniquePtr evp_pkey(EVP_PKEY_new()); + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_FALSE(EVP_PKEY_get0(evp_pkey.get())); X509_PUBKEY *tmp_key = nullptr; ASSERT_TRUE(evp_pkey); ASSERT_TRUE(EVP_PKEY_set1_EC_KEY(evp_pkey.get(), key.get())); + ASSERT_EQ(key.get(), EVP_PKEY_get0(evp_pkey.get())); + OPENSSL_END_ALLOW_DEPRECATED ASSERT_TRUE(X509_PUBKEY_set(&tmp_key, evp_pkey.get())); bssl::UniquePtr x509_pubkey(tmp_key); bssl::UniquePtr x509_pubkey_copy((X509_PUBKEY *)ASN1_dup( diff --git a/crypto/bio/bio.c b/crypto/bio/bio.c index 60410ef7b1..0fccaefbce 100644 --- a/crypto/bio/bio.c +++ b/crypto/bio/bio.c @@ -162,6 +162,10 @@ int BIO_read(BIO *bio, void *buf, int len) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } + if (len <= 0) { + return 0; + } + if (HAS_CALLBACK(bio)) { ret = (int)bio->callback_ex(bio, BIO_CB_READ, buf, len, 0, 0L, 1L, NULL); if (ret <= 0) { @@ -172,9 +176,6 @@ int BIO_read(BIO *bio, void *buf, int len) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); return -2; } - if (len <= 0) { - return 0; - } ret = bio->method->bread(bio, buf, len); if (ret > 0) { bio->num_read += ret; @@ -212,6 +213,10 @@ int BIO_gets(BIO *bio, char *buf, int len) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } + if (len <= 0) { + return 0; + } + int ret = 0; if (HAS_CALLBACK(bio)) { ret = (int)bio->callback_ex(bio, BIO_CB_GETS, buf, len, 0, 0L, 1L, NULL); @@ -223,9 +228,6 @@ int BIO_gets(BIO *bio, char *buf, int len) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); return -2; } - if (len <= 0) { - return 0; - } ret = bio->method->bgets(bio, buf, len); if (ret > 0) { bio->num_read += ret; @@ -241,6 +243,10 @@ int BIO_write(BIO *bio, const void *in, int inl) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); return -2; } + if (inl <= 0) { + return 0; + } + if (HAS_CALLBACK(bio)) { ret = (int)bio->callback_ex(bio, BIO_CB_WRITE, in, inl, 0, 0L, 1L, NULL); if (ret <= 0) { @@ -252,9 +258,6 @@ int BIO_write(BIO *bio, const void *in, int inl) { OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); return -2; } - if (inl <= 0) { - return 0; - } ret = bio->method->bwrite(bio, in, inl); if (ret > 0) { bio->num_write += ret; diff --git a/crypto/crypto_test.cc b/crypto/crypto_test.cc index 3434527932..9ceff77d4e 100644 --- a/crypto/crypto_test.cc +++ b/crypto/crypto_test.cc @@ -27,6 +27,25 @@ #include #include "test/test_util.h" +static int AWS_LC_ERROR_return(void) { + GUARD_PTR(NULL); + return 1; +} + +static int AWS_LC_SUCCESS_return(void) { + char non_null_ptr[1]; + GUARD_PTR(non_null_ptr); + return 1; +} + +TEST(CryptoTest, SafetyMacro) { + // It is assumed that |GUARD_PTR| returns 0 for fail/false and 1 for + // success/true. Change these default values with care because code might not + // use the related macros |AWS_LC_ERROR| or |AWS_LC_SUCCESS|. + EXPECT_EQ(AWS_LC_ERROR_return(), 0); + EXPECT_EQ(AWS_LC_SUCCESS_return(), 1); +} + // Test that OPENSSL_VERSION_NUMBER and OPENSSL_VERSION_TEXT are consistent. // Node.js parses the version out of OPENSSL_VERSION_TEXT instead of using // OPENSSL_VERSION_NUMBER. diff --git a/crypto/curve25519/curve25519.c b/crypto/curve25519/curve25519.c index 91379a6b59..2f3e72934f 100644 --- a/crypto/curve25519/curve25519.c +++ b/crypto/curve25519/curve25519.c @@ -29,6 +29,7 @@ #include "internal.h" #include "../internal.h" +#include "../fipsmodule/cpucap/internal.h" // X25519 [1] and Ed25519 [2] is an ECDHE protocol and signature scheme, // respectively. This file contains an implementation of both using two @@ -100,6 +101,7 @@ void ED25519_keypair_from_seed(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], void ED25519_keypair(uint8_t out_public_key[ED25519_PUBLIC_KEY_LEN], uint8_t out_private_key[ED25519_PRIVATE_KEY_LEN]) { + SET_DIT_AUTO_DISABLE; // Ed25519 key generation: rfc8032 5.1.5 // Private key is 32 octets of random data. @@ -127,6 +129,7 @@ int ED25519_sign(uint8_t out_sig[ED25519_SIGNATURE_LEN], // seed = private_key[0:31] // A = private_key[32:61] (per 5.1.5.4) // Compute az = SHA512(seed). + SET_DIT_AUTO_DISABLE; uint8_t az[SHA512_DIGEST_LENGTH]; SHA512(private_key, ED25519_PRIVATE_KEY_SEED_LEN, az); // s = az[0:31] @@ -217,6 +220,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len, void X25519_public_from_private( uint8_t out_public_value[X25519_PUBLIC_VALUE_LEN], const uint8_t private_key[X25519_PRIVATE_KEY_LEN]) { + SET_DIT_AUTO_DISABLE; #if defined(CURVE25519_S2N_BIGNUM_CAPABLE) x25519_public_from_private_s2n_bignum(out_public_value, private_key); @@ -229,6 +233,7 @@ void X25519_public_from_private( void X25519_keypair(uint8_t out_public_value[X25519_PUBLIC_VALUE_LEN], uint8_t out_private_key[X25519_PRIVATE_KEY_LEN]) { + SET_DIT_AUTO_DISABLE; RAND_bytes(out_private_key, X25519_PRIVATE_KEY_LEN); @@ -256,6 +261,7 @@ int X25519(uint8_t out_shared_key[X25519_SHARED_KEY_LEN], const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN]) { + SET_DIT_AUTO_DISABLE; static const uint8_t kZeros[X25519_SHARED_KEY_LEN] = {0}; #if defined(CURVE25519_S2N_BIGNUM_CAPABLE) diff --git a/crypto/des/des.c b/crypto/des/des.c index 6f0d300f5a..e40fc7659d 100644 --- a/crypto/des/des.c +++ b/crypto/des/des.c @@ -61,6 +61,91 @@ #include "internal.h" +/* IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 +16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 +24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + +32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 +40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 +48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 +56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + +The output has been subject to swaps of the form +0 1 -> 3 1 but the odd and even bits have been put into +2 3 2 0 +different words. The main trick is to remember that +t=((l>>size)^r)&(mask); +r^=t; +l^=(t<> (n)) ^ (b)) & (m)); \ + (b) ^= (t); \ + (a) ^= ((t) << (n)); \ + } while (0) + +#define IP(l, r) \ + do { \ + uint32_t tt; \ + PERM_OP(r, l, tt, 4, 0x0f0f0f0fL); \ + PERM_OP(l, r, tt, 16, 0x0000ffffL); \ + PERM_OP(r, l, tt, 2, 0x33333333L); \ + PERM_OP(l, r, tt, 8, 0x00ff00ffL); \ + PERM_OP(r, l, tt, 1, 0x55555555L); \ + } while (0) + +#define FP(l, r) \ + do { \ + uint32_t tt; \ + PERM_OP(l, r, tt, 1, 0x55555555L); \ + PERM_OP(r, l, tt, 8, 0x00ff00ffL); \ + PERM_OP(l, r, tt, 2, 0x33333333L); \ + PERM_OP(r, l, tt, 16, 0x0000ffffL); \ + PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \ + } while (0) + +#define LOAD_DATA(ks, R, S, u, t, E0, E1) \ + do { \ + (u) = (R) ^ (ks)->subkeys[S][0]; \ + (t) = (R) ^ (ks)->subkeys[S][1]; \ + } while (0) + +#define D_ENCRYPT(ks, LL, R, S) \ + do { \ + LOAD_DATA(ks, R, S, u, t, E0, E1); \ + t = CRYPTO_rotr_u32(t, 4); \ + (LL) ^= \ + DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \ + DES_SPtrans[4][(u >> 18L) & 0x3f] ^ \ + DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \ + DES_SPtrans[3][(t >> 10L) & 0x3f] ^ \ + DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \ + } while (0) + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + static const uint32_t des_skb[8][64] = { { // for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 0x00000000, 0x00000010, 0x20000000, 0x20000010, 0x00010000, @@ -445,7 +530,8 @@ int DES_is_weak_key(const DES_cblock *key) return (int)(result & 1); } -static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) { +static void DES_encrypt1(uint32_t data[2], const DES_key_schedule *ks, + int enc) { uint32_t l, r, t, u; r = data[0]; @@ -509,7 +595,8 @@ static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) { data[1] = r; } -static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) { +static void DES_encrypt2(uint32_t data[2], const DES_key_schedule *ks, + int enc) { uint32_t l, r, t, u; r = data[0]; @@ -566,7 +653,7 @@ static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) { data[1] = CRYPTO_rotr_u32(r, 3); } -void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, +void DES_encrypt3(uint32_t data[2], const DES_key_schedule *ks1, const DES_key_schedule *ks2, const DES_key_schedule *ks3) { uint32_t l, r; @@ -575,9 +662,9 @@ void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, IP(l, r); data[0] = l; data[1] = r; - DES_encrypt2((uint32_t *)data, ks1, DES_ENCRYPT); - DES_encrypt2((uint32_t *)data, ks2, DES_DECRYPT); - DES_encrypt2((uint32_t *)data, ks3, DES_ENCRYPT); + DES_encrypt2(data, ks1, DES_ENCRYPT); + DES_encrypt2(data, ks2, DES_DECRYPT); + DES_encrypt2(data, ks3, DES_ENCRYPT); l = data[0]; r = data[1]; FP(r, l); @@ -585,7 +672,7 @@ void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, data[1] = r; } -void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, +void DES_decrypt3(uint32_t data[2], const DES_key_schedule *ks1, const DES_key_schedule *ks2, const DES_key_schedule *ks3) { uint32_t l, r; @@ -594,9 +681,9 @@ void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, IP(l, r); data[0] = l; data[1] = r; - DES_encrypt2((uint32_t *)data, ks3, DES_DECRYPT); - DES_encrypt2((uint32_t *)data, ks2, DES_ENCRYPT); - DES_encrypt2((uint32_t *)data, ks1, DES_DECRYPT); + DES_encrypt2(data, ks3, DES_DECRYPT); + DES_encrypt2(data, ks2, DES_ENCRYPT); + DES_encrypt2(data, ks1, DES_DECRYPT); l = data[0]; r = data[1]; FP(r, l); @@ -643,7 +730,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin1 ^= tout1; tin[1] = tin1; - DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + DES_encrypt1(tin, schedule, DES_ENCRYPT); tout0 = tin[0]; l2c(tout0, out); tout1 = tin[1]; @@ -655,7 +742,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin1 ^= tout1; tin[1] = tin1; - DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + DES_encrypt1(tin, schedule, DES_ENCRYPT); tout0 = tin[0]; l2c(tout0, out); tout1 = tin[1]; @@ -672,7 +759,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; c2l(in, tin1); tin[1] = tin1; - DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + DES_encrypt1(tin, schedule, DES_DECRYPT); tout0 = tin[0] ^ xor0; tout1 = tin[1] ^ xor1; l2c(tout0, out); @@ -685,7 +772,7 @@ void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; c2l(in, tin1); tin[1] = tin1; - DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + DES_encrypt1(tin, schedule, DES_DECRYPT); tout0 = tin[0] ^ xor0; tout1 = tin[1] ^ xor1; l2cn(tout0, tout1, out, len); @@ -745,7 +832,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin[1] = tin1; - DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + DES_encrypt3(tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; @@ -759,7 +846,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin[1] = tin1; - DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + DES_encrypt3(tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; @@ -783,7 +870,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin[1] = tin1; - DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + DES_decrypt3(tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; @@ -803,7 +890,7 @@ void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, tin[0] = tin0; tin[1] = tin1; - DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + DES_decrypt3(tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; @@ -829,16 +916,3 @@ void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, int enc) { DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc); } - -#undef HPERM_OP -#undef c2l -#undef l2c -#undef c2ln -#undef l2cn -#undef PERM_OP -#undef IP -#undef FP -#undef LOAD_DATA -#undef D_ENCRYPT -#undef ITERATIONS -#undef HALF_ITERATIONS diff --git a/crypto/des/internal.h b/crypto/des/internal.h index 2124fd5812..0d07a1b026 100644 --- a/crypto/des/internal.h +++ b/crypto/des/internal.h @@ -58,6 +58,7 @@ #define OPENSSL_HEADER_DES_INTERNAL_H #include +#include #include "../internal.h" @@ -145,90 +146,18 @@ extern "C" { } \ } while (0) -/* IP and FP - * The problem is more of a geometric problem that random bit fiddling. - 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 - 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 -16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 -24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 - -32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 -40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 -48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 -56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 - -The output has been subject to swaps of the form -0 1 -> 3 1 but the odd and even bits have been put into -2 3 2 0 -different words. The main trick is to remember that -t=((l>>size)^r)&(mask); -r^=t; -l^=(t<> (n)) ^ (b)) & (m)); \ - (b) ^= (t); \ - (a) ^= ((t) << (n)); \ - } while (0) - -#define IP(l, r) \ - do { \ - uint32_t tt; \ - PERM_OP(r, l, tt, 4, 0x0f0f0f0fL); \ - PERM_OP(l, r, tt, 16, 0x0000ffffL); \ - PERM_OP(r, l, tt, 2, 0x33333333L); \ - PERM_OP(l, r, tt, 8, 0x00ff00ffL); \ - PERM_OP(r, l, tt, 1, 0x55555555L); \ - } while (0) - -#define FP(l, r) \ - do { \ - uint32_t tt; \ - PERM_OP(l, r, tt, 1, 0x55555555L); \ - PERM_OP(r, l, tt, 8, 0x00ff00ffL); \ - PERM_OP(l, r, tt, 2, 0x33333333L); \ - PERM_OP(r, l, tt, 16, 0x0000ffffL); \ - PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \ - } while (0) -#define LOAD_DATA(ks, R, S, u, t, E0, E1) \ - do { \ - (u) = (R) ^ (ks)->subkeys[S][0]; \ - (t) = (R) ^ (ks)->subkeys[S][1]; \ - } while (0) +// Private functions. +// +// These functions are only exported for use in |decrepit|. -#define D_ENCRYPT(ks, LL, R, S) \ - do { \ - LOAD_DATA(ks, R, S, u, t, E0, E1); \ - t = CRYPTO_rotr_u32(t, 4); \ - (LL) ^= \ - DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \ - DES_SPtrans[4][(u >> 18L) & 0x3f] ^ \ - DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \ - DES_SPtrans[3][(t >> 10L) & 0x3f] ^ \ - DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \ - } while (0) +OPENSSL_EXPORT void DES_decrypt3(uint32_t data[2], const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); -#define ITERATIONS 16 -#define HALF_ITERATIONS 8 +OPENSSL_EXPORT void DES_encrypt3(uint32_t data[2], const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); #if defined(__cplusplus) diff --git a/crypto/ecdh_extra/ecdh_test.cc b/crypto/ecdh_extra/ecdh_test.cc index 45c40db3df..eaa29956b6 100644 --- a/crypto/ecdh_extra/ecdh_test.cc +++ b/crypto/ecdh_extra/ecdh_test.cc @@ -264,7 +264,9 @@ static void RunWycheproofTest(FileTest *t) { } EC_KEY *peer_ec = EVP_PKEY_get0_EC_KEY(peer_evp.get()); ASSERT_TRUE(peer_ec); - + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_EQ(peer_ec, EVP_PKEY_get0(peer_evp.get())); + OPENSSL_END_ALLOW_DEPRECATED bssl::UniquePtr key(EC_KEY_new()); ASSERT_TRUE(key); ASSERT_TRUE(EC_KEY_set_group(key.get(), group)); diff --git a/crypto/evp_extra/evp_test.cc b/crypto/evp_extra/evp_test.cc index fb87e49818..3fe3f308e0 100644 --- a/crypto/evp_extra/evp_test.cc +++ b/crypto/evp_extra/evp_test.cc @@ -662,6 +662,9 @@ static void RunWycheproofVerifyTest(const char *path) { if (EVP_PKEY_id(key.get()) == EVP_PKEY_DSA) { // DSA is deprecated and is not usable via EVP. DSA *dsa = EVP_PKEY_get0_DSA(key.get()); + OPENSSL_BEGIN_ALLOW_DEPRECATED + ASSERT_EQ(dsa, EVP_PKEY_get0(key.get())); + OPENSSL_END_ALLOW_DEPRECATED uint8_t digest[EVP_MAX_MD_SIZE]; unsigned digest_len; ASSERT_TRUE( @@ -1022,6 +1025,9 @@ static EVP_PKEY * instantiate_and_set_private_key(const uint8_t *private_key, size_t private_key_size, int key_type, int curve_nid) { EVP_PKEY *pkey = NULL; + OPENSSL_BEGIN_ALLOW_DEPRECATED + EXPECT_FALSE(EVP_PKEY_get0(pkey)); + OPENSSL_END_ALLOW_DEPRECATED if (NID_X25519 == curve_nid) { pkey = EVP_PKEY_new_raw_private_key(curve_nid, nullptr, private_key, @@ -1037,7 +1043,11 @@ static EVP_PKEY * instantiate_and_set_private_key(const uint8_t *private_key, BN_free(private_key_bn); pkey = EVP_PKEY_new(); EXPECT_TRUE(pkey); + OPENSSL_BEGIN_ALLOW_DEPRECATED + EXPECT_FALSE(EVP_PKEY_get0(pkey)); EXPECT_TRUE(EVP_PKEY_assign(pkey, key_type, (EC_KEY *) ec_key)); + EXPECT_EQ(ec_key, EVP_PKEY_get0(pkey)); + OPENSSL_END_ALLOW_DEPRECATED } return pkey; diff --git a/crypto/fipsmodule/aes/aes.c b/crypto/fipsmodule/aes/aes.c index 60f3545796..40edc2982f 100644 --- a/crypto/fipsmodule/aes/aes.c +++ b/crypto/fipsmodule/aes/aes.c @@ -60,6 +60,7 @@ // code, above, is incompatible with the |aes_hw_*| functions. void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + SET_DIT_AUTO_DISABLE; if (hwaes_capable()) { aes_hw_encrypt(in, out, key); } else if (vpaes_capable()) { @@ -70,6 +71,7 @@ void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { } void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + SET_DIT_AUTO_DISABLE; if (hwaes_capable()) { aes_hw_decrypt(in, out, key); } else if (vpaes_capable()) { @@ -80,6 +82,7 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { } int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + SET_DIT_AUTO_DISABLE; if (bits != 128 && bits != 192 && bits != 256) { return -2; } @@ -93,6 +96,7 @@ int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { } int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + SET_DIT_AUTO_DISABLE; if (bits != 128 && bits != 192 && bits != 256) { return -2; } diff --git a/crypto/fipsmodule/aes/asm/aesni-x86_64.pl b/crypto/fipsmodule/aes/asm/aesni-x86_64.pl index 9e8804d591..fb31730c64 100644 --- a/crypto/fipsmodule/aes/asm/aesni-x86_64.pl +++ b/crypto/fipsmodule/aes/asm/aesni-x86_64.pl @@ -1307,10 +1307,7 @@ sub aesni_generate8 { lea 7($ctr),%r9 mov %r10d,0x60+12(%rsp) bswap %r9d - leaq OPENSSL_ia32cap_P(%rip),%r10 - mov 4(%r10),%r10d xor $key0,%r9d - and \$`1<<26|1<<22`,%r10d # isolate XSAVE+MOVBE mov %r9d,0x70+12(%rsp) $movkey 0x10($key),$rndkey1 @@ -1321,104 +1318,10 @@ sub aesni_generate8 { cmp \$8,$len # $len is in blocks jb .Lctr32_tail # short input if ($len<8) - sub \$6,$len # $len is biased by -6 - cmp \$`1<<22`,%r10d # check for MOVBE without XSAVE - je .Lctr32_6x # [which denotes Atom Silvermont] - lea 0x80($key),$key # size optimization - sub \$2,$len # $len is biased by -8 + sub \$8,$len # $len is biased by -8 jmp .Lctr32_loop8 -.align 16 -.Lctr32_6x: - shl \$4,$rounds - mov \$48,$rnds_ - bswap $key0 - lea 32($key,$rounds),$key # end of key schedule - sub %rax,%r10 # twisted $rounds - jmp .Lctr32_loop6 - -.align 16 -.Lctr32_loop6: - add \$6,$ctr # next counter value - $movkey -48($key,$rnds_),$rndkey0 - aesenc $rndkey1,$inout0 - mov $ctr,%eax - xor $key0,%eax - aesenc $rndkey1,$inout1 - movbe %eax,`0x00+12`(%rsp) # store next counter value - lea 1($ctr),%eax - aesenc $rndkey1,$inout2 - xor $key0,%eax - movbe %eax,`0x10+12`(%rsp) - aesenc $rndkey1,$inout3 - lea 2($ctr),%eax - xor $key0,%eax - aesenc $rndkey1,$inout4 - movbe %eax,`0x20+12`(%rsp) - lea 3($ctr),%eax - aesenc $rndkey1,$inout5 - $movkey -32($key,$rnds_),$rndkey1 - xor $key0,%eax - - aesenc $rndkey0,$inout0 - movbe %eax,`0x30+12`(%rsp) - lea 4($ctr),%eax - aesenc $rndkey0,$inout1 - xor $key0,%eax - movbe %eax,`0x40+12`(%rsp) - aesenc $rndkey0,$inout2 - lea 5($ctr),%eax - xor $key0,%eax - aesenc $rndkey0,$inout3 - movbe %eax,`0x50+12`(%rsp) - mov %r10,%rax # mov $rnds_,$rounds - aesenc $rndkey0,$inout4 - aesenc $rndkey0,$inout5 - $movkey -16($key,$rnds_),$rndkey0 - - call .Lenc_loop6 - - movdqu ($inp),$inout6 # load 6 input blocks - movdqu 0x10($inp),$inout7 - movdqu 0x20($inp),$in0 - movdqu 0x30($inp),$in1 - movdqu 0x40($inp),$in2 - movdqu 0x50($inp),$in3 - lea 0x60($inp),$inp # $inp+=6*16 - $movkey -64($key,$rnds_),$rndkey1 - pxor $inout0,$inout6 # inp^=E(ctr) - movaps 0x00(%rsp),$inout0 # load next counter [xor-ed with 0 round] - pxor $inout1,$inout7 - movaps 0x10(%rsp),$inout1 - pxor $inout2,$in0 - movaps 0x20(%rsp),$inout2 - pxor $inout3,$in1 - movaps 0x30(%rsp),$inout3 - pxor $inout4,$in2 - movaps 0x40(%rsp),$inout4 - pxor $inout5,$in3 - movaps 0x50(%rsp),$inout5 - movdqu $inout6,($out) # store 6 output blocks - movdqu $inout7,0x10($out) - movdqu $in0,0x20($out) - movdqu $in1,0x30($out) - movdqu $in2,0x40($out) - movdqu $in3,0x50($out) - lea 0x60($out),$out # $out+=6*16 - - sub \$6,$len - jnc .Lctr32_loop6 # loop if $len-=6 didn't borrow - - add \$6,$len # restore real remaining $len - jz .Lctr32_done # done if ($len==0) - - lea -48($rnds_),$rounds - lea -80($key,$rnds_),$key # restore $key - neg $rounds - shr \$4,$rounds # restore $rounds - jmp .Lctr32_tail - .align 32 .Lctr32_loop8: add \$8,$ctr # next counter value @@ -2910,16 +2813,10 @@ sub aesni_generate8 { movdqa $inout3,$in3 movdqu 0x50($inp),$inout5 movdqa $inout4,$in4 - leaq OPENSSL_ia32cap_P(%rip),%r9 - mov 4(%r9),%r9d cmp \$0x70,$len jbe .Lcbc_dec_six_or_seven - and \$`1<<26|1<<22`,%r9d # isolate XSAVE+MOVBE - sub \$0x50,$len # $len is biased by -5*16 - cmp \$`1<<22`,%r9d # check for MOVBE without XSAVE - je .Lcbc_dec_loop6_enter # [which denotes Atom Silvermont] - sub \$0x20,$len # $len is biased by -7*16 + sub \$0x70,$len # $len is biased by -7*16 lea 0x70($key),$key # size optimization jmp .Lcbc_dec_loop8_enter .align 16 @@ -3111,51 +3008,6 @@ sub aesni_generate8 { pxor $inout7,$inout7 jmp .Lcbc_dec_tail_collected -.align 16 -.Lcbc_dec_loop6: - movups $inout5,($out) - lea 0x10($out),$out - movdqu 0x00($inp),$inout0 # load input - movdqu 0x10($inp),$inout1 - movdqa $inout0,$in0 - movdqu 0x20($inp),$inout2 - movdqa $inout1,$in1 - movdqu 0x30($inp),$inout3 - movdqa $inout2,$in2 - movdqu 0x40($inp),$inout4 - movdqa $inout3,$in3 - movdqu 0x50($inp),$inout5 - movdqa $inout4,$in4 -.Lcbc_dec_loop6_enter: - lea 0x60($inp),$inp - movdqa $inout5,$inout6 - - call _aesni_decrypt6 - - pxor $iv,$inout0 # ^= IV - movdqa $inout6,$iv - pxor $in0,$inout1 - movdqu $inout0,($out) - pxor $in1,$inout2 - movdqu $inout1,0x10($out) - pxor $in2,$inout3 - movdqu $inout2,0x20($out) - pxor $in3,$inout4 - mov $key_,$key - movdqu $inout3,0x30($out) - pxor $in4,$inout5 - mov $rnds_,$rounds - movdqu $inout4,0x40($out) - lea 0x50($out),$out - sub \$0x60,$len - ja .Lcbc_dec_loop6 - - movdqa $inout5,$inout0 - add \$0x50,$len - jle .Lcbc_dec_clear_tail_collected - movups $inout5,($out) - lea 0x10($out),$out - .Lcbc_dec_tail: movups ($inp),$inout0 sub \$0x10,$len diff --git a/crypto/fipsmodule/cipher/aead.c b/crypto/fipsmodule/cipher/aead.c index a4df0b35ad..a5e47f98c6 100644 --- a/crypto/fipsmodule/cipher/aead.c +++ b/crypto/fipsmodule/cipher/aead.c @@ -79,6 +79,7 @@ int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len, size_t tag_len, enum evp_aead_direction_t dir) { + SET_DIT_AUTO_DISABLE; if (key_len != aead->key_len) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE); ctx->aead = NULL; @@ -124,6 +125,7 @@ int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { + SET_DIT_AUTO_DISABLE; if (in_len + ctx->aead->overhead < in_len /* overflow */) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); goto error; @@ -162,6 +164,7 @@ int EVP_AEAD_CTX_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t in_len, const uint8_t *extra_in, size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + SET_DIT_AUTO_DISABLE; //check that it was preserved // |in| and |out| may alias exactly, |out_tag| may not alias. if (!check_alias(in, in_len, out, in_len) || buffers_alias(out, in_len, out_tag, max_out_tag_len) || @@ -194,6 +197,7 @@ int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { + SET_DIT_AUTO_DISABLE; if (!check_alias(in, in_len, out, max_out_len)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); goto error; @@ -241,6 +245,7 @@ int EVP_AEAD_CTX_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + SET_DIT_AUTO_DISABLE; if (!check_alias(in, in_len, out, in_len)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); goto error; diff --git a/crypto/fipsmodule/cipher/cipher.c b/crypto/fipsmodule/cipher/cipher.c index b9c5834be0..7a71fb2fc0 100644 --- a/crypto/fipsmodule/cipher/cipher.c +++ b/crypto/fipsmodule/cipher/cipher.c @@ -104,6 +104,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { } int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { + SET_DIT_AUTO_DISABLE; if (in == NULL || in->cipher == NULL) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED); return 0; @@ -145,6 +146,7 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *engine, const uint8_t *key, const uint8_t *iv, int enc) { + SET_DIT_AUTO_DISABLE; GUARD_PTR(ctx); if (enc == -1) { enc = ctx->encrypt; @@ -262,6 +264,7 @@ static int block_remainder(const EVP_CIPHER_CTX *ctx, int len) { int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len) { + SET_DIT_AUTO_DISABLE; GUARD_PTR(ctx); if (ctx->poisoned) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -354,6 +357,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, } int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + SET_DIT_AUTO_DISABLE; int n; unsigned int i, b, bl; GUARD_PTR(ctx); @@ -408,6 +412,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, int in_len) { + SET_DIT_AUTO_DISABLE; GUARD_PTR(ctx); if (ctx->poisoned) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -474,6 +479,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, } int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { + SET_DIT_AUTO_DISABLE; int i, n; unsigned int b; *out_len = 0; @@ -482,7 +488,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { // |ctx->cipher->cipher| calls the static aes encryption function way under // the hood instead of |EVP_Cipher|, so the service indicator does not need // locking here. - + if (ctx->poisoned) { OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -546,6 +552,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { + SET_DIT_AUTO_DISABLE; GUARD_PTR(ctx); GUARD_PTR(ctx->cipher); const int ret = ctx->cipher->cipher(ctx, out, in, in_len); diff --git a/crypto/fipsmodule/cpucap/cpu_aarch64.c b/crypto/fipsmodule/cpucap/cpu_aarch64.c index 5a4de192b5..8f6c06a17e 100644 --- a/crypto/fipsmodule/cpucap/cpu_aarch64.c +++ b/crypto/fipsmodule/cpucap/cpu_aarch64.c @@ -49,4 +49,44 @@ void handle_cpu_env(uint32_t *out, const char *in) { } } +#if defined(MAKE_DIT_AVAILABLE) && !defined(OPENSSL_WINDOWS) +// "DIT" is not recognised as a register name by clang-10 (at least) +// Register's encoded name is from e.g. +// https://github.com/ashwio/arm64-sysreg-lib/blob/d421e249a026f6f14653cb6f9c4edd8c5d898595/include/sysreg/dit.h#L286 +#define DIT_REGISTER s3_3_c4_c2_5 + +static uint64_t armv8_get_dit(void) { + uint64_t val = 0; + __asm__ volatile("mrs %0, s3_3_c4_c2_5" : "=r" (val)); + return (val >> 24) & 1; +} + +// See https://github.com/torvalds/linux/blob/53eaeb7fbe2702520125ae7d72742362c071a1f2/arch/arm64/include/asm/sysreg.h#L82 +// As per Arm ARM for v8-A, Section "C.5.1.3 op0 == 0b00, architectural hints, +// barriers and CLREX, and PSTATE access", ARM DDI 0487 J.a, system instructions +// for accessing PSTATE fields have the following encoding +// and C5.2.4 DIT, Data Independent Timing: +// Op0 = 0, CRn = 4 +// Op1 (3 for DIT) , Op2 (5 for DIT) encodes the PSTATE field modified and defines the constraints. +// CRm = Imm4 (#0 or #1 below) +// Rt = 0x1f +uint64_t armv8_enable_dit(void) { + if (CRYPTO_is_ARMv8_DIT_capable()) { + uint64_t original_dit = armv8_get_dit(); + // Encoding of "msr dit, #1" + __asm__ volatile(".long 0xd503415f"); + return original_dit; + } else { + return 0; + } +} + +void armv8_restore_dit(volatile uint64_t *original_dit) { + if (CRYPTO_is_ARMv8_DIT_capable() && *original_dit != 1) { + // Encoding of "msr dit, #0" + __asm__ volatile(".long 0xd503405f"); + } +} +#endif // MAKE_DIT_AVAILABLE && !OPENSSL_WINDOWS + #endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP diff --git a/crypto/fipsmodule/cpucap/cpu_aarch64_apple.c b/crypto/fipsmodule/cpucap/cpu_aarch64_apple.c index 41630fb4ac..ddf26b8427 100644 --- a/crypto/fipsmodule/cpucap/cpu_aarch64_apple.c +++ b/crypto/fipsmodule/cpucap/cpu_aarch64_apple.c @@ -99,6 +99,12 @@ void OPENSSL_cpuid_setup(void) { OPENSSL_armcap_P |= ARMV8_APPLE_M1; } +#if defined(MAKE_DIT_AVAILABLE) + if (has_hw_feature("hw.optional.arm.FEAT_DIT")) { + OPENSSL_armcap_P |= ARMV8_DIT; + } +#endif // MAKE_DIT_AVAILABLE + // OPENSSL_armcap is a 32-bit, unsigned value which may start with "0x" to // indicate a hex value. Prior to the 32-bit value, a '~' or '|' may be given. // diff --git a/crypto/fipsmodule/cpucap/cpu_aarch64_linux.c b/crypto/fipsmodule/cpucap/cpu_aarch64_linux.c index bdc1752c83..8d3f803505 100644 --- a/crypto/fipsmodule/cpucap/cpu_aarch64_linux.c +++ b/crypto/fipsmodule/cpucap/cpu_aarch64_linux.c @@ -91,6 +91,14 @@ void OPENSSL_cpuid_setup(void) { } } +#if defined(MAKE_DIT_AVAILABLE) + static const unsigned long kDIT = 1 << 24; + // Before enabling/disabling the DIT flag, check it's available in HWCAP + if (hwcap & kDIT) { + OPENSSL_armcap_P |= ARMV8_DIT; + } +#endif // MAKE_DIT_AVAILABLE + // OPENSSL_armcap is a 32-bit, unsigned value which may start with "0x" to // indicate a hex value. Prior to the 32-bit value, a '~' or '|' may be given. // diff --git a/crypto/fipsmodule/cpucap/internal.h b/crypto/fipsmodule/cpucap/internal.h index b145129b82..f9c44c3b3e 100644 --- a/crypto/fipsmodule/cpucap/internal.h +++ b/crypto/fipsmodule/cpucap/internal.h @@ -235,7 +235,9 @@ OPENSSL_INLINE int CRYPTO_is_ARMv8_wide_multiplier_capable(void) { (OPENSSL_armcap_P & ARMV8_APPLE_M1) != 0; } - +OPENSSL_INLINE int CRYPTO_is_ARMv8_DIT_capable(void) { + return (OPENSSL_armcap_P & ARMV8_DIT) != 0; +} #endif // OPENSSL_ARM || OPENSSL_AARCH64 diff --git a/crypto/fipsmodule/dh/dh.c b/crypto/fipsmodule/dh/dh.c index 5ea303e68a..e0da26c736 100644 --- a/crypto/fipsmodule/dh/dh.c +++ b/crypto/fipsmodule/dh/dh.c @@ -97,6 +97,7 @@ DH *DH_new_by_nid(int nid) { } void DH_free(DH *dh) { + SET_DIT_AUTO_DISABLE; if (dh == NULL) { return; } @@ -116,20 +117,39 @@ void DH_free(DH *dh) { OPENSSL_free(dh); } -unsigned DH_bits(const DH *dh) { return BN_num_bits(dh->p); } +unsigned DH_bits(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return BN_num_bits(dh->p); +} -const BIGNUM *DH_get0_pub_key(const DH *dh) { return dh->pub_key; } +const BIGNUM *DH_get0_pub_key(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return dh->pub_key;; +} -const BIGNUM *DH_get0_priv_key(const DH *dh) { return dh->priv_key; } +const BIGNUM *DH_get0_priv_key(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return dh->priv_key; +} -const BIGNUM *DH_get0_p(const DH *dh) { return dh->p; } +const BIGNUM *DH_get0_p(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return dh->p; +} -const BIGNUM *DH_get0_q(const DH *dh) { return dh->q; } +const BIGNUM *DH_get0_q(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return dh->q; +} -const BIGNUM *DH_get0_g(const DH *dh) { return dh->g; } +const BIGNUM *DH_get0_g(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return dh->g; +} void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, const BIGNUM **out_priv_key) { + SET_DIT_AUTO_DISABLE; if (out_pub_key != NULL) { *out_pub_key = dh->pub_key; } @@ -139,11 +159,13 @@ void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, } void DH_clear_flags(DH *dh, int flags) { + SET_DIT_AUTO_DISABLE; (void) dh; (void) flags; } int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { + SET_DIT_AUTO_DISABLE; if (pub_key != NULL) { BN_free(dh->pub_key); dh->pub_key = pub_key; @@ -159,6 +181,7 @@ int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, const BIGNUM **out_g) { + SET_DIT_AUTO_DISABLE; if (out_p != NULL) { *out_p = dh->p; } @@ -171,6 +194,7 @@ void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, } int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + SET_DIT_AUTO_DISABLE; if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL)) { return 0; @@ -198,11 +222,13 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { } int DH_set_length(DH *dh, unsigned priv_length) { + SET_DIT_AUTO_DISABLE; dh->priv_length = priv_length; return 1; } int DH_generate_key(DH *dh) { + SET_DIT_AUTO_DISABLE; boringssl_ensure_ffdh_self_test(); if (!dh_check_params_fast(dh)) { @@ -386,12 +412,14 @@ int dh_compute_key_padded_no_self_test(unsigned char *out, int DH_compute_key_padded(unsigned char *out, const BIGNUM *peers_key, DH *dh) { boringssl_ensure_ffdh_self_test(); + SET_DIT_AUTO_DISABLE; return dh_compute_key_padded_no_self_test(out, peers_key, dh); } int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { boringssl_ensure_ffdh_self_test(); + SET_DIT_AUTO_DISABLE; BN_CTX *ctx = BN_CTX_new(); if (ctx == NULL) { @@ -414,6 +442,8 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, size_t max_out_len, const BIGNUM *peers_key, const EVP_MD *digest) { + SET_DIT_AUTO_DISABLE; + *out_len = SIZE_MAX; const size_t digest_len = EVP_MD_size(digest); @@ -451,11 +481,18 @@ int DH_compute_key_hashed(DH *dh, uint8_t *out, size_t *out_len, return ret; } -int DH_size(const DH *dh) { return BN_num_bytes(dh->p); } +int DH_size(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return BN_num_bytes(dh->p); +} -unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } +unsigned DH_num_bits(const DH *dh) { + SET_DIT_AUTO_DISABLE; + return BN_num_bits(dh->p); +} int DH_up_ref(DH *dh) { + SET_DIT_AUTO_DISABLE; CRYPTO_refcount_inc(&dh->references); return 1; } diff --git a/crypto/fipsmodule/ec/ec.c b/crypto/fipsmodule/ec/ec.c index 4fc2c48bb9..4976dd8230 100644 --- a/crypto/fipsmodule/ec/ec.c +++ b/crypto/fipsmodule/ec/ec.c @@ -846,6 +846,7 @@ int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r, int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { boringssl_ensure_ecc_self_test(); + SET_DIT_AUTO_DISABLE; return ec_point_mul_no_self_test(group, r, g_scalar, p, p_scalar, ctx); } @@ -881,6 +882,7 @@ int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *p, const EC_SCALAR *scalar) { + SET_DIT_AUTO_DISABLE; if (p == NULL || scalar == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -900,6 +902,7 @@ int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r, int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r, const EC_SCALAR *scalar) { + SET_DIT_AUTO_DISABLE; if (scalar == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; diff --git a/crypto/fipsmodule/evp/digestsign.c b/crypto/fipsmodule/evp/digestsign.c index ed84201808..e2bedf0c42 100644 --- a/crypto/fipsmodule/evp/digestsign.c +++ b/crypto/fipsmodule/evp/digestsign.c @@ -157,15 +157,18 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; return do_sigver_init(ctx, pctx, type, e, pkey, evp_sign); } int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; return do_sigver_init(ctx, pctx, type, e, pkey, evp_verify); } int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + SET_DIT_AUTO_DISABLE; if (!uses_prehash(ctx, evp_sign) && !used_for_hmac(ctx)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -175,6 +178,7 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { } int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + SET_DIT_AUTO_DISABLE; if (!uses_prehash(ctx, evp_verify) || used_for_hmac(ctx)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -185,6 +189,7 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len) { + SET_DIT_AUTO_DISABLE; if (!uses_prehash(ctx, evp_sign) && !used_for_hmac(ctx)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -230,6 +235,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, } int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len) { + SET_DIT_AUTO_DISABLE; if (!uses_prehash(ctx, evp_verify) || used_for_hmac(ctx)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -261,6 +267,7 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len, // We have to avoid the underlying |EVP_DigestSignFinal| services updating // the indicator state, so we lock the state here. FIPS_service_indicator_lock_state(); + SET_DIT_AUTO_DISABLE; int ret = 0; if (uses_prehash(ctx, evp_sign) || used_for_hmac(ctx)) { @@ -296,6 +303,7 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, // We have to avoid the underlying |EVP_DigestSignFinal| services updating // the indicator state, so we lock the state here. FIPS_service_indicator_lock_state(); + SET_DIT_AUTO_DISABLE; int ret = 0; if (uses_prehash(ctx, evp_verify) && !used_for_hmac(ctx)) { @@ -322,19 +330,20 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, } void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) { - // |pctx| could be null, so we have to deal with the cleanup job here. - if (!(ctx->flags & EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { - EVP_PKEY_CTX_free(ctx->pctx); - } + SET_DIT_AUTO_DISABLE; + // |pctx| could be null, so we have to deal with the cleanup job here. + if (!(ctx->flags & EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { + EVP_PKEY_CTX_free(ctx->pctx); + } - ctx->pctx = pctx; - ctx->pctx_ops = EVP_MD_pctx_ops(); + ctx->pctx = pctx; + ctx->pctx_ops = EVP_MD_pctx_ops(); - if (pctx != NULL) { - // make sure |pctx| is not freed when destroying |EVP_MD_CTX| - ctx->flags |= EVP_MD_CTX_FLAG_KEEP_PKEY_CTX; - } else { - // if |pctx| is null, we remove the flag. - ctx->flags &= ~EVP_MD_CTX_FLAG_KEEP_PKEY_CTX; - } + if (pctx != NULL) { + // make sure |pctx| is not freed when destroying |EVP_MD_CTX| + ctx->flags |= EVP_MD_CTX_FLAG_KEEP_PKEY_CTX; + } else { + // if |pctx| is null, we remove the flag. + ctx->flags &= ~EVP_MD_CTX_FLAG_KEEP_PKEY_CTX; + } } diff --git a/crypto/fipsmodule/evp/evp.c b/crypto/fipsmodule/evp/evp.c index 4587f8a36a..386b989538 100644 --- a/crypto/fipsmodule/evp/evp.c +++ b/crypto/fipsmodule/evp/evp.c @@ -105,6 +105,7 @@ static void free_it(EVP_PKEY *pkey) { } void EVP_PKEY_free(EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey == NULL) { return; } @@ -118,11 +119,13 @@ void EVP_PKEY_free(EVP_PKEY *pkey) { } int EVP_PKEY_up_ref(EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; CRYPTO_refcount_inc(&pkey->references); return 1; } int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey->ameth && pkey->ameth->pkey_opaque) { return pkey->ameth->pkey_opaque(pkey); } @@ -130,6 +133,7 @@ int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + SET_DIT_AUTO_DISABLE; if (a->type != b->type) { return -1; } @@ -153,6 +157,7 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + SET_DIT_AUTO_DISABLE; if (to->type == EVP_PKEY_NONE) { if (!EVP_PKEY_set_type(to, from->type)) { return 0; @@ -186,6 +191,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { } int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey->ameth && pkey->ameth->param_missing) { return pkey->ameth->param_missing(pkey); } @@ -193,6 +199,7 @@ int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { } int EVP_PKEY_size(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey && pkey->ameth && pkey->ameth->pkey_size) { return pkey->ameth->pkey_size(pkey); } @@ -200,6 +207,7 @@ int EVP_PKEY_size(const EVP_PKEY *pkey) { } int EVP_PKEY_bits(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey && pkey->ameth && pkey->ameth->pkey_bits) { return pkey->ameth->pkey_bits(pkey); } @@ -207,6 +215,7 @@ int EVP_PKEY_bits(const EVP_PKEY *pkey) { } int EVP_PKEY_id(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; return pkey->type; } @@ -267,6 +276,7 @@ int EVP_PKEY_type(int nid) { EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, const uint8_t *mac_key, size_t mac_key_len) { + SET_DIT_AUTO_DISABLE; // Only |EVP_PKEY_HMAC| is supported as of now. if (type != EVP_PKEY_HMAC) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -308,6 +318,7 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, const uint8_t *mac_key, } int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { + SET_DIT_AUTO_DISABLE; if (EVP_PKEY_assign_RSA(pkey, key)) { RSA_up_ref(key); return 1; @@ -316,6 +327,7 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { } int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { + SET_DIT_AUTO_DISABLE; const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(EVP_PKEY_RSA); assert(meth != NULL); evp_pkey_set_method(pkey, meth); @@ -324,6 +336,7 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { } RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; @@ -332,6 +345,7 @@ RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { } RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; RSA *rsa = EVP_PKEY_get0_RSA(pkey); if (rsa != NULL) { RSA_up_ref(rsa); @@ -340,6 +354,7 @@ RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) { } int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { + SET_DIT_AUTO_DISABLE; if (EVP_PKEY_assign_DSA(pkey, key)) { DSA_up_ref(key); return 1; @@ -348,6 +363,7 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { } int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { + SET_DIT_AUTO_DISABLE; const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(EVP_PKEY_DSA); assert(meth != NULL); evp_pkey_set_method(pkey, meth); @@ -356,6 +372,7 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { } DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey->type != EVP_PKEY_DSA) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return NULL; @@ -364,6 +381,7 @@ DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { } DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; DSA *dsa = EVP_PKEY_get0_DSA(pkey); if (dsa != NULL) { DSA_up_ref(dsa); @@ -372,6 +390,7 @@ DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) { } int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + SET_DIT_AUTO_DISABLE; if (EVP_PKEY_assign_EC_KEY(pkey, key)) { EC_KEY_up_ref(key); return 1; @@ -380,6 +399,7 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { } int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + SET_DIT_AUTO_DISABLE; const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(EVP_PKEY_EC); assert(meth != NULL); evp_pkey_set_method(pkey, meth); @@ -388,6 +408,7 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { } EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; if (pkey->type != EVP_PKEY_EC) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); return NULL; @@ -396,6 +417,7 @@ EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { } EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (ec_key != NULL) { EC_KEY_up_ref(ec_key); @@ -403,13 +425,21 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { return ec_key; } -DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { return NULL; } -DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey) { return NULL; } +DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; + return NULL; +} + +DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; + return NULL; +} int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { // This function can only be used to assign RSA, DSA, and EC keys. Other key // types have internal representations which are not exposed through the // public API. + SET_DIT_AUTO_DISABLE; switch (type) { case EVP_PKEY_RSA: return EVP_PKEY_assign_RSA(pkey, key); @@ -427,6 +457,7 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { } int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { + SET_DIT_AUTO_DISABLE; if (pkey && pkey->pkey.ptr) { // This isn't strictly necessary, but historically |EVP_PKEY_set_type| would // clear |pkey| even if |evp_pkey_asn1_find| failed, so we preserve that @@ -450,6 +481,7 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, const uint8_t *in, size_t len) { + SET_DIT_AUTO_DISABLE; EVP_PKEY *ret = EVP_PKEY_new(); if (ret == NULL || !EVP_PKEY_set_type(ret, type)) { @@ -498,6 +530,7 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { + SET_DIT_AUTO_DISABLE; if (pkey == NULL || pkey->ameth == NULL || pkey->ameth->get_priv_raw == NULL) { @@ -510,6 +543,7 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out, int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out, size_t *out_len) { + SET_DIT_AUTO_DISABLE; if (pkey == NULL || pkey->ameth == NULL || pkey->ameth->get_pub_raw == NULL) { @@ -521,6 +555,7 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out, } int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + SET_DIT_AUTO_DISABLE; if (a->type != b->type) { return -1; } @@ -533,22 +568,29 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + SET_DIT_AUTO_DISABLE; return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md); } int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + SET_DIT_AUTO_DISABLE; return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD, 0, (void *)out_md); } void *EVP_PKEY_get0(const EVP_PKEY *pkey) { - // Node references, but never calls this function, so for now we return NULL. - // If other projects require complete support, call |EVP_PKEY_get0_RSA|, etc., - // rather than reading |pkey->pkey.ptr| directly. This avoids problems if our - // internal representation does not match the type the caller expects from - // OpenSSL. - return NULL; + SET_DIT_AUTO_DISABLE; + GUARD_PTR(pkey); + switch (pkey->type) { + case EVP_PKEY_RSA: + case EVP_PKEY_RSA_PSS: + case EVP_PKEY_DSA: + case EVP_PKEY_EC: + return pkey->pkey.ptr; + default: + return NULL; + } } void OpenSSL_add_all_algorithms(void) {} @@ -562,6 +604,7 @@ void OpenSSL_add_all_digests(void) {} void EVP_cleanup(void) {} int EVP_PKEY_base_id(const EVP_PKEY *pkey) { + SET_DIT_AUTO_DISABLE; // OpenSSL has two notions of key type because it supports multiple OIDs for // the same algorithm: NID_rsa vs NID_rsaEncryption and five distinct spelling // of DSA. We do not support these, so the base ID is simply the ID. @@ -714,7 +757,7 @@ static int evp_pkey_set1_tls_encodedpoint_x25519(EVP_PKEY *pkey, int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const uint8_t *in, size_t len) { - + SET_DIT_AUTO_DISABLE; if (NULL == pkey) { OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); goto err; @@ -828,7 +871,7 @@ static size_t evp_pkey_get1_tls_encodedpoint_x25519(const EVP_PKEY *pkey, } size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) { - + SET_DIT_AUTO_DISABLE; if (NULL == pkey) { OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); goto err; diff --git a/crypto/fipsmodule/evp/evp_ctx.c b/crypto/fipsmodule/evp/evp_ctx.c index 5ca42873c9..a6b6d17ed3 100644 --- a/crypto/fipsmodule/evp/evp_ctx.c +++ b/crypto/fipsmodule/evp/evp_ctx.c @@ -149,6 +149,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { } EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { + SET_DIT_AUTO_DISABLE; return evp_pkey_ctx_new(pkey, e, -1); } @@ -157,6 +158,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { } void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (ctx == NULL) { return; } @@ -169,6 +171,7 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { } EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx->pmeth || !ctx->pmeth->copy) { return NULL; } @@ -202,10 +205,14 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { return ret; } -EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; + return ctx->pkey; +} int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); return 0; @@ -229,6 +236,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, } int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (ctx == NULL || ctx->pmeth == NULL || (ctx->pmeth->sign == NULL && ctx->pmeth->sign_message == NULL)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -245,6 +253,7 @@ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, const uint8_t *digest, size_t digest_len) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -257,6 +266,7 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, } int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (ctx == NULL || ctx->pmeth == NULL || (ctx->pmeth->verify == NULL && ctx->pmeth->verify_message == NULL)) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -272,6 +282,7 @@ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, const uint8_t *digest, size_t digest_len) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -294,6 +305,7 @@ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -306,6 +318,7 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -316,6 +329,7 @@ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -328,6 +342,7 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -338,6 +353,7 @@ int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, const uint8_t *sig, size_t sig_len) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -350,6 +366,7 @@ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, } int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -359,6 +376,7 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { } int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { + SET_DIT_AUTO_DISABLE; int ret; if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) || @@ -419,6 +437,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { } int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -431,6 +450,7 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { } int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -480,6 +500,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { // We have to avoid potential underlying services updating the indicator state, // so we lock the state here. FIPS_service_indicator_lock_state(); + SET_DIT_AUTO_DISABLE; int ret = 0; if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); @@ -518,6 +539,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { } int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -527,6 +549,7 @@ int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { } int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { + SET_DIT_AUTO_DISABLE; if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -576,6 +599,7 @@ int EVP_PKEY_encapsulate_deterministic(EVP_PKEY_CTX *ctx, int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, uint8_t *ciphertext, size_t *ciphertext_len, uint8_t *shared_secret, size_t *shared_secret_len) { + SET_DIT_AUTO_DISABLE; if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->encapsulate == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; @@ -588,6 +612,7 @@ int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, uint8_t *shared_secret, size_t *shared_secret_len, const uint8_t *ciphertext, size_t ciphertext_len) { + SET_DIT_AUTO_DISABLE; if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->decapsulate == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; diff --git a/crypto/fipsmodule/evp/p_hkdf.c b/crypto/fipsmodule/evp/p_hkdf.c index fe83d05d1c..2fbc31fa3c 100644 --- a/crypto/fipsmodule/evp/p_hkdf.c +++ b/crypto/fipsmodule/evp/p_hkdf.c @@ -211,6 +211,7 @@ int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const uint8_t *key, size_t key_len) { + SET_DIT_AUTO_DISABLE; CBS cbs; CBS_init(&cbs, key, key_len); return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_HKDF, EVP_PKEY_OP_DERIVE, diff --git a/crypto/fipsmodule/hkdf/hkdf.c b/crypto/fipsmodule/hkdf/hkdf.c index f2af32274c..bccdaf1527 100644 --- a/crypto/fipsmodule/hkdf/hkdf.c +++ b/crypto/fipsmodule/hkdf/hkdf.c @@ -22,6 +22,7 @@ #include "../../internal.h" #include "../service_indicator/internal.h" +#include "../cpucap/internal.h" // TODO(CryptoAlg-1281): We need to get our FIPS testing partner's opinion on // which API level(s) we need to check at. HKDF_extract() originally had checks @@ -63,7 +64,7 @@ int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, // We have to avoid the underlying HMAC services updating the indicator // state, so we lock the state here. FIPS_service_indicator_lock_state(); - + SET_DIT_AUTO_DISABLE; // If salt is not given, HashLength zeros are used. However, HMAC does that // internally already so we can ignore it. unsigned len; @@ -103,7 +104,7 @@ int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, // We have to avoid the underlying HMAC services updating the indicator // state, so we lock the state here. FIPS_service_indicator_lock_state(); - + SET_DIT_AUTO_DISABLE; if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) { goto out; } diff --git a/crypto/fipsmodule/hmac/hmac.c b/crypto/fipsmodule/hmac/hmac.c index 4b9ca9ac99..211ae04d3c 100644 --- a/crypto/fipsmodule/hmac/hmac.c +++ b/crypto/fipsmodule/hmac/hmac.c @@ -122,9 +122,14 @@ struct hmac_methods_st { HASH_NAME##_has_blocksize_not_divisible_by_eight_t) \ OPENSSL_STATIC_ASSERT(HASH_CBLOCK <= EVP_MAX_MD_BLOCK_SIZE, \ HASH_NAME##_has_overlarge_blocksize_t) \ - OPENSSL_STATIC_ASSERT( \ - sizeof(HASH_CTX) <= sizeof(union md_ctx_union), \ - HASH_NAME##_has_overlarge_context_t) + OPENSSL_STATIC_ASSERT(HMAC_##HASH_NAME##_PRECOMPUTED_KEY_SIZE == \ + 2 * HASH_NAME##_CHAINING_LENGTH, \ + HASH_NAME##_has_incorrect_precomputed_key_size) \ + OPENSSL_STATIC_ASSERT(HMAC_##HASH_NAME##_PRECOMPUTED_KEY_SIZE <= \ + HMAC_MAX_PRECOMPUTED_KEY_SIZE, \ + HASH_NAME##_has_too_large_precomputed_key_size) \ + OPENSSL_STATIC_ASSERT(sizeof(HASH_CTX) <= sizeof(union md_ctx_union), \ + HASH_NAME##_has_overlarge_context_t) // The maximum number of HMAC implementations #define HMAC_METHOD_MAX 8 diff --git a/crypto/fipsmodule/modes/asm/ghash-x86_64.pl b/crypto/fipsmodule/modes/asm/ghash-x86_64.pl index be7ac4f8c0..46cf131c41 100644 --- a/crypto/fipsmodule/modes/asm/ghash-x86_64.pl +++ b/crypto/fipsmodule/modes/asm/ghash-x86_64.pl @@ -124,7 +124,6 @@ $code=<<___; .text -.extern OPENSSL_ia32cap_P ___ @@ -391,15 +390,9 @@ sub reduction_alg9 { # 17/11 times faster than Intel version my ($Xl,$Xm,$Xh,$Hkey3,$Hkey4)=map("%xmm$_",(11..15)); $code.=<<___; - leaq OPENSSL_ia32cap_P(%rip),%rax - mov 4(%rax),%eax cmp \$0x30,$len jb .Lskip4x - and \$`1<<26|1<<22`,%eax # isolate MOVBE+XSAVE - cmp \$`1<<22`,%eax # check for MOVBE without XSAVE - je .Lskip4x - sub \$0x30,$len mov \$0xA040608020C0E000,%rax # ((7..0)·0xE0)&0xff movdqu 0x30($Htbl),$Hkey3 diff --git a/crypto/fipsmodule/rand/ctrdrbg.c b/crypto/fipsmodule/rand/ctrdrbg.c index 217176a7fb..3b523376c2 100644 --- a/crypto/fipsmodule/rand/ctrdrbg.c +++ b/crypto/fipsmodule/rand/ctrdrbg.c @@ -30,6 +30,7 @@ static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, size_t personalization_len) { + SET_DIT_AUTO_DISABLE; CTR_DRBG_STATE *drbg = OPENSSL_malloc(sizeof(CTR_DRBG_STATE)); if (drbg == NULL || !CTR_DRBG_init(drbg, entropy, personalization, personalization_len)) { @@ -40,11 +41,15 @@ CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], return drbg; } -void CTR_DRBG_free(CTR_DRBG_STATE *state) { OPENSSL_free(state); } +void CTR_DRBG_free(CTR_DRBG_STATE *state) { + SET_DIT_AUTO_DISABLE; + OPENSSL_free(state); +} int CTR_DRBG_init(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, size_t personalization_len) { + SET_DIT_AUTO_DISABLE; // Section 10.2.1.3.1 if (personalization_len > CTR_DRBG_ENTROPY_LEN) { return 0; @@ -118,6 +123,7 @@ int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *additional_data, size_t additional_data_len) { + SET_DIT_AUTO_DISABLE; // Section 10.2.1.4 uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; @@ -146,6 +152,7 @@ int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, const uint8_t *additional_data, size_t additional_data_len) { + SET_DIT_AUTO_DISABLE; // See 9.3.1 if (out_len > CTR_DRBG_MAX_GENERATE_LENGTH) { return 0; diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c index c34b0b2ff5..5cea886b57 100644 --- a/crypto/fipsmodule/rsa/rsa.c +++ b/crypto/fipsmodule/rsa/rsa.c @@ -111,6 +111,7 @@ RSA *RSA_new_public_key(const BIGNUM *n, const BIGNUM *e) { RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, const BIGNUM *iqmp) { + SET_DIT_AUTO_DISABLE; RSA *rsa = RSA_new(); if (rsa == NULL || // !bn_dup_into(&rsa->n, n) || // @@ -131,6 +132,7 @@ RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d) { + SET_DIT_AUTO_DISABLE; RSA *rsa = RSA_new(); if (rsa == NULL || // !bn_dup_into(&rsa->n, n) || // @@ -145,6 +147,7 @@ RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e, } RSA *RSA_new_private_key_no_e(const BIGNUM *n, const BIGNUM *d) { + SET_DIT_AUTO_DISABLE; RSA *rsa = RSA_new(); if (rsa == NULL) { return NULL; @@ -182,6 +185,7 @@ RSA *RSA_new_private_key_large_e(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, const BIGNUM *iqmp) { + SET_DIT_AUTO_DISABLE; RSA *rsa = RSA_new(); if (rsa == NULL) { return NULL; @@ -249,10 +253,12 @@ RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n) { } void RSA_free(RSA *rsa) { + SET_DIT_AUTO_DISABLE; if (rsa == NULL) { return; } + if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) { return; } @@ -279,30 +285,59 @@ void RSA_free(RSA *rsa) { } int RSA_up_ref(RSA *rsa) { + SET_DIT_AUTO_DISABLE; CRYPTO_refcount_inc(&rsa->references); return 1; } -unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); } +unsigned RSA_bits(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return BN_num_bits(rsa->n); +} -const BIGNUM *RSA_get0_n(const RSA *rsa) { return rsa->n; } +const BIGNUM *RSA_get0_n(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->n; +} -const BIGNUM *RSA_get0_e(const RSA *rsa) { return rsa->e; } +const BIGNUM *RSA_get0_e(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->e; +} -const BIGNUM *RSA_get0_d(const RSA *rsa) { return rsa->d; } +const BIGNUM *RSA_get0_d(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->d; +} -const BIGNUM *RSA_get0_p(const RSA *rsa) { return rsa->p; } +const BIGNUM *RSA_get0_p(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->p; +} -const BIGNUM *RSA_get0_q(const RSA *rsa) { return rsa->q; } +const BIGNUM *RSA_get0_q(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->q; +} -const BIGNUM *RSA_get0_dmp1(const RSA *rsa) { return rsa->dmp1; } +const BIGNUM *RSA_get0_dmp1(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->dmp1; +} -const BIGNUM *RSA_get0_dmq1(const RSA *rsa) { return rsa->dmq1; } +const BIGNUM *RSA_get0_dmq1(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->dmq1; +} -const BIGNUM *RSA_get0_iqmp(const RSA *rsa) { return rsa->iqmp; } +const BIGNUM *RSA_get0_iqmp(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->iqmp; +} void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, const BIGNUM **out_d) { + SET_DIT_AUTO_DISABLE; if (out_n != NULL) { *out_n = rsa->n; } @@ -316,6 +351,7 @@ void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, const BIGNUM **out_q) { + SET_DIT_AUTO_DISABLE; if (out_p != NULL) { *out_p = rsa->p; } @@ -327,11 +363,13 @@ void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { // We do not support the id-RSASSA-PSS key encoding. If we add support later, // the |maskHash| field should be filled in for OpenSSL compatibility. + SET_DIT_AUTO_DISABLE; return NULL; } void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { + SET_DIT_AUTO_DISABLE; if (out_dmp1 != NULL) { *out_dmp1 = rsa->dmp1; } @@ -344,6 +382,7 @@ void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, } int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + SET_DIT_AUTO_DISABLE; if ((rsa->n == NULL && n == NULL) || (rsa->e == NULL && e == NULL && rsa->d == NULL && d == NULL)) { return 0; @@ -367,11 +406,13 @@ int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { } int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { + SET_DIT_AUTO_DISABLE; if ((rsa->p == NULL && p == NULL) || (rsa->q == NULL && q == NULL)) { return 0; } + if (p != NULL) { BN_free(rsa->p); rsa->p = p; @@ -386,6 +427,7 @@ int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { } int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { + SET_DIT_AUTO_DISABLE; if ((rsa->dmp1 == NULL && dmp1 == NULL) || (rsa->dmq1 == NULL && dmq1 == NULL) || (rsa->iqmp == NULL && iqmp == NULL)) { @@ -412,6 +454,7 @@ int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { + SET_DIT_AUTO_DISABLE; if (rsa->meth->sign_raw) { return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); } @@ -422,11 +465,14 @@ static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out, int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { boringssl_ensure_rsa_self_test(); + SET_DIT_AUTO_DISABLE; + return rsa_sign_raw_no_self_test(rsa, out_len, out, max_out, in, in_len, padding); } unsigned RSA_size(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; size_t ret = rsa->meth->size ? rsa->meth->size(rsa) : rsa_default_size(rsa); // RSA modulus sizes are bounded by |BIGNUM|, which must fit in |unsigned|. // @@ -436,11 +482,13 @@ unsigned RSA_size(const RSA *rsa) { } int RSA_is_opaque(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); } int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + SET_DIT_AUTO_DISABLE; int index; if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl, argp, free_func)) { @@ -450,10 +498,12 @@ int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, } int RSA_set_ex_data(RSA *rsa, int idx, void *arg) { + SET_DIT_AUTO_DISABLE; return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg); } void *RSA_get_ex_data(const RSA *rsa, int idx) { + SET_DIT_AUTO_DISABLE; return CRYPTO_get_ex_data(&rsa->ex_data, idx); } @@ -662,6 +712,7 @@ int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest, int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa) { boringssl_ensure_rsa_self_test(); + SET_DIT_AUTO_DISABLE; return rsa_sign_no_self_test(hash_nid, digest, digest_len, out, out_len, rsa); } @@ -669,6 +720,7 @@ int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *digest, size_t digest_len, const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len) { + SET_DIT_AUTO_DISABLE; if (digest_len != EVP_MD_size(md)) { OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; @@ -680,6 +732,7 @@ int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, return 0; } + int ret = RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, digest, md, mgf1_md, salt_len) && RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len, @@ -691,6 +744,7 @@ int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, int rsa_digestsign_no_self_test(const EVP_MD *md, const uint8_t *input, size_t in_len, uint8_t *out, unsigned *out_len, RSA *rsa) { + SET_DIT_AUTO_DISABLE; uint8_t digest[EVP_MAX_MD_SIZE]; unsigned int digest_len = EVP_MAX_MD_SIZE; if (!EVP_Digest(input, in_len, digest, &digest_len, md, NULL)) { @@ -772,6 +826,7 @@ int rsa_digestverify_no_self_test(const EVP_MD *md, const uint8_t *input, int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, const uint8_t *sig, size_t sig_len, RSA *rsa) { boringssl_ensure_rsa_self_test(); + SET_DIT_AUTO_DISABLE; return rsa_verify_no_self_test(hash_nid, digest, digest_len, sig, sig_len, rsa); } @@ -779,6 +834,7 @@ int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len, int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len, const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len, const uint8_t *sig, size_t sig_len) { + SET_DIT_AUTO_DISABLE; if (digest_len != EVP_MD_size(md)) { OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; @@ -819,24 +875,34 @@ int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out, int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) { boringssl_ensure_rsa_self_test(); + SET_DIT_AUTO_DISABLE; return rsa_private_transform_no_self_test(rsa, out, in, len); } -int RSA_flags(const RSA *rsa) { return rsa->flags; } +int RSA_flags(const RSA *rsa) { + SET_DIT_AUTO_DISABLE; + return rsa->flags; +} -int RSA_test_flags(const RSA *rsa, int flags) { return rsa->flags & flags; } +int RSA_test_flags(const RSA *rsa, int flags) { + SET_DIT_AUTO_DISABLE; + return rsa->flags & flags; +} int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { + SET_DIT_AUTO_DISABLE; return (rsa != NULL && ((rsa->flags & RSA_FLAG_NO_BLINDING) == 0)) ? 1 : 0; } void RSA_blinding_off_temp_for_accp_compatibility(RSA *rsa) { + SET_DIT_AUTO_DISABLE; if (rsa != NULL) { rsa->flags |= RSA_FLAG_NO_BLINDING; } } int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) { + SET_DIT_AUTO_DISABLE; if (ctx != NULL && ctx->pmeth != NULL) { if (ctx->pmeth->pkey_id == EVP_PKEY_RSA || ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) { @@ -861,6 +927,7 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) // or <= n when RSA_FLAG_LARGE_PUBLIC_EXPONENT is set. // int is_public_component_of_rsa_key_good(const RSA *key) { + SET_DIT_AUTO_DISABLE; if (key->n == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; @@ -942,6 +1009,7 @@ enum rsa_key_type_for_checking { static enum rsa_key_type_for_checking determine_key_type_for_checking(const RSA *key) { // The key must have the modulus n. + SET_DIT_AUTO_DISABLE; if (key->n == NULL) { return RSA_KEY_TYPE_FOR_CHECKING_INVALID; } @@ -983,7 +1051,7 @@ static enum rsa_key_type_for_checking determine_key_type_for_checking(const RSA // consisting of public and private component, but it can also be only the // public component. The public component is // (n, e), -// the modulus n and the public exponent e. A private key contains at minimum +// the modulus n and the public exponent e. A private key contains at minimum // the private exponent e in addition to the public part: // (n, e, d), // while normally a private key would consist of @@ -994,7 +1062,7 @@ static enum rsa_key_type_for_checking determine_key_type_for_checking(const RSA // Additionally, we support checking stripped private keys that JCA supports // that consist of (n, d). // -// The function performs the following checks (when possible): +// The function performs the following checks (when possible): // - n fits in 16k bits, // - 1 < log(e, 2) <= 33, // - n and e are odd, @@ -1009,7 +1077,7 @@ static enum rsa_key_type_for_checking determine_key_type_for_checking(const RSA // Note: see the rsa_key_type_for_checking enum for details on types of keys // the function can work with. int RSA_check_key(const RSA *key) { - + SET_DIT_AUTO_DISABLE; enum rsa_key_type_for_checking key_type = determine_key_type_for_checking(key); if (key_type == RSA_KEY_TYPE_FOR_CHECKING_INVALID) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); @@ -1237,6 +1305,7 @@ DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { // that the AWS-LC FIPS module offers only RSA signing and verification as // approved FIPS services. int RSA_check_fips(RSA *key) { + SET_DIT_AUTO_DISABLE; enum rsa_key_type_for_checking key_type = determine_key_type_for_checking(key); // In addition to invalid key type, stripped private keys can not be checked @@ -1320,4 +1389,3 @@ int RSA_check_fips(RSA *key) { return ret; } - diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index 4106968172..b97d08b53a 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -1164,6 +1164,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, const BIGNUM *e_value, BN_GENCB *cb, int check_fips) { boringssl_ensure_rsa_self_test(); + SET_DIT_AUTO_DISABLE; RSA *tmp = NULL; uint32_t err; diff --git a/crypto/fipsmodule/sshkdf/sshkdf.c b/crypto/fipsmodule/sshkdf/sshkdf.c index b95cd9c6b5..a8b758ce41 100644 --- a/crypto/fipsmodule/sshkdf/sshkdf.c +++ b/crypto/fipsmodule/sshkdf/sshkdf.c @@ -21,6 +21,7 @@ int SSHKDF(const EVP_MD *evp_md, char type, uint8_t *out, size_t out_len) { + SET_DIT_AUTO_DISABLE; EVP_MD_CTX *md = NULL; uint8_t digest[EVP_MAX_MD_SIZE]; unsigned int digest_size = 0; diff --git a/crypto/fipsmodule/tls/kdf.c b/crypto/fipsmodule/tls/kdf.c index ec1f39f7cf..ab84d368bb 100644 --- a/crypto/fipsmodule/tls/kdf.c +++ b/crypto/fipsmodule/tls/kdf.c @@ -59,7 +59,6 @@ #include "../../internal.h" - // tls1_P_hash computes the TLS P_ function as described in RFC 5246, // section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and // |secret| as the secret. |label|, |seed1|, and |seed2| are concatenated to @@ -144,6 +143,7 @@ int CRYPTO_tls1_prf(const EVP_MD *digest, // We have to avoid the underlying HMAC services updating the indicator state, // so we lock the state here. FIPS_service_indicator_lock_state(); + SET_DIT_AUTO_DISABLE; int ret = 0; const EVP_MD *original_digest = digest; if (out_len == 0) { diff --git a/crypto/hmac_extra/hmac_test.cc b/crypto/hmac_extra/hmac_test.cc index 7e29ceb6f8..074710bf03 100644 --- a/crypto/hmac_extra/hmac_test.cc +++ b/crypto/hmac_extra/hmac_test.cc @@ -91,6 +91,27 @@ static const EVP_MD *GetDigest(const std::string &name) { return nullptr; } +static size_t GetPrecomputedKeySize(const std::string &name) { + if (name == "MD5") { + return HMAC_MD5_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA1") { + return HMAC_SHA1_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA224") { + return HMAC_SHA224_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA256") { + return HMAC_SHA256_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA384") { + return HMAC_SHA384_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA512") { + return HMAC_SHA512_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA512/224") { + return HMAC_SHA512_224_PRECOMPUTED_KEY_SIZE; + } else if (name == "SHA512/256") { + return HMAC_SHA512_256_PRECOMPUTED_KEY_SIZE; + } + return 0; +} + static void RunHMACTestEVP(const std::vector &key, const std::vector &msg, const std::vector &tag, const EVP_MD *md) { @@ -252,10 +273,12 @@ TEST(HMACTest, TestVectors) { // Get the precomputed key length for later use // And test the precomputed key size is at most HMAC_MAX_PRECOMPUTED_KEY_SIZE + // and is equal to HMAC_xxx_PRECOMPUTED_KEY_SIZE, where xxx is the digest name ASSERT_TRUE(HMAC_set_precomputed_key_export(ctx.get())); size_t precomputed_key_len; HMAC_get_precomputed_key(ctx.get(), nullptr, &precomputed_key_len); ASSERT_LE(precomputed_key_len, (size_t) HMAC_MAX_PRECOMPUTED_KEY_SIZE); + ASSERT_EQ(GetPrecomputedKeySize(digest_str), precomputed_key_len); // Test that at this point, the context cannot be used with HMAC_Update ASSERT_FALSE(HMAC_Update(ctx.get(), input.data(), input.size())); diff --git a/crypto/internal.h b/crypto/internal.h index 1546549714..6bbe306cea 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -1345,11 +1345,9 @@ OPENSSL_EXPORT int OPENSSL_vasprintf_internal(char **str, const char *format, OPENSSL_PRINTF_FORMAT_FUNC(2, 0); -// Experimental Safety Macros +// Experimental safety macros inspired by s2n-tls. -// Inspired by s2n-tls - -// __AWS_LC_ENSURE checks if |cond| is true nothing happens, else |action| is called +// If |cond| is false |action| is invoked, otherwise nothing happens. #define __AWS_LC_ENSURE(cond, action) \ do { \ if (!(cond)) { \ @@ -1360,8 +1358,9 @@ OPENSSL_EXPORT int OPENSSL_vasprintf_internal(char **str, const char *format, #define AWS_LC_ERROR 0 #define AWS_LC_SUCCESS 1 -// RESULT_GUARD_PTR checks |ptr|: if it is null it adds ERR_R_PASSED_NULL_PARAMETER -// to the error queue and returns 0, if it is not null nothing happens. +// GUARD_PTR checks |ptr|: if it is NULL it adds |ERR_R_PASSED_NULL_PARAMETER| +// to the error queue and returns 0, if it is not NULL nothing happens. +// // NOTE: this macro should only be used with functions that return 0 (for error) // and 1 (for success). #define GUARD_PTR(ptr) __AWS_LC_ENSURE((ptr) != NULL, OPENSSL_PUT_ERROR(CRYPTO, ERR_R_PASSED_NULL_PARAMETER); \ diff --git a/crypto/kyber/pqcrystals_kyber_ref_common/verify.c b/crypto/kyber/pqcrystals_kyber_ref_common/verify.c index ed4a6541f8..b7a692de8e 100644 --- a/crypto/kyber/pqcrystals_kyber_ref_common/verify.c +++ b/crypto/kyber/pqcrystals_kyber_ref_common/verify.c @@ -39,9 +39,6 @@ int verify(const uint8_t *a, const uint8_t *b, size_t len) **************************************************/ void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { - size_t i; - - b = -b; - for(i=0;i #include "verify.h" +#include "../../internal.h" + /************************************************* * Name: verify * @@ -39,9 +41,6 @@ int verify(const uint8_t *a, const uint8_t *b, size_t len) **************************************************/ void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { - size_t i; - - b = -b; - for(i=0;itbsRequest->requestExtensions, val, len); } +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) { + if (resp == NULL) { + OPENSSL_PUT_ERROR(OCSP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (val != NULL && len <= 0) { + OPENSSL_PUT_ERROR(OCSP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return ocsp_add_nonce(&resp->tbsResponseData->responseExtensions, val, len); +} + int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) { if (req == NULL || bs == NULL) { OPENSSL_PUT_ERROR(OCSP, ERR_R_PASSED_NULL_PARAMETER); diff --git a/crypto/ocsp/ocsp_test.cc b/crypto/ocsp/ocsp_test.cc index 7459054254..859f9a5794 100644 --- a/crypto/ocsp/ocsp_test.cc +++ b/crypto/ocsp/ocsp_test.cc @@ -1432,6 +1432,32 @@ TEST(OCSPTest, OCSPNonce) { EXPECT_GE(OCSP_REQUEST_get_ext_by_NID(ocspRequest.get(), NID_id_pkix_OCSP_Nonce, -1), 0); + + // Same tests as above, but against an |OCSP_BASICRESP|. + data = GetTestData( + std::string("crypto/ocsp/test/aws/ocsp_response_no_nonce.der").c_str()); + std::vector ocsp_response_data(data.begin(), data.end()); + bssl::UniquePtr ocspResponse = + LoadOCSP_RESPONSE(ocsp_response_data); + ASSERT_TRUE(ocspResponse); + bssl::UniquePtr basicResponse( + OCSP_response_get1_basic(ocspResponse.get())); + ASSERT_TRUE(basicResponse); + + EXPECT_FALSE( + OCSP_basic_add1_nonce(basicResponse.get(), ocsp_response_nonce, 0)); + + // Adding a random nonce with the default length should succeed. + // |OCSP_BASICRESP_get_ext_by_NID| returns a negative number if a nonce does + // not exist. + // Add a random nonce with a specified length this time around. + EXPECT_LT(OCSP_BASICRESP_get_ext_by_NID(basicResponse.get(), + NID_id_pkix_OCSP_Nonce, -1), + 0); + EXPECT_TRUE(OCSP_basic_add1_nonce(basicResponse.get(), nullptr, 10)); + EXPECT_GE(OCSP_BASICRESP_get_ext_by_NID(basicResponse.get(), + NID_id_pkix_OCSP_Nonce, -1), + 0); } TEST(OCSPTest, OCSPCRLString) { diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h index 471862b81d..94c8736f41 100644 --- a/crypto/test/test_util.h +++ b/crypto/test/test_util.h @@ -76,11 +76,11 @@ bssl::UniquePtr CertFromPEM(const char *pem); // unique_ptr will automatically call fclose on the file descriptior when the // variable goes out of scope, so we need to specify BIO_NOCLOSE close flags // to avoid a double-free condition. -struct FileCloser { +struct TempFileCloser { void operator()(FILE *f) const { fclose(f); } }; -using TempFILE = std::unique_ptr; +using TempFILE = std::unique_ptr; #if defined(OPENSSL_WINDOWS) #include diff --git a/generated-src/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S b/generated-src/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S index b6ae7fc080..cb186b7f08 100644 --- a/generated-src/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S +++ b/generated-src/linux-x86_64/crypto/fipsmodule/aesni-x86_64.S @@ -972,10 +972,7 @@ _CET_ENDBR leaq 7(%r8),%r9 movl %r10d,96+12(%rsp) bswapl %r9d - leaq OPENSSL_ia32cap_P(%rip),%r10 - movl 4(%r10),%r10d xorl %ebp,%r9d - andl $71303168,%r10d movl %r9d,112+12(%rsp) movups 16(%rcx),%xmm1 @@ -986,104 +983,10 @@ _CET_ENDBR cmpq $8,%rdx jb .Lctr32_tail - subq $6,%rdx - cmpl $4194304,%r10d - je .Lctr32_6x - leaq 128(%rcx),%rcx - subq $2,%rdx + subq $8,%rdx jmp .Lctr32_loop8 -.align 16 -.Lctr32_6x: - shll $4,%eax - movl $48,%r10d - bswapl %ebp - leaq 32(%rcx,%rax,1),%rcx - subq %rax,%r10 - jmp .Lctr32_loop6 - -.align 16 -.Lctr32_loop6: - addl $6,%r8d - movups -48(%rcx,%r10,1),%xmm0 -.byte 102,15,56,220,209 - movl %r8d,%eax - xorl %ebp,%eax -.byte 102,15,56,220,217 -.byte 0x0f,0x38,0xf1,0x44,0x24,12 - leal 1(%r8),%eax -.byte 102,15,56,220,225 - xorl %ebp,%eax -.byte 0x0f,0x38,0xf1,0x44,0x24,28 -.byte 102,15,56,220,233 - leal 2(%r8),%eax - xorl %ebp,%eax -.byte 102,15,56,220,241 -.byte 0x0f,0x38,0xf1,0x44,0x24,44 - leal 3(%r8),%eax -.byte 102,15,56,220,249 - movups -32(%rcx,%r10,1),%xmm1 - xorl %ebp,%eax - -.byte 102,15,56,220,208 -.byte 0x0f,0x38,0xf1,0x44,0x24,60 - leal 4(%r8),%eax -.byte 102,15,56,220,216 - xorl %ebp,%eax -.byte 0x0f,0x38,0xf1,0x44,0x24,76 -.byte 102,15,56,220,224 - leal 5(%r8),%eax - xorl %ebp,%eax -.byte 102,15,56,220,232 -.byte 0x0f,0x38,0xf1,0x44,0x24,92 - movq %r10,%rax -.byte 102,15,56,220,240 -.byte 102,15,56,220,248 - movups -16(%rcx,%r10,1),%xmm0 - - call .Lenc_loop6 - - movdqu (%rdi),%xmm8 - movdqu 16(%rdi),%xmm9 - movdqu 32(%rdi),%xmm10 - movdqu 48(%rdi),%xmm11 - movdqu 64(%rdi),%xmm12 - movdqu 80(%rdi),%xmm13 - leaq 96(%rdi),%rdi - movups -64(%rcx,%r10,1),%xmm1 - pxor %xmm2,%xmm8 - movaps 0(%rsp),%xmm2 - pxor %xmm3,%xmm9 - movaps 16(%rsp),%xmm3 - pxor %xmm4,%xmm10 - movaps 32(%rsp),%xmm4 - pxor %xmm5,%xmm11 - movaps 48(%rsp),%xmm5 - pxor %xmm6,%xmm12 - movaps 64(%rsp),%xmm6 - pxor %xmm7,%xmm13 - movaps 80(%rsp),%xmm7 - movdqu %xmm8,(%rsi) - movdqu %xmm9,16(%rsi) - movdqu %xmm10,32(%rsi) - movdqu %xmm11,48(%rsi) - movdqu %xmm12,64(%rsi) - movdqu %xmm13,80(%rsi) - leaq 96(%rsi),%rsi - - subq $6,%rdx - jnc .Lctr32_loop6 - - addq $6,%rdx - jz .Lctr32_done - - leal -48(%r10),%eax - leaq -80(%rcx,%r10,1),%rcx - negl %eax - shrl $4,%eax - jmp .Lctr32_tail - .align 32 .Lctr32_loop8: addl $8,%r8d @@ -2566,16 +2469,10 @@ _CET_ENDBR movdqa %xmm5,%xmm14 movdqu 80(%rdi),%xmm7 movdqa %xmm6,%xmm15 - leaq OPENSSL_ia32cap_P(%rip),%r9 - movl 4(%r9),%r9d cmpq $0x70,%rdx jbe .Lcbc_dec_six_or_seven - andl $71303168,%r9d - subq $0x50,%rdx - cmpl $4194304,%r9d - je .Lcbc_dec_loop6_enter - subq $0x20,%rdx + subq $0x70,%rdx leaq 112(%rcx),%rcx jmp .Lcbc_dec_loop8_enter .align 16 @@ -2846,51 +2743,6 @@ _CET_ENDBR pxor %xmm9,%xmm9 jmp .Lcbc_dec_tail_collected -.align 16 -.Lcbc_dec_loop6: - movups %xmm7,(%rsi) - leaq 16(%rsi),%rsi - movdqu 0(%rdi),%xmm2 - movdqu 16(%rdi),%xmm3 - movdqa %xmm2,%xmm11 - movdqu 32(%rdi),%xmm4 - movdqa %xmm3,%xmm12 - movdqu 48(%rdi),%xmm5 - movdqa %xmm4,%xmm13 - movdqu 64(%rdi),%xmm6 - movdqa %xmm5,%xmm14 - movdqu 80(%rdi),%xmm7 - movdqa %xmm6,%xmm15 -.Lcbc_dec_loop6_enter: - leaq 96(%rdi),%rdi - movdqa %xmm7,%xmm8 - - call _aesni_decrypt6 - - pxor %xmm10,%xmm2 - movdqa %xmm8,%xmm10 - pxor %xmm11,%xmm3 - movdqu %xmm2,(%rsi) - pxor %xmm12,%xmm4 - movdqu %xmm3,16(%rsi) - pxor %xmm13,%xmm5 - movdqu %xmm4,32(%rsi) - pxor %xmm14,%xmm6 - movq %rbp,%rcx - movdqu %xmm5,48(%rsi) - pxor %xmm15,%xmm7 - movl %r10d,%eax - movdqu %xmm6,64(%rsi) - leaq 80(%rsi),%rsi - subq $0x60,%rdx - ja .Lcbc_dec_loop6 - - movdqa %xmm7,%xmm2 - addq $0x50,%rdx - jle .Lcbc_dec_clear_tail_collected - movups %xmm7,(%rsi) - leaq 16(%rsi),%rsi - .Lcbc_dec_tail: movups (%rdi),%xmm2 subq $0x10,%rdx diff --git a/generated-src/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S b/generated-src/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S index 5921f1f3c4..8961d4502c 100644 --- a/generated-src/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S +++ b/generated-src/linux-x86_64/crypto/fipsmodule/ghash-x86_64.S @@ -5,8 +5,6 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__ELF__) .text -.extern OPENSSL_ia32cap_P -.hidden OPENSSL_ia32cap_P .globl gcm_init_clmul .hidden gcm_init_clmul .type gcm_init_clmul,@function @@ -244,15 +242,9 @@ _CET_ENDBR jz .Lodd_tail movdqu 16(%rsi),%xmm6 - leaq OPENSSL_ia32cap_P(%rip),%rax - movl 4(%rax),%eax cmpq $0x30,%rcx jb .Lskip4x - andl $71303168,%eax - cmpl $4194304,%eax - je .Lskip4x - subq $0x30,%rcx movq $0xA040608020C0E000,%rax movdqu 48(%rsi),%xmm14 diff --git a/generated-src/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S b/generated-src/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S index 418c0550a6..cf247d9fad 100644 --- a/generated-src/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S +++ b/generated-src/mac-x86_64/crypto/fipsmodule/aesni-x86_64.S @@ -970,10 +970,7 @@ L$ctr32_bulk: leaq 7(%r8),%r9 movl %r10d,96+12(%rsp) bswapl %r9d - leaq _OPENSSL_ia32cap_P(%rip),%r10 - movl 4(%r10),%r10d xorl %ebp,%r9d - andl $71303168,%r10d movl %r9d,112+12(%rsp) movups 16(%rcx),%xmm1 @@ -984,104 +981,10 @@ L$ctr32_bulk: cmpq $8,%rdx jb L$ctr32_tail - subq $6,%rdx - cmpl $4194304,%r10d - je L$ctr32_6x - leaq 128(%rcx),%rcx - subq $2,%rdx + subq $8,%rdx jmp L$ctr32_loop8 -.p2align 4 -L$ctr32_6x: - shll $4,%eax - movl $48,%r10d - bswapl %ebp - leaq 32(%rcx,%rax,1),%rcx - subq %rax,%r10 - jmp L$ctr32_loop6 - -.p2align 4 -L$ctr32_loop6: - addl $6,%r8d - movups -48(%rcx,%r10,1),%xmm0 -.byte 102,15,56,220,209 - movl %r8d,%eax - xorl %ebp,%eax -.byte 102,15,56,220,217 -.byte 0x0f,0x38,0xf1,0x44,0x24,12 - leal 1(%r8),%eax -.byte 102,15,56,220,225 - xorl %ebp,%eax -.byte 0x0f,0x38,0xf1,0x44,0x24,28 -.byte 102,15,56,220,233 - leal 2(%r8),%eax - xorl %ebp,%eax -.byte 102,15,56,220,241 -.byte 0x0f,0x38,0xf1,0x44,0x24,44 - leal 3(%r8),%eax -.byte 102,15,56,220,249 - movups -32(%rcx,%r10,1),%xmm1 - xorl %ebp,%eax - -.byte 102,15,56,220,208 -.byte 0x0f,0x38,0xf1,0x44,0x24,60 - leal 4(%r8),%eax -.byte 102,15,56,220,216 - xorl %ebp,%eax -.byte 0x0f,0x38,0xf1,0x44,0x24,76 -.byte 102,15,56,220,224 - leal 5(%r8),%eax - xorl %ebp,%eax -.byte 102,15,56,220,232 -.byte 0x0f,0x38,0xf1,0x44,0x24,92 - movq %r10,%rax -.byte 102,15,56,220,240 -.byte 102,15,56,220,248 - movups -16(%rcx,%r10,1),%xmm0 - - call L$enc_loop6 - - movdqu (%rdi),%xmm8 - movdqu 16(%rdi),%xmm9 - movdqu 32(%rdi),%xmm10 - movdqu 48(%rdi),%xmm11 - movdqu 64(%rdi),%xmm12 - movdqu 80(%rdi),%xmm13 - leaq 96(%rdi),%rdi - movups -64(%rcx,%r10,1),%xmm1 - pxor %xmm2,%xmm8 - movaps 0(%rsp),%xmm2 - pxor %xmm3,%xmm9 - movaps 16(%rsp),%xmm3 - pxor %xmm4,%xmm10 - movaps 32(%rsp),%xmm4 - pxor %xmm5,%xmm11 - movaps 48(%rsp),%xmm5 - pxor %xmm6,%xmm12 - movaps 64(%rsp),%xmm6 - pxor %xmm7,%xmm13 - movaps 80(%rsp),%xmm7 - movdqu %xmm8,(%rsi) - movdqu %xmm9,16(%rsi) - movdqu %xmm10,32(%rsi) - movdqu %xmm11,48(%rsi) - movdqu %xmm12,64(%rsi) - movdqu %xmm13,80(%rsi) - leaq 96(%rsi),%rsi - - subq $6,%rdx - jnc L$ctr32_loop6 - - addq $6,%rdx - jz L$ctr32_done - - leal -48(%r10),%eax - leaq -80(%rcx,%r10,1),%rcx - negl %eax - shrl $4,%eax - jmp L$ctr32_tail - .p2align 5 L$ctr32_loop8: addl $8,%r8d @@ -2564,16 +2467,10 @@ L$cbc_decrypt_bulk: movdqa %xmm5,%xmm14 movdqu 80(%rdi),%xmm7 movdqa %xmm6,%xmm15 - leaq _OPENSSL_ia32cap_P(%rip),%r9 - movl 4(%r9),%r9d cmpq $0x70,%rdx jbe L$cbc_dec_six_or_seven - andl $71303168,%r9d - subq $0x50,%rdx - cmpl $4194304,%r9d - je L$cbc_dec_loop6_enter - subq $0x20,%rdx + subq $0x70,%rdx leaq 112(%rcx),%rcx jmp L$cbc_dec_loop8_enter .p2align 4 @@ -2844,51 +2741,6 @@ L$cbc_dec_seven: pxor %xmm9,%xmm9 jmp L$cbc_dec_tail_collected -.p2align 4 -L$cbc_dec_loop6: - movups %xmm7,(%rsi) - leaq 16(%rsi),%rsi - movdqu 0(%rdi),%xmm2 - movdqu 16(%rdi),%xmm3 - movdqa %xmm2,%xmm11 - movdqu 32(%rdi),%xmm4 - movdqa %xmm3,%xmm12 - movdqu 48(%rdi),%xmm5 - movdqa %xmm4,%xmm13 - movdqu 64(%rdi),%xmm6 - movdqa %xmm5,%xmm14 - movdqu 80(%rdi),%xmm7 - movdqa %xmm6,%xmm15 -L$cbc_dec_loop6_enter: - leaq 96(%rdi),%rdi - movdqa %xmm7,%xmm8 - - call _aesni_decrypt6 - - pxor %xmm10,%xmm2 - movdqa %xmm8,%xmm10 - pxor %xmm11,%xmm3 - movdqu %xmm2,(%rsi) - pxor %xmm12,%xmm4 - movdqu %xmm3,16(%rsi) - pxor %xmm13,%xmm5 - movdqu %xmm4,32(%rsi) - pxor %xmm14,%xmm6 - movq %rbp,%rcx - movdqu %xmm5,48(%rsi) - pxor %xmm15,%xmm7 - movl %r10d,%eax - movdqu %xmm6,64(%rsi) - leaq 80(%rsi),%rsi - subq $0x60,%rdx - ja L$cbc_dec_loop6 - - movdqa %xmm7,%xmm2 - addq $0x50,%rdx - jle L$cbc_dec_clear_tail_collected - movups %xmm7,(%rsi) - leaq 16(%rsi),%rsi - L$cbc_dec_tail: movups (%rdi),%xmm2 subq $0x10,%rdx diff --git a/generated-src/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S b/generated-src/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S index bcbea651c9..30cfd46091 100644 --- a/generated-src/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S +++ b/generated-src/mac-x86_64/crypto/fipsmodule/ghash-x86_64.S @@ -5,7 +5,6 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__APPLE__) .text - .globl _gcm_init_clmul .private_extern _gcm_init_clmul @@ -243,15 +242,9 @@ L$_ghash_clmul: jz L$odd_tail movdqu 16(%rsi),%xmm6 - leaq _OPENSSL_ia32cap_P(%rip),%rax - movl 4(%rax),%eax cmpq $0x30,%rcx jb L$skip4x - andl $71303168,%eax - cmpl $4194304,%eax - je L$skip4x - subq $0x30,%rcx movq $0xA040608020C0E000,%rax movdqu 48(%rsi),%xmm14 diff --git a/generated-src/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm b/generated-src/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm index 0583f0ec8a..273c922c3c 100644 --- a/generated-src/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm +++ b/generated-src/win-x86_64/crypto/fipsmodule/aesni-x86_64.asm @@ -1023,10 +1023,7 @@ DB 102,15,58,34,232,3 lea r9,[7+r8] mov DWORD[((96+12))+rsp],r10d bswap r9d - lea r10,[OPENSSL_ia32cap_P] - mov r10d,DWORD[4+r10] xor r9d,ebp - and r10d,71303168 mov DWORD[((112+12))+rsp],r9d movups xmm1,XMMWORD[16+rcx] @@ -1037,104 +1034,10 @@ DB 102,15,58,34,232,3 cmp rdx,8 jb NEAR $L$ctr32_tail - sub rdx,6 - cmp r10d,4194304 - je NEAR $L$ctr32_6x - lea rcx,[128+rcx] - sub rdx,2 + sub rdx,8 jmp NEAR $L$ctr32_loop8 -ALIGN 16 -$L$ctr32_6x: - shl eax,4 - mov r10d,48 - bswap ebp - lea rcx,[32+rax*1+rcx] - sub r10,rax - jmp NEAR $L$ctr32_loop6 - -ALIGN 16 -$L$ctr32_loop6: - add r8d,6 - movups xmm0,XMMWORD[((-48))+r10*1+rcx] - DB 102,15,56,220,209 - mov eax,r8d - xor eax,ebp - DB 102,15,56,220,217 - DB 0x0f,0x38,0xf1,0x44,0x24,12 - lea eax,[1+r8] - DB 102,15,56,220,225 - xor eax,ebp - DB 0x0f,0x38,0xf1,0x44,0x24,28 - DB 102,15,56,220,233 - lea eax,[2+r8] - xor eax,ebp - DB 102,15,56,220,241 - DB 0x0f,0x38,0xf1,0x44,0x24,44 - lea eax,[3+r8] - DB 102,15,56,220,249 - movups xmm1,XMMWORD[((-32))+r10*1+rcx] - xor eax,ebp - - DB 102,15,56,220,208 - DB 0x0f,0x38,0xf1,0x44,0x24,60 - lea eax,[4+r8] - DB 102,15,56,220,216 - xor eax,ebp - DB 0x0f,0x38,0xf1,0x44,0x24,76 - DB 102,15,56,220,224 - lea eax,[5+r8] - xor eax,ebp - DB 102,15,56,220,232 - DB 0x0f,0x38,0xf1,0x44,0x24,92 - mov rax,r10 - DB 102,15,56,220,240 - DB 102,15,56,220,248 - movups xmm0,XMMWORD[((-16))+r10*1+rcx] - - call $L$enc_loop6 - - movdqu xmm8,XMMWORD[rdi] - movdqu xmm9,XMMWORD[16+rdi] - movdqu xmm10,XMMWORD[32+rdi] - movdqu xmm11,XMMWORD[48+rdi] - movdqu xmm12,XMMWORD[64+rdi] - movdqu xmm13,XMMWORD[80+rdi] - lea rdi,[96+rdi] - movups xmm1,XMMWORD[((-64))+r10*1+rcx] - pxor xmm8,xmm2 - movaps xmm2,XMMWORD[rsp] - pxor xmm9,xmm3 - movaps xmm3,XMMWORD[16+rsp] - pxor xmm10,xmm4 - movaps xmm4,XMMWORD[32+rsp] - pxor xmm11,xmm5 - movaps xmm5,XMMWORD[48+rsp] - pxor xmm12,xmm6 - movaps xmm6,XMMWORD[64+rsp] - pxor xmm13,xmm7 - movaps xmm7,XMMWORD[80+rsp] - movdqu XMMWORD[rsi],xmm8 - movdqu XMMWORD[16+rsi],xmm9 - movdqu XMMWORD[32+rsi],xmm10 - movdqu XMMWORD[48+rsi],xmm11 - movdqu XMMWORD[64+rsi],xmm12 - movdqu XMMWORD[80+rsi],xmm13 - lea rsi,[96+rsi] - - sub rdx,6 - jnc NEAR $L$ctr32_loop6 - - add rdx,6 - jz NEAR $L$ctr32_done - - lea eax,[((-48))+r10] - lea rcx,[((-80))+r10*1+rcx] - neg eax - shr eax,4 - jmp NEAR $L$ctr32_tail - ALIGN 32 $L$ctr32_loop8: add r8d,8 @@ -2719,16 +2622,10 @@ $L$cbc_decrypt_body: movdqa xmm14,xmm5 movdqu xmm7,XMMWORD[80+rdi] movdqa xmm15,xmm6 - lea r9,[OPENSSL_ia32cap_P] - mov r9d,DWORD[4+r9] cmp rdx,0x70 jbe NEAR $L$cbc_dec_six_or_seven - and r9d,71303168 - sub rdx,0x50 - cmp r9d,4194304 - je NEAR $L$cbc_dec_loop6_enter - sub rdx,0x20 + sub rdx,0x70 lea rcx,[112+rcx] jmp NEAR $L$cbc_dec_loop8_enter ALIGN 16 @@ -2999,51 +2896,6 @@ $L$cbc_dec_seven: pxor xmm9,xmm9 jmp NEAR $L$cbc_dec_tail_collected -ALIGN 16 -$L$cbc_dec_loop6: - movups XMMWORD[rsi],xmm7 - lea rsi,[16+rsi] - movdqu xmm2,XMMWORD[rdi] - movdqu xmm3,XMMWORD[16+rdi] - movdqa xmm11,xmm2 - movdqu xmm4,XMMWORD[32+rdi] - movdqa xmm12,xmm3 - movdqu xmm5,XMMWORD[48+rdi] - movdqa xmm13,xmm4 - movdqu xmm6,XMMWORD[64+rdi] - movdqa xmm14,xmm5 - movdqu xmm7,XMMWORD[80+rdi] - movdqa xmm15,xmm6 -$L$cbc_dec_loop6_enter: - lea rdi,[96+rdi] - movdqa xmm8,xmm7 - - call _aesni_decrypt6 - - pxor xmm2,xmm10 - movdqa xmm10,xmm8 - pxor xmm3,xmm11 - movdqu XMMWORD[rsi],xmm2 - pxor xmm4,xmm12 - movdqu XMMWORD[16+rsi],xmm3 - pxor xmm5,xmm13 - movdqu XMMWORD[32+rsi],xmm4 - pxor xmm6,xmm14 - mov rcx,rbp - movdqu XMMWORD[48+rsi],xmm5 - pxor xmm7,xmm15 - mov eax,r10d - movdqu XMMWORD[64+rsi],xmm6 - lea rsi,[80+rsi] - sub rdx,0x60 - ja NEAR $L$cbc_dec_loop6 - - movdqa xmm2,xmm7 - add rdx,0x50 - jle NEAR $L$cbc_dec_clear_tail_collected - movups XMMWORD[rsi],xmm7 - lea rsi,[16+rsi] - $L$cbc_dec_tail: movups xmm2,XMMWORD[rdi] sub rdx,0x10 diff --git a/generated-src/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm b/generated-src/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm index 649f8a22b5..909abc58c1 100644 --- a/generated-src/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm +++ b/generated-src/win-x86_64/crypto/fipsmodule/ghash-x86_64.asm @@ -11,7 +11,6 @@ default rel %include "openssl/boringssl_prefix_symbols_nasm.inc" section .text code align=64 -EXTERN OPENSSL_ia32cap_P global gcm_init_clmul ALIGN 16 @@ -275,15 +274,9 @@ DB 102,65,15,56,0,194 jz NEAR $L$odd_tail movdqu xmm6,XMMWORD[16+rdx] - lea rax,[OPENSSL_ia32cap_P] - mov eax,DWORD[4+rax] cmp r9,0x30 jb NEAR $L$skip4x - and eax,71303168 - cmp eax,4194304 - je NEAR $L$skip4x - sub r9,0x30 mov rax,0xA040608020C0E000 movdqu xmm14,XMMWORD[48+rdx] diff --git a/include/openssl/arm_arch.h b/include/openssl/arm_arch.h index d2495bad66..5db9bb3aa8 100644 --- a/include/openssl/arm_arch.h +++ b/include/openssl/arm_arch.h @@ -89,6 +89,8 @@ #define ARMV8_APPLE_M1 (1 << 13) #define ARMV8_NEOVERSE_V2 (1 << 14) +// ARMV8_DIT indicates support for the Data-Independent Timing (DIT) flag. +#define ARMV8_DIT (1 << 14) // // MIDR_EL1 system register // diff --git a/include/openssl/bio.h b/include/openssl/bio.h index 96f59d6b9c..730601467a 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -105,9 +105,10 @@ OPENSSL_EXPORT int BIO_up_ref(BIO *bio); // BIO_read calls the |bio| |callback_ex| if set with |BIO_CB_READ|, attempts to // read |len| bytes into |data|, then calls |callback_ex| with -// |BIO_CB_READ|+|BIO_CB_RETURN|. If |callback_ex| is set BIO_read returns the -// value from calling the |callback_ex|, otherwise |BIO_read| returns the number -// of bytes read, zero on EOF, or a negative number on error. +// |BIO_CB_READ|+|BIO_CB_RETURN|. If |len| is less than or equal to zero, the +// function does nothing and return zero. If |callback_ex| is set BIO_read +// returns the value from calling the |callback_ex|, otherwise |BIO_read| +// returns the number of bytes read, zero on EOF, or a negative number on error. OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); // BIO_read_ex calls |BIO_read| and stores the number of bytes read in @@ -119,14 +120,16 @@ OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); OPENSSL_EXPORT int BIO_read_ex(BIO *bio, void *data, size_t data_len, size_t *read_bytes); -// BIO_gets calls the |bio| |callback_ex| if set with |BIO_CB_GETS|, attempts -// to read a line from |bio| and write at most |size| bytes into |buf|, then -// calls |callback_ex| with |BIO_CB_GETS|+|BIO_CB_RETURN|. If |callback_ex| is -// set BIO_gets returns the value from calling the |callback_ex|, otherwise -// |BIO_gets| returns the number of bytes read, or a negative number on error. -// This function's output always includes a trailing NUL byte, so it will read at -// most |size - 1| bytes. +// BIO_gets calls |callback_ex| from |bio| if set with |BIO_CB_GETS|, attempts +// to read a line from |bio| and writes at most |size| bytes into |buf|. Then it +// calls |callback_ex| with |BIO_CB_GETS|+|BIO_CB_RETURN|. If |size| is less +// than or equal to zero, the function does nothing and returns zero. +// If |callback_ex| is set, |BIO_gets| returns the value from calling +// |callback_ex|, otherwise |BIO_gets| returns the number of bytes read, or a +// negative number on error. // +// This function's output always includes a trailing NUL byte, so it will read +// at most |size - 1| bytes. // If the function read a complete line, the output will include the newline // character, '\n'. If no newline was found before |size - 1| bytes or EOF, it // outputs the bytes which were available. @@ -134,9 +137,10 @@ OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); // BIO_write call the |bio| |callback_ex| if set with |BIO_CB_WRITE|, writes // |len| bytes from |data| to |bio|, then calls |callback_ex| with -// |BIO_CB_WRITE|+|BIO_CB_RETURN|. If |callback_ex| is set BIO_write returns the -// value from calling the |callback_ex|, otherwise |BIO_write| returns the -// number of bytes written, or a negative number on error. +// |BIO_CB_WRITE|+|BIO_CB_RETURN|. If |len| is less than or equal to zero, the +// function does nothing and return zero. If |callback_ex| is set BIO_write +// returns the value from calling the |callback_ex|, otherwise |BIO_write| +// returns the number of bytes written, or a negative number on error. OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len); // BIO_write_ex calls |BIO_write| and stores the number of bytes written in diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index bb1be29a40..fbe6e21957 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -84,6 +84,35 @@ OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); #endif // OPENSSL_ARM && OPENSSL_LINUX && !OPENSSL_STATIC_ARMCAP +// Data-Independent Timing (DIT) on AArch64 + +#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS) && defined(MAKE_DIT_AVAILABLE) +// (TODO): See if we can detect the DIT capability in Windows environment + +// armv8_enable_dit sets the DIT flag to 1 and returns its original value +// before it was called. +uint64_t armv8_enable_dit(void); + +// armv8_restore_dit takes as input a value to restore the DIT flag to. +void armv8_restore_dit(volatile uint64_t *original_dit); + +// SET_DIT_AUTO_DISABLE can be inserted in the caller's application at +// the beginning of the code section that makes repeated calls to AWS-LC functions. +// The flag will be automatically restored to its original value at the end of the +// scope. +// This can minimise the effect on performance of repeatedly setting and +// disabling DIT. +// Instead of the macro, the functions above can be used. +// An example of their usage is present in the benchmarking function +// `Speed()` in `tool/speed.cc` when the option `-dit` is passed in. +#define SET_DIT_AUTO_DISABLE \ + volatile uint64_t _dit_restore_orig \ + __attribute__((cleanup(armv8_restore_dit))) \ + OPENSSL_UNUSED = armv8_enable_dit(); + +#else +#define SET_DIT_AUTO_DISABLE +#endif // OPENSSL_AARCH64 && !OPENSSL_WINDOWS && MAKE_DIT_AVAILABLE // FIPS monitoring diff --git a/include/openssl/des.h b/include/openssl/des.h index d9b49bfec3..f425a792e5 100644 --- a/include/openssl/des.h +++ b/include/openssl/des.h @@ -156,18 +156,6 @@ OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, const DES_key_schedule *ks2, DES_cblock *ivec, int enc); -// Private functions. -// -// These functions are deprecated. - -OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, - const DES_key_schedule *ks2, - const DES_key_schedule *ks3); - -OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, - const DES_key_schedule *ks2, - const DES_key_schedule *ks3); - #if defined(__cplusplus) } // extern C diff --git a/include/openssl/evp.h b/include/openssl/evp.h index eea831786f..42631fa72f 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1142,17 +1142,18 @@ OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, size_t mac_key_len); -// General No-op Functions [Deprecated]. +// Deprecated functions -// EVP_PKEY_get0 returns NULL. This function is provided for compatibility with -// OpenSSL but does not return anything. Use the typed |EVP_PKEY_get0_*| -// functions instead. +// EVP_PKEY_get0 returns the consumed key. The type of value returned will be +// one of the following, depending on the type of the |EVP_PKEY|: +// |RSA|, |DSA| or |EC_KEY|. // -// Note: In OpenSSL, the returned type will be different depending on the type -// of |EVP_PKEY| consumed. This leads to misuage very easily and has been -// deprecated as a no-op to avoid so. +// This function is provided only for compatibility with OpenSSL. +// Prefer the use the typed |EVP_PKEY_get0_*| functions instead. OPENSSL_EXPORT OPENSSL_DEPRECATED void *EVP_PKEY_get0(const EVP_PKEY *pkey); +// General No-op Functions [Deprecated]. + // OpenSSL_add_all_algorithms does nothing. This has been deprecated since // OpenSSL 1.1.0. // diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h index 95f873218c..0f791bffc0 100644 --- a/include/openssl/hmac.h +++ b/include/openssl/hmac.h @@ -153,6 +153,23 @@ OPENSSL_EXPORT void HMAC_CTX_reset(HMAC_CTX *ctx); // Precomputed key functions +// HMAC_MD5_PRECOMPUTED_KEY_SIZE is the precomputed key size for MD5, in bytes +#define HMAC_MD5_PRECOMPUTED_KEY_SIZE 32 +// HMAC_SHA1_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA1, in bytes +#define HMAC_SHA1_PRECOMPUTED_KEY_SIZE 40 +// HMAC_SHA224_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA224, in bytes +#define HMAC_SHA224_PRECOMPUTED_KEY_SIZE 64 +// HMAC_SHA256_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA256, in bytes +#define HMAC_SHA256_PRECOMPUTED_KEY_SIZE 64 +// HMAC_SHA384_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA384, in bytes +#define HMAC_SHA384_PRECOMPUTED_KEY_SIZE 128 +// HMAC_SHA512_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA512, in bytes +#define HMAC_SHA512_PRECOMPUTED_KEY_SIZE 128 +// HMAC_SHA512_224_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA512_224, in bytes +#define HMAC_SHA512_224_PRECOMPUTED_KEY_SIZE 128 +// HMAC_SHA512_256_PRECOMPUTED_KEY_SIZE is the precomputed key size for SHA512_256, in bytes +#define HMAC_SHA512_256_PRECOMPUTED_KEY_SIZE 128 + // HMAC_MAX_PRECOMPUTED_KEY_SIZE is the largest precomputed key size, in bytes. #define HMAC_MAX_PRECOMPUTED_KEY_SIZE (2 * (EVP_MAX_MD_CHAINING_LENGTH)) @@ -176,7 +193,8 @@ OPENSSL_EXPORT int HMAC_set_precomputed_key_export(HMAC_CTX *ctx); // // If |out| is not NULL, |*out_len| must contain the number of bytes of space // available at |out|. If sufficient, the precomputed key will be written in -// |out| and |out_len| will be updated with the true length. An output size of +// |out| and |out_len| will be updated with the true length (which is +// |HMAC_xxx_PRECOMPUTED_KEY_SIZE| for hash function xxx). An output size of // |HMAC_MAX_PRECOMPUTED_KEY_SIZE| will always be large enough. After a // successful call to |HMAC_get_precomputed_key| with a non-NULL |out|, the // context can be directly used for computing an HMAC using |HMAC_Update| and diff --git a/include/openssl/nid.h b/include/openssl/nid.h index fa8a985717..15d262ae8a 100644 --- a/include/openssl/nid.h +++ b/include/openssl/nid.h @@ -4321,9 +4321,11 @@ extern "C" { #define SN_SecP256r1Kyber768Draft00 "SecP256r1Kyber768Draft00" #define NID_SecP256r1Kyber768Draft00 981 +#define OBJ_SecP256r1Kyber768Draft00 1L, 3L, 9999L, 99L, 52L #define SN_X25519Kyber768Draft00 "X25519Kyber768Draft00" #define NID_X25519Kyber768Draft00 982 +#define OBJ_X25519Kyber768Draft00 1L, 3L, 9999L, 99L, 51L #define SN_ffdhe3072 "ffdhe3072" #define NID_ffdhe3072 983 diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h index b5caba4c33..df1f4b8fc7 100644 --- a/include/openssl/ocsp.h +++ b/include/openssl/ocsp.h @@ -171,11 +171,16 @@ OPENSSL_EXPORT OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); // |req|. If |val| is NULL, a random nonce is generated and used. If |len| is // zero or negative, a default length of 16 bytes will be used. // If |val| is non-NULL, |len| must equal the length of |val|. This is different -// from OpenSSL, which allows a default length for |len| to be used. Misusage +// from OpenSSL, which allows a default length for |len| to be used. Mis-usage // of the default length could result in a read overflow, so we disallow it. OPENSSL_EXPORT int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +// OCSP_basic_add1_nonce is identical to |OCSP_request_add1_nonce|, but adds the +// nonce to |resp| instead (the response). +OPENSSL_EXPORT int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, + unsigned char *val, int len); + // OCSP_check_nonce checks nonce existence and equality in |req| and |bs|. If // there is parsing issue with |req| or |bs|, it will be determined that a // nonce does not exist within |req| or |bs|. diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 1cf54d2c39..f0a392a6c3 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2322,6 +2322,44 @@ OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *store, X509 *x509); // |X509_STORE_CTX_set0_crls|. OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *store, X509_CRL *crl); +// X509_STORE_get0_param returns |store|'s verification parameters. This object +// is mutable and may be modified by the caller. For an individual certificate +// verification operation, |X509_STORE_CTX_init| initializes the +// |X509_STORE_CTX|'s parameters with these parameters. +// +// WARNING: |X509_STORE_CTX_init| applies some default parameters (as in +// |X509_VERIFY_PARAM_inherit|) after copying |store|'s parameters. This means +// it is impossible to leave some parameters unset at |store|. They must be +// explicitly unset after creating the |X509_STORE_CTX|. +// +// As of writing these late defaults are a depth limit (see +// |X509_VERIFY_PARAM_set_depth|) and the |X509_V_FLAG_TRUSTED_FIRST| flag. This +// warning does not apply if the parameters were set in |store|. +// +// TODO(crbug.com/boringssl/441): This behavior is very surprising. Can we +// remove this notion of late defaults? The unsettable value at |X509_STORE| is +// -1, which rejects everything but explicitly-trusted self-signed certificates. +// |X509_V_FLAG_TRUSTED_FIRST| is mostly a workaround for poor path-building. +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store); + +// X509_STORE_set1_param copies verification parameters from |param| as in +// |X509_VERIFY_PARAM_set1|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store, + const X509_VERIFY_PARAM *param); + +// X509_STORE_set_flags enables all values in |flags| in |store|'s verification +// flags. |flags| should be a combination of |X509_V_FLAG_*| constants. +// +// WARNING: These flags will be combined with default flags when copied to an +// |X509_STORE_CTX|. This means it is impossible to unset those defaults from +// the |X509_STORE|. See discussion in |X509_STORE_get0_param|. +OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *store, unsigned long flags); + +// X509_STORE_set_depth configures |store| to, by default, limit certificate +// chains to |depth| intermediate certificates. This count excludes both the +// target certificate and the trust anchor (root certificate). +OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth); + // X509_STORE_set_purpose configures the purpose check for |store|. See // |X509_VERIFY_PARAM_set_purpose| for details. OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose); @@ -2330,15 +2368,13 @@ OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose); // |X509_VERIFY_PARAM_set_trust| for details. OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust); -// TODO(crbug.com/boringssl/426): Move the other |X509_STORE| functions here. - // Certificate verification. // // An |X509_STORE_CTX| object represents a single certificate verification // operation. To verify a certificate chain, callers construct an // |X509_STORE_CTX|, initialize it with |X509_STORE_CTX_init|, configure extra -// parameters, and call |X509_verify_cert|. +// parameters with |X509_STORE_CTX_get0_param|, and call |X509_verify_cert|. // X509_STORE_CTX_new returns a newly-allocated, empty |X509_STORE_CTX|, or NULL // on error. @@ -2384,6 +2420,137 @@ OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, // depended on. OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); +// X509_STORE_CTX_get0_chain, after a successful |X509_verify_cert| call, +// returns the verified certificate chain. The chain begins with the leaf and +// ends with trust anchor. +// +// At other points, such as after a failed verification or during the deprecated +// verification callback, it returns the partial chain built so far. Callers +// should avoid relying on this as this exposes unstable library implementation +// details. +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get1_chain behaves like |X509_STORE_CTX_get0_chain| but +// returns a newly-allocated |STACK_OF(X509)| containing the completed chain, +// with each certificate's reference count incremented. Callers must free the +// result with |sk_X509_pop_free| and |X509_free| when done. +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); + + +// The following values are possible outputs of |X509_STORE_CTX_get_error|. +#define X509_V_OK 0 +#define X509_V_ERR_UNSPECIFIED 1 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +#define X509_V_ERR_UNNESTED_RESOURCE 46 +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_APPLICATION_VERIFICATION 50 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +#define X509_V_ERR_HOSTNAME_MISMATCH 62 +#define X509_V_ERR_EMAIL_MISMATCH 63 +#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +#define X509_V_ERR_INVALID_CALL 65 +#define X509_V_ERR_STORE_LOOKUP 66 +#define X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS 67 + +// X509_STORE_CTX_get_error, after |X509_verify_cert| returns, returns +// |X509_V_OK| if verification succeeded or an |X509_V_ERR_*| describing why +// verification failed. This will be consistent with |X509_verify_cert|'s return +// value, unless the caller used the deprecated verification callback (see +// |X509_STORE_CTX_set_verify_cb|) in a way that breaks |ctx|'s invariants. +// +// If called during the deprecated verification callback when |ok| is zero, it +// returns the current error under consideration. +OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_set_error sets |ctx|'s error to |err|, which should be +// |X509_V_OK| or an |X509_V_ERR_*| constant. It is not expected to be called in +// typical |X509_STORE_CTX| usage, but may be used in callback APIs where +// applications synthesize |X509_STORE_CTX| error conditions. See also +// |X509_STORE_CTX_set_verify_cb| and |SSL_CTX_set_cert_verify_callback|. +OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err); + +// X509_verify_cert_error_string returns |err| as a human-readable string, where +// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns +// a default description. +OPENSSL_EXPORT const char *X509_verify_cert_error_string(long err); + +// X509_STORE_CTX_get_error_depth returns the depth at which the error returned +// by |X509_STORE_CTX_get_error| occured. This is zero-indexed integer into the +// certificate chain. Zero indicates the target certificate, one its issuer, and +// so on. +OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get_current_cert returns the certificate which caused the +// error returned by |X509_STORE_CTX_get_error|. +OPENSSL_EXPORT X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get0_current_crl returns the CRL which caused the error +// returned by |X509_STORE_CTX_get_error|. +OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get0_store returns the |X509_STORE| that |ctx| uses. +OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get0_cert returns the leaf certificate that |ctx| is +// verifying. +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get0_untrusted returns the stack of untrusted intermediates +// used by |ctx| for certificate verification. +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); + // X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates // in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this // function causes |ctx| to ignore any certificates configured in the @@ -2396,6 +2563,16 @@ OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +// X509_STORE_CTX_set0_crls configures |ctx| to consider the CRLs in |sk| as +// candidates for CRL lookup. |sk| must remain valid for the duration of |ctx|. +// These CRLs are considered in addition to CRLs found in |X509_STORE|. +// +// WARNING: This function differs from most |set0| functions in that it does not +// take ownership of its input. The caller is required to ensure the lifetimes +// are consistent. +OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, + STACK_OF(X509_CRL) *sk); + // X509_STORE_CTX_set_default looks up the set of parameters named |name| and // applies those default verification parameters for |ctx|. As in // |X509_VERIFY_PARAM_inherit|, only unset parameters are changed. This function @@ -2413,6 +2590,49 @@ OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); +// X509_STORE_CTX_get0_param returns |ctx|'s verification parameters. This +// object is mutable and may be modified by the caller. +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( + X509_STORE_CTX *ctx); + +// X509_STORE_CTX_set0_param returns |ctx|'s verification parameters to |param| +// and takes ownership of |param|. After this function returns, the caller +// should not free |param|. +// +// WARNING: This function discards any values which were previously applied in +// |ctx|, including the "default" parameters applied late in +// |X509_STORE_CTX_init|. These late defaults are not applied to parameters +// created standalone by |X509_VERIFY_PARAM_new|. +// +// TODO(crbug.com/boringssl/441): This behavior is very surprising. Should we +// re-apply the late defaults in |param|, or somehow avoid this notion of late +// defaults altogether? +OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, + X509_VERIFY_PARAM *param); + +// X509_STORE_CTX_set_flags enables all values in |flags| in |ctx|'s +// verification flags. |flags| should be a combination of |X509_V_FLAG_*| +// constants. +OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, + unsigned long flags); + +// X509_STORE_CTX_set_time configures certificate verification to use |t| +// instead of the current time. |flags| is ignored and should be zero. +OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, + unsigned long flags, time_t t); + +// X509_STORE_CTX_set_time_posix configures certificate verification to use |t| +// instead of the current time. |t| is interpreted as a POSIX timestamp in +// seconds. |flags| is ignored and should be zero. +OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, + unsigned long flags, + int64_t t); + +// X509_STORE_CTX_set_depth configures |ctx| to, by default, limit certificate +// chains to |depth| intermediate certificates. This count excludes both the +// target certificate and the trust anchor (root certificate). +OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + // X509_STORE_CTX_set_purpose simultaneously configures |ctx|'s purpose and // trust checks, if unset. It returns one on success and zero if |purpose| is // not a valid purpose value. |purpose| should be an |X509_PURPOSE_*| constant. @@ -2448,9 +2668,6 @@ OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); // difference. OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); -// TODO(crbug.com/boringssl/426): Move the other |X509_STORE_CTX| functions -// here. - // Verification parameters // @@ -2464,6 +2681,147 @@ OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); // X509_VERIFY_PARAM_free releases memory associated with |param|. OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +// X509_VERIFY_PARAM_inherit applies |from| as the default values for |to|. That +// is, for each parameter that is unset in |to|, it copies the value in |from|. +// This function returns one on success and zero on error. +OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); + +// X509_VERIFY_PARAM_set1 copies parameters from |from| to |to|. If a parameter +// is unset in |from|, the existing value in |to| is preserved. This function +// returns one on success and zero on error. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); + +// X509_VERIFY_PARAM_set_flags enables all values in |flags| in |param|'s +// verification flags and returns one. |flags| should be a combination of +// |X509_V_FLAG_*| constants. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); + +// X509_VERIFY_PARAM_clear_flags disables all values in |flags| in |param|'s +// verification flags and returns one. |flags| should be a combination of +// |X509_V_FLAG_*| constants. +OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); + +// X509_VERIFY_PARAM_get_flags returns |param|'s verification flags. +OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags( + const X509_VERIFY_PARAM *param); + +// X509_VERIFY_PARAM_set_depth configures |param| to limit certificate chains to +// |depth| intermediate certificates. This count excludes both the target +// certificate and the trust anchor (root certificate). +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, + int depth); + +// X509_VERIFY_PARAM_get_depth returns the maximum depth configured in |param|. +// See |X509_VERIFY_PARAM_set_depth|. +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +// X509_VERIFY_PARAM_set_time configures certificate verification to use |t| +// instead of the current time. +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, + time_t t); + +// X509_VERIFY_PARAM_set_time_posix configures certificate verification to use +// |t| instead of the current time. |t| is interpreted as a POSIX timestamp in +// seconds. +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, + int64_t t); + +// X509_VERIFY_PARAM_add0_policy adds |policy| to the user-initial-policy-set +// (see Section 6.1.1 of RFC 5280). On success, it takes ownership of +// |policy| and returns one. Otherwise, it returns zero and the caller retains +// owneship of |policy|. +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); + +// X509_VERIFY_PARAM_set1_policies sets the user-initial-policy-set (see +// Section 6.1.1 of RFC 5280) to a copy of |policies|. It returns one on success +// and zero on error. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( + X509_VERIFY_PARAM *param, const STACK_OF(ASN1_OBJECT) *policies); + +// X509_VERIFY_PARAM_set1_host configures |param| to check for the DNS name +// specified by |name| and clears any previously specified hostname. If |name| +// is NULL or empty, the list of hostnames is cleared and name checks are not +// performed on the peer certificate. It returns one on success and zero on +// error. +// |namelen| should be set to the length of |name|. It may be zero if |name| is +// NUL-terminated, but this is only maintained for backwards compatibility with +// OpenSSL. +// +// By default, both subject alternative names and the subject's common name +// attribute are checked. The latter has long been deprecated, so callers should +// call |X509_VERIFY_PARAM_set_hostflags| with +// |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| to use the standard behavior. +// https://crbug.com/boringssl/464 tracks fixing the default. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t name_len); + +// X509_VERIFY_PARAM_add1_host adds |name| to the list of names checked by +// |param|. If any configured DNS name matches the certificate, verification +// succeeds. Any previous names set via |X509_VERIFY_PARAM_set1_host| or +// |X509_VERIFY_PARAM_add1_host| are retained, no change is made if |name| is +// NULL or empty. When multiple names are configured, the peer is considered +// verified when any name matches. It returns one on success and zero on error. +// |namelen| should be set to the length of |name|. It may be zero if |name| is +// NUL-terminated, but this is only maintained for backwards compatibility with +// OpenSSL. +// +// By default, both subject alternative names and the subject's common name +// attribute are checked. The latter has long been deprecated, so callers should +// call |X509_VERIFY_PARAM_set_hostflags| with +// |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| to use the standard behavior. +// https://crbug.com/boringssl/464 tracks fixing the default. +OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t name_len); + +// X509_CHECK_FLAG_NO_WILDCARDS disables wildcard matching for DNS names. +#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 + +// X509_CHECK_FLAG_NEVER_CHECK_SUBJECT disables the subject fallback, normally +// enabled when subjectAltNames is missing. +#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 + +// X509_VERIFY_PARAM_set_hostflags sets the name-checking flags on |param| to +// |flags|. |flags| should be a combination of |X509_CHECK_FLAG_*| constants. +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); + +// X509_VERIFY_PARAM_set1_email configures |param| to check for the email +// address specified by |email|. It returns one on success and zero on error. +// |emaillen| should be set to the length of |email|. It may be zero if |email| +// is NUL-terminated, but this is only maintained for backwards compatibility +// with OpenSSL. +// +// By default, both subject alternative names and the subject's email address +// attribute are checked. The |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| flag may be +// used to change this behavior. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, + size_t email_len); + +// X509_VERIFY_PARAM_set1_ip configures |param| to check for the IP address +// specified by |ip|. It returns one on success and zero on error. The IP +// address is specified in its binary representation. |ip_len| must be 4 for an +// IPv4 address and 16 for an IPv6 address. +// NOTE:|iplen| MUST be set to the length of |ip|. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const uint8_t *ip, size_t ip_len); + +// X509_VERIFY_PARAM_set1_ip_asc decodes |ipasc| as the ASCII representation of +// an IPv4 or IPv6 address, and configures |param| to check for it. It returns +// one on success and zero on error. +// |ipasc| MUST be a NUL-terminal ASCII string: dotted decimal quad for IPv4 and +// colon-separated hexadecimal for IPv6. The condensed "::" notation is +// supported for IPv6 addresses. +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + // X509_PURPOSE_SSL_CLIENT validates TLS client certificates. It checks for the // id-kp-clientAuth EKU and one of digitalSignature or keyAgreement key usages. // The TLS library is expected to check for the key usage specific to the @@ -2582,9 +2940,6 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); -// TODO(crbug.com/boringssl/426): Move the other |X509_VERIFY_PARAM| functions -// here. - // SignedPublicKeyAndChallenge structures. // @@ -4006,6 +4361,17 @@ OPENSSL_EXPORT void X509_STORE_set_check_crl( OPENSSL_EXPORT void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +// The following flags do nothing. The corresponding non-standard options have +// been removed. +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 +#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0 +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0 + +// X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS does nothing, but is necessary in +// OpenSSL to enable standard wildcard matching. In AWS-LC, this behavior is +// always enabled. +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 + // Private structures. @@ -4041,11 +4407,6 @@ DEFINE_STACK_OF(X509_TRUST) #define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings -// X509_verify_cert_error_string returns |err| as a human-readable string, where -// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns -// a default description. -OPENSSL_EXPORT const char *X509_verify_cert_error_string(long err); - OPENSSL_EXPORT const char *X509_get_default_cert_area(void); OPENSSL_EXPORT const char *X509_get_default_cert_dir(void); OPENSSL_EXPORT const char *X509_get_default_cert_file(void); @@ -4118,17 +4479,6 @@ certificate chain. DEFINE_STACK_OF(X509_OBJECT) - -// X509_STORE_set_depth configures |store| to, by default, limit certificate -// chains to |depth| intermediate certificates. This count excludes both the -// target certificate and the trust anchor (root certificate). -OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth); - -// X509_STORE_CTX_set_depth configures |ctx| to, by default, limit certificate -// chains to |depth| intermediate certificates. This count excludes both the -// target certificate and the trust anchor (root certificate). -OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); - #define X509_STORE_CTX_set_app_data(ctx, data) \ X509_STORE_CTX_set_ex_data(ctx, 0, data) #define X509_STORE_CTX_get_app_data(ctx) X509_STORE_CTX_get_ex_data(ctx, 0) @@ -4147,90 +4497,16 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); // of the |X509_FILETYPE_*| constants to determine if the contents are PEM or // DER. If |type| is |X509_FILETYPE_DEFAULT|, |path| is ignored and instead some // default system path is used. -OPENSSL_EXPORT int X509_LOOKUP_load_file(X509_LOOKUP *lookup, const char *path, - int type); - -// X509_LOOKUP_add_dir configures |lookup| to load information from the -// directory at |path|. It returns one on success and zero on error. |type| -// should be one of the |X509_FILETYPE_*| constants to determine if the contents -// are PEM or DER. If |type| is |X509_FILETYPE_DEFAULT|, |path| is ignored and -// instead some default system path is used. -OPENSSL_EXPORT int X509_LOOKUP_add_dir(X509_LOOKUP *lookup, const char *path, - int type); - -#define X509_V_OK 0 -#define X509_V_ERR_UNSPECIFIED 1 - -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -#define X509_V_ERR_UNABLE_TO_GET_CRL 3 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -#define X509_V_ERR_CERT_NOT_YET_VALID 9 -#define X509_V_ERR_CERT_HAS_EXPIRED 10 -#define X509_V_ERR_CRL_NOT_YET_VALID 11 -#define X509_V_ERR_CRL_HAS_EXPIRED 12 -#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -#define X509_V_ERR_OUT_OF_MEM 17 -#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -#define X509_V_ERR_CERT_REVOKED 23 -#define X509_V_ERR_INVALID_CA 24 -#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -#define X509_V_ERR_INVALID_PURPOSE 26 -#define X509_V_ERR_CERT_UNTRUSTED 27 -#define X509_V_ERR_CERT_REJECTED 28 -// These are 'informational' when looking for issuer cert -#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -#define X509_V_ERR_AKID_SKID_MISMATCH 30 -#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 - -#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -#define X509_V_ERR_INVALID_NON_CA 37 -#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 - -#define X509_V_ERR_INVALID_EXTENSION 41 -#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -#define X509_V_ERR_NO_EXPLICIT_POLICY 43 -#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 - -#define X509_V_ERR_UNNESTED_RESOURCE 46 - -#define X509_V_ERR_PERMITTED_VIOLATION 47 -#define X509_V_ERR_EXCLUDED_VIOLATION 48 -#define X509_V_ERR_SUBTREE_MINMAX 49 -#define X509_V_ERR_APPLICATION_VERIFICATION 50 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 - -// The following indicate Host, email and IP check errors -#define X509_V_ERR_HOSTNAME_MISMATCH 62 -#define X509_V_ERR_EMAIL_MISMATCH 63 -#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 - -// X509_V_ERR_INVALID_CALL indicates a caller error. -#define X509_V_ERR_INVALID_CALL 65 -// X509_V_ERR_STORE_LOOKUP indicates an issuer lookup error. -#define X509_V_ERR_STORE_LOOKUP 66 +OPENSSL_EXPORT int X509_LOOKUP_load_file(X509_LOOKUP *lookup, const char *path, + int type); -#define X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS 67 +// X509_LOOKUP_add_dir configures |lookup| to load information from the +// directory at |path|. It returns one on success and zero on error. |type| +// should be one of the |X509_FILETYPE_*| constants to determine if the contents +// are PEM or DER. If |type| is |X509_FILETYPE_DEFAULT|, |path| is ignored and +// instead some default system path is used. +OPENSSL_EXPORT int X509_LOOKUP_add_dir(X509_LOOKUP *lookup, const char *path, + int type); // Certificate verify flags @@ -4339,46 +4615,6 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); -// X509_STORE_set_flags enables all values in |flags| in |store|'s verification -// flags. |flags| should be a combination of |X509_V_FLAG_*| constants. -// -// WARNING: These flags will be combined with default flags when copied to an -// |X509_STORE_CTX|. This means it is impossible to unset those defaults from -// the |X509_STORE|. See discussion in |X509_STORE_get0_param|. -OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *store, unsigned long flags); - -// X509_STORE_set1_param copies verification parameters from |param| as in -// |X509_VERIFY_PARAM_set1|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store, - const X509_VERIFY_PARAM *param); - -// X509_STORE_get0_param returns |store|'s verification parameters. This object -// is mutable and may be modified by the caller. For an individual certificate -// verification operation, |X509_STORE_CTX_init| initializes the -// |X509_STORE_CTX|'s parameters with these parameters. -// -// WARNING: |X509_STORE_CTX_init| applies some default parameters (as in -// |X509_VERIFY_PARAM_inherit|) after copying |store|'s parameters. This means -// it is impossible to leave some parameters unset at |store|. They must be -// explicitly unset after creating the |X509_STORE_CTX|. -// -// As of writing these late defaults are a depth limit (see -// |X509_VERIFY_PARAM_set_depth|) and the |X509_V_FLAG_TRUSTED_FIRST| flag. This -// warning does not apply if the parameters were set in |store|. -// -// TODO(crbug.com/boringssl/441): This behavior is very surprising. Can we -// remove this notion of late defaults? The unsettable value at |X509_STORE| is -// -1, which rejects everything but explicitly-trusted self-signed certificates. -// |X509_V_FLAG_TRUSTED_FIRST| is mostly a workaround for poor path-building. -OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store); - -// X509_STORE_CTX_get0_store returns the |X509_STORE| that |ctx| uses. -OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); - -// X509_STORE_CTX_get0_cert returns the leaf certificate that |ctx| is -// verifying. -OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); - OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, const X509_LOOKUP_METHOD *m); @@ -4410,205 +4646,6 @@ OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, OPENSSL_EXPORT int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *dir); OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); -OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); -OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); -OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); -OPENSSL_EXPORT X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); -OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); -OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); - -// X509_STORE_CTX_get0_chain, after a successful |X509_verify_cert| call, -// returns the verified certificate chain. The chain begins with the leaf and -// ends with trust anchor. -// -// At other points, such as after a failed verification or during the deprecated -// verification callback, it returns the partial chain built so far. Callers -// should avoid relying on this as this exposes unstable library implementation -// details. -OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); - -// X509_STORE_CTX_get1_chain behaves like |X509_STORE_CTX_get0_chain| and also -// increments the reference counter. The |STACK_OF(X509)| must be freed with -// |sk_X509_pop_free| -OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); -OPENSSL_EXPORT void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); -OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted( - X509_STORE_CTX *ctx); -OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, - STACK_OF(X509_CRL) *sk); - -// X509_STORE_CTX_set_flags enables all values in |flags| in |ctx|'s -// verification flags. |flags| should be a combination of |X509_V_FLAG_*| -// constants. -OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, - unsigned long flags); - -// X509_STORE_CTX_set_time configures certificate verification to use |t| -// instead of the current time. |flags| is ignored and should be zero. -OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, - unsigned long flags, time_t t); - -// X509_STORE_CTX_set_time_posix configures certificate verification to use |t| -// instead of the current time. |t| is interpreted as a POSIX timestamp in -// seconds. |flags| is ignored and should be zero. -OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, - unsigned long flags, - int64_t t); - -// X509_STORE_CTX_get0_param returns |ctx|'s verification parameters. This -// object is mutable and may be modified by the caller. -OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( - X509_STORE_CTX *ctx); - -// X509_STORE_CTX_set0_param returns |ctx|'s verification parameters to |param| -// and takes ownership of |param|. After this function returns, the caller -// should not free |param|. -// -// WARNING: This function discards any values which were previously applied in -// |ctx|, including the "default" parameters applied late in -// |X509_STORE_CTX_init|. These late defaults are not applied to parameters -// created standalone by |X509_VERIFY_PARAM_new|. -// -// TODO(crbug.com/boringssl/441): This behavior is very surprising. Should we -// re-apply the late defaults in |param|, or somehow avoid this notion of late -// defaults altogether? -OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, - X509_VERIFY_PARAM *param); - -// X509_VERIFY_PARAM_inherit applies |from| as the default values for |to|. That -// is, for each parameter that is unset in |to|, it copies the value in |from|. -// This function returns one on success and zero on error. -OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); - -// X509_VERIFY_PARAM_set1 copies parameters from |from| to |to|. If a parameter -// is unset in |from|, the existing value in |to| is preserved. This function -// returns one on success and zero on error. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); - -// X509_VERIFY_PARAM_set_flags enables all values in |flags| in |param|'s -// verification flags and returns one. |flags| should be a combination of -// |X509_V_FLAG_*| constants. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, - unsigned long flags); - -// X509_VERIFY_PARAM_clear_flags disables all values in |flags| in |param|'s -// verification flags and returns one. |flags| should be a combination of -// |X509_V_FLAG_*| constants. -OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, - unsigned long flags); - -// X509_VERIFY_PARAM_get_flags returns |param|'s verification flags. -OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags( - const X509_VERIFY_PARAM *param); - -// X509_VERIFY_PARAM_set_depth configures |param| to limit certificate chains to -// |depth| intermediate certificates. This count excludes both the target -// certificate and the trust anchor (root certificate). -OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, - int depth); - -// X509_VERIFY_PARAM_set_time configures certificate verification to use |t| -// instead of the current time. -OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, - time_t t); - -// X509_VERIFY_PARAM_set_time_posix configures certificate verification to use -// |t| instead of the current time. |t| is interpreted as a POSIX timestamp in -// seconds. -OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, - int64_t t); - -// X509_VERIFY_PARAM_add0_policy adds |policy| to the user-initial-policy-set -// (see Section 6.1.1 of RFC 5280). On success, it takes ownership of -// |policy| and returns one. Otherwise, it returns zero and the caller retains -// owneship of |policy|. -OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, - ASN1_OBJECT *policy); - -// X509_VERIFY_PARAM_set1_policies sets the user-initial-policy-set (see -// Section 6.1.1 of RFC 5280) to a copy of |policies|. It returns one on success -// and zero on error. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( - X509_VERIFY_PARAM *param, const STACK_OF(ASN1_OBJECT) *policies); - -// X509_VERIFY_PARAM_set1_host configures |param| to check for the DNS name -// specified by |name| and clears any previously specified hostname. If |name| -// is NULL or empty, the list of hostnames is cleared and name checks are not -// performed on the peer certificate. It returns one on success and zero on -// error. -// |namelen| should be set to the length of |name|. It may be zero if |name| is -// NUL-terminated, but this is only maintained for backwards compatibility with -// OpenSSL. -// -// By default, both subject alternative names and the subject's common name -// attribute are checked. The latter has long been deprecated, so callers should -// call |X509_VERIFY_PARAM_set_hostflags| with -// |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| to use the standard behavior. -// https://crbug.com/boringssl/464 tracks fixing the default. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, - size_t namelen); - -// X509_VERIFY_PARAM_add1_host adds |name| to the list of names checked by -// |param|. If any configured DNS name matches the certificate, verification -// succeeds. Any previous names set via |X509_VERIFY_PARAM_set1_host| or -// |X509_VERIFY_PARAM_add1_host| are retained, no change is made if |name| is -// NULL or empty. When multiple names are configured, the peer is considered -// verified when any name matches. It returns one on success and zero on error. -// |namelen| should be set to the length of |name|. It may be zero if |name| is -// NUL-terminated, but this is only maintained for backwards compatibility with -// OpenSSL. -// -// By default, both subject alternative names and the subject's common name -// attribute are checked. The latter has long been deprecated, so callers should -// call |X509_VERIFY_PARAM_set_hostflags| with -// |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| to use the standard behavior. -// https://crbug.com/boringssl/464 tracks fixing the default. -OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, - size_t name_len); - -// X509_VERIFY_PARAM_set_hostflags sets the name-checking flags on |param| to -// |flags|. |flags| should be a combination of |X509_CHECK_FLAG_*| constants. -OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags); - -// X509_VERIFY_PARAM_set1_email configures |param| to check for the email -// address specified by |email|. It returns one on success and zero on error. -// |emaillen| should be set to the length of |email|. It may be zero if |email| -// is NUL-terminated, but this is only maintained for backwards compatibility -// with OpenSSL. -// -// By default, both subject alternative names and the subject's email address -// attribute are checked. The |X509_CHECK_FLAG_NEVER_CHECK_SUBJECT| flag may be -// used to change this behavior. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, - const char *email, - size_t emaillen); - -// X509_VERIFY_PARAM_set1_ip configures |param| to check for the IP address -// specified by |ip|. It returns one on success and zero on error. The IP -// address is specified in its binary representation. |ip_len| must be 4 for an -// IPv4 address and 16 for an IPv6 address. -// NOTE:|iplen| MUST be set to the length of |ip|. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, - size_t iplen); - -// X509_VERIFY_PARAM_set1_ip_asc decodes |ipasc| as the ASCII representation of -// an IPv4 or IPv6 address, and configures |param| to check for it. It returns -// one on success and zero on error. -// |ipasc| MUST be a NUL-terminal ASCII string: dotted decimal quad for IPv4 and -// colon-separated hexadecimal for IPv6. The condensed "::" notation is -// supported for IPv6 addresses. -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, - const char *ipasc); - -// X509_VERIFY_PARAM_get_depth returns the maximum depth configured in |param|. -// See |X509_VERIFY_PARAM_set_depth|. -OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); typedef void *(*X509V3_EXT_NEW)(void); typedef void (*X509V3_EXT_FREE)(void *); @@ -5037,45 +5074,6 @@ OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *); -// X509_check_* functions -// -// See https://www.openssl.org/docs/manmaster/man3/X509_check_host.html -// for more details. - -// X509_CHECK_FLAG_NO_WILDCARDS disables wildcard matching for dnsName fields -// and common name. This only applies to |X509_check_host|. -#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 - -// X509_CHECK_FLAG_NEVER_CHECK_SUBJECT skips the subject common name fallback -// if subjectAltNames is missing. -#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 - -// X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS does nothing, but is necessary in -// OpenSSL to enable standard wildcard matching. In AWS-LC, this behavior is -// always enabled. This only applies to |X509_check_host| in OpenSSL. -#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 - -// X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT is deprecated and does nothing. -// Enabling this in OpenSSL considers the subject DN even if the certificate -// contains at least one subject alternative name of the right type; the -// default is to ignore the subject DN when at least one corresponding subject -// alternative names is present. -#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 - -// X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS is deprecated and does nothing. -// This only applies to |X509_check_host|. When used in OpenSSL, it allows a -// "*" that constitutes the complete label of a DNS name (e.g. -// "*.example.com") to match more than one label in |chk|. -#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0 - -// X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS is deprecated and does nothing. -// This only applies to |X509_check_host|. When used in OpenSSL, it -// restricts name values which start with ".", that would otherwise match -// any sub-domain in the peer certificate, to only match direct child -// sub-domains. -#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0 - - #if defined(__cplusplus) } // extern C #endif diff --git a/tests/ci/run_openssl_comparison_tests.sh b/tests/ci/run_openssl_comparison_tests.sh old mode 100644 new mode 100755 index 6d6d3b11e4..e82338e4fb --- a/tests/ci/run_openssl_comparison_tests.sh +++ b/tests/ci/run_openssl_comparison_tests.sh @@ -39,10 +39,7 @@ declare -A openssl_branches=( export AWSLC_TOOL_PATH="${BUILD_ROOT}/tool-openssl/openssl" for branch in "${!openssl_branches[@]}"; do export OPENSSL_TOOL_PATH="${install_dir}/openssl-${branch}/bin/openssl" - LD_LIBRARY_PATH="${install_dir}/openssl-${branch}/${openssl_branches[$branch]}" - for test in X509ComparisonTest RSAComparisonTest MD5ComparisonTest; do - echo "Running ${test} against OpenSSL ${branch}" - LD_LIBRARY_PATH="${install_dir}/openssl-${branch}/${openssl_branches[$branch]}" "${BUILD_ROOT}/tool-openssl/tool_openssl_test" --gtest_filter=${test}.* - done + echo "Running ${test} against OpenSSL ${branch}" + LD_LIBRARY_PATH="${install_dir}/openssl-${branch}/${openssl_branches[$branch]}" "${BUILD_ROOT}/tool-openssl/tool_openssl_test" done diff --git a/tests/ci/run_posix_tests.sh b/tests/ci/run_posix_tests.sh index 46eb8904b9..3e0b3c4195 100755 --- a/tests/ci/run_posix_tests.sh +++ b/tests/ci/run_posix_tests.sh @@ -35,6 +35,9 @@ build_and_test -DTEST_SYSGENID_PATH="${TEST_SYSGENID_PATH}" echo "Testing with pre-generated assembly code." build_and_test -DDISABLE_PERL=ON +echo "Testing building with AArch64 Data-Independent Timing (DIT) on." +build_and_test -DENABLE_DATA_INDEPENDENT_TIMING_AARCH64=ON -DCMAKE_BUILD_TYPE=Release + if [[ "${AWSLC_C99_TEST}" == "1" ]]; then echo "Testing the C99 compatability of AWS-LC headers." ./tests/coding_guidelines/c99_gcc_test.sh diff --git a/tests/ci/run_windows_tests.bat b/tests/ci/run_windows_tests.bat index b8d08f8f67..0edf144ee5 100644 --- a/tests/ci/run_windows_tests.bat +++ b/tests/ci/run_windows_tests.bat @@ -38,6 +38,13 @@ call :build_and_test Release "-DBUILD_SHARED_LIBS=1" || goto error call :build_and_test Release "-DBUILD_SHARED_LIBS=1 -DFIPS=1" || goto error @rem For FIPS on Windows we also have a RelWithDebInfo build to generate debug symbols. call :build_and_test RelWithDebInfo "-DBUILD_SHARED_LIBS=1 -DFIPS=1" || goto error + +@rem On Windows, CMake defaults to dynamically linking to the Windows C-runtime. +@rem We test statically linking CRT to our static library. +call :build_and_test Release "-DBUILD_SHARED_LIBS=0 -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded" || goto error +@rem For shared libraries, static CRT should not be used to avoid passing CRT objects across DLL boundaries: +@rem https://learn.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries?view=msvc-170 + exit /b 0 :run_sde_tests diff --git a/tests/ci/setup.py b/tests/ci/setup.py index f339245627..90a72de56e 100644 --- a/tests/ci/setup.py +++ b/tests/ci/setup.py @@ -23,7 +23,7 @@ "aws-cdk-lib==2.74.0", "constructs==10.1.314", # PyYAML is a YAML parser and emitter for Python. Used to read build_spec.yaml. - "pyyaml==6.0", + "pyyaml==6.0.1", # A formatter for Python code. "yapf==0.30.0", # Introduced by benchmark framework. diff --git a/tool-openssl/CMakeLists.txt b/tool-openssl/CMakeLists.txt index 595cc29089..9daac52077 100644 --- a/tool-openssl/CMakeLists.txt +++ b/tool-openssl/CMakeLists.txt @@ -1,12 +1,14 @@ add_executable( - openssl + openssl - ../tool/args.cc - ../tool/file.cc - tool.cc - x509.cc - rsa.cc - md5.cc + ../tool/args.cc + ../tool/file.cc + ../tool/fd.cc + + dgst.cc + rsa.cc + tool.cc + x509.cc ) target_include_directories(openssl PUBLIC ${PROJECT_SOURCE_DIR}/include) @@ -43,16 +45,19 @@ endif() if(BUILD_TESTING) add_executable( - tool_openssl_test - - ../tool/args.cc - ../tool/file.cc - x509_test.cc - rsa_test.cc - md5_test.cc - x509.cc - rsa.cc - md5.cc + tool_openssl_test + + ../tool/args.cc + ../tool/file.cc + ../tool/fd.cc + ../crypto/test/test_util.cc + + dgst.cc + dgst_test.cc + rsa.cc + rsa_test.cc + x509.cc + x509_test.cc ) target_link_libraries(tool_openssl_test boringssl_gtest_main ssl crypto) diff --git a/tool-openssl/dgst.cc b/tool-openssl/dgst.cc new file mode 100644 index 0000000000..ce4a5c5ba6 --- /dev/null +++ b/tool-openssl/dgst.cc @@ -0,0 +1,220 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include +#include +#include + +#include +#include +#include "internal.h" + +// MD5 command currently only supports stdin +static const argument_t kArguments[] = { + {"-help", kBooleanArgument, "Display option summary"}, + {"-hmac", kOptionalArgument, + "Create a hashed MAC with the corresponding key"}, + {"", kOptionalArgument, ""}}; + +static bool dgst_file_op(const std::string &filename, const int fd, + const EVP_MD *digest) { + static const size_t kBufSize = 8192; + std::unique_ptr buf(new uint8_t[kBufSize]); + + bssl::ScopedEVP_MD_CTX ctx; + if (!EVP_DigestInit_ex(ctx.get(), digest, nullptr)) { + fprintf(stderr, "Failed to initialize EVP_MD_CTX.\n"); + return false; + } + + for (;;) { + size_t n; + if (!ReadFromFD(fd, &n, buf.get(), kBufSize)) { + fprintf(stderr, "Failed to read from %s: %s\n", filename.c_str(), + strerror(errno)); + return false; + } + + if (n == 0) { + break; + } + + if (!EVP_DigestUpdate(ctx.get(), buf.get(), n)) { + fprintf(stderr, "Failed to update hash.\n"); + return false; + } + } + + uint8_t hash[EVP_MAX_MD_SIZE]; + unsigned hash_len; + if (!EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) { + fprintf(stderr, "Failed to finish hash.\n"); + return false; + } + + // Print digest output. OpenSSL outputs the digest name with files, but not + // with stdin. + if (fd != 0) { + fprintf(stdout, "%s(%s)= ", EVP_MD_get0_name(digest), filename.c_str()); + } else { + fprintf(stdout, "(%s)= ", filename.c_str()); + }; + for (size_t i = 0; i < hash_len; i++) { + fprintf(stdout, "%02x", hash[i]); + } + fprintf(stdout, "\n"); + return true; +} + +static bool hmac_file_op(const std::string &filename, const int fd, + const EVP_MD *digest, const char *hmac_key, + const size_t hmac_key_len) { + static const size_t kBufSize = 8192; + std::unique_ptr buf(new uint8_t[kBufSize]); + + bssl::ScopedHMAC_CTX ctx; + if (!HMAC_Init_ex(ctx.get(), hmac_key, hmac_key_len, digest, nullptr)) { + fprintf(stderr, "Failed to initialize HMAC_Init_ex.\n"); + return false; + } + + // Update |buf| from file continuously. + for (;;) { + size_t n; + if (!ReadFromFD(fd, &n, buf.get(), kBufSize)) { + fprintf(stderr, "Failed to read from %s: %s\n", filename.c_str(), + strerror(errno)); + return false; + } + + if (n == 0) { + break; + } + + if (!HMAC_Update(ctx.get(), buf.get(), n)) { + fprintf(stderr, "Failed to update HMAC.\n"); + return false; + } + } + + const unsigned expected_mac_len = EVP_MD_size(digest); + std::unique_ptr mac(new uint8_t[expected_mac_len]); + unsigned mac_len; + if (!HMAC_Final(ctx.get(), mac.get(), &mac_len)) { + fprintf(stderr, "Failed to finalize HMAC.\n"); + return false; + } + + // Print HMAC output. OpenSSL outputs the digest name with files, but not + // with stdin. + if (fd != 0) { + fprintf(stdout, "HMAC-%s(%s)= ", EVP_MD_get0_name(digest), + filename.c_str()); + } else { + fprintf(stdout, "(%s)= ", filename.c_str()); + }; + for (size_t i = 0; i < expected_mac_len; i++) { + fprintf(stdout, "%02x", mac[i]); + } + fprintf(stdout, "\n"); + return true; +} + +static bool dgst_tool_op(const args_list_t &args, const EVP_MD *digest) { + std::vector file_inputs; + + // Default is SHA-256. + // TODO: Make this customizable when "-digest" is introduced. + if (digest == nullptr) { + digest = EVP_sha256(); + } + + // HMAC keys can be empty, but C++ std::string has no way to differentiate + // between null and empty. + const char *hmac_key = nullptr; + size_t hmac_key_len = 0; + + auto it = args.begin(); + while (it != args.end()) { + const std::string &arg = *it; + if (!arg.empty() && arg[0] != '-') { + // Any input without a '-' prefix is parsed as a file. This + // also marks the end of any option input. + while (it != args.end()) { + if (!(*it).empty()) { + file_inputs.push_back(*it); + } + it++; + } + break; + } + + if (!arg.empty() && arg[0] == '-') { + const std::string option = arg.substr(1); + if (option == "help") { + PrintUsage(kArguments); + return false; + } else if (option == "hmac") { + // Read next argument as key string. + it++; + // HMAC allows for empty keys. + if (it != args.end()) { + hmac_key = (*it).c_str(); + hmac_key_len = (*it).length(); + } else { + fprintf(stderr, + "dgst: Option -hmac needs a value\n" + "dgst: Use -help for summary.\n"); + return false; + } + } else { + fprintf(stderr, "Unknown option '%s'.\n", option.c_str()); + return false; + } + } else { + // Empty input. OpenSSL continues processing the next file even when + // provided an invalid file. + fprintf(stderr, "Failed to read from empty input."); + } + + // Increment while loop. + it++; + } + + // Use stdin if no files are provided. + if (file_inputs.empty()) { + // 0 denotes stdin. + std::string file_name = "stdin"; + int fd = 0; + if (hmac_key) { + if (!hmac_file_op(file_name, fd, digest, hmac_key, hmac_key_len)) { + return false; + } + } else { + if (!dgst_file_op(file_name, fd, digest)) { + return false; + } + } + return true; + } + + // Do the dgst operation on all file inputs. + for (const auto &file_name : file_inputs) { + ScopedFD scoped_fd = OpenFD(file_name.c_str(), O_RDONLY | O_BINARY); + int fd = scoped_fd.get(); + if (hmac_key) { + if (!hmac_file_op(file_name, fd, digest, hmac_key, hmac_key_len)) { + return false; + } + } else { + if (!dgst_file_op(file_name, fd, digest)) { + return false; + } + } + } + + return true; +} + +bool dgstTool(const args_list_t &args) { return dgst_tool_op(args, nullptr); } +bool md5Tool(const args_list_t &args) { return dgst_tool_op(args, EVP_md5()); } diff --git a/tool-openssl/dgst_test.cc b/tool-openssl/dgst_test.cc new file mode 100644 index 0000000000..0ef6743fa5 --- /dev/null +++ b/tool-openssl/dgst_test.cc @@ -0,0 +1,200 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include +#include +#include "../crypto/test/test_util.h" +#include "test_util.h" + +// -------------------- MD5 OpenSSL Comparison Test --------------------------- + +// Comparison tests cannot run without set up of environment variables: +// AWSLC_TOOL_PATH and OPENSSL_TOOL_PATH. + +class DgstComparisonTest : public ::testing::Test { + protected: + void SetUp() override { + // Skip gtests if env variables not set + awslc_executable_path = getenv("AWSLC_TOOL_PATH"); + openssl_executable_path = getenv("OPENSSL_TOOL_PATH"); + if (awslc_executable_path == nullptr || + openssl_executable_path == nullptr) { + GTEST_SKIP() << "Skipping test: AWSLC_TOOL_PATH and/or OPENSSL_TOOL_PATH " + "environment variables are not set"; + } + ASSERT_GT(createTempFILEpath(in_path), 0u); + ASSERT_GT(createTempFILEpath(out_path_awslc), 0u); + ASSERT_GT(createTempFILEpath(out_path_openssl), 0u); + } + void TearDown() override { + if (awslc_executable_path != nullptr && + openssl_executable_path != nullptr) { + // RemoveFile(in_path); + RemoveFile(out_path_awslc); + RemoveFile(out_path_openssl); + } + } + char in_path[PATH_MAX]; + char out_path_awslc[PATH_MAX]; + char out_path_openssl[PATH_MAX]; + const char *awslc_executable_path; + const char *openssl_executable_path; + std::string awslc_output_str; + std::string openssl_output_str; +}; + +// OpenSSL versions 3.1.0 and later change from "(stdin)= " to "MD5(stdin) =" +std::string GetHash(const std::string &str) { + size_t pos = str.find('='); + if (pos == std::string::npos) { + return ""; + } + return str.substr(pos + 1); +} + +// Test against OpenSSL output for "-hmac" +TEST_F(DgstComparisonTest, HMAC_default_files) { + std::string input_file = std::string(in_path); + std::ofstream ofs(input_file); + ofs << "AWS_LC_TEST_STRING_INPUT"; + ofs.close(); + + // Run -hmac against a single file. + std::string awslc_command = std::string(awslc_executable_path) + + " dgst -hmac test_key_string " + input_file + + " > " + out_path_awslc; + std::string openssl_command = std::string(openssl_executable_path) + + " dgst -hmac test_key_string " + input_file + + " > " + out_path_openssl; + + RunCommandsAndCompareOutput(awslc_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + std::string awslc_hash = GetHash(awslc_output_str); + std::string openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(awslc_hash, openssl_hash); + + // Run -hmac again against multiple files. + char in_path2[PATH_MAX]; + ASSERT_GT(createTempFILEpath(in_path2), 0u); + std::string input_file2 = std::string(in_path2); + ofs.open(input_file2); + ofs << "AWS_LC_TEST_STRING_INPUT_2"; + ofs.close(); + + awslc_command = std::string(awslc_executable_path) + + " dgst -hmac alternative_key_string " + input_file + " " + + input_file2 + " > " + out_path_awslc; + openssl_command = std::string(openssl_executable_path) + + " dgst -hmac alternative_key_string " + input_file + " " + + input_file2 + +" > " + out_path_openssl; + + RunCommandsAndCompareOutput(awslc_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + awslc_hash = GetHash(awslc_output_str); + openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(awslc_hash, openssl_hash); + + // Run -hmac with empty key + awslc_command = std::string(awslc_executable_path) + + " dgst -hmac \"\" " + " " + + input_file + " " + input_file2 + " > " + out_path_awslc; + openssl_command = std::string(openssl_executable_path) + " dgst -hmac \"\" " + + input_file + " " + input_file2 + +" > " + out_path_openssl; + + RunCommandsAndCompareOutput(awslc_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + awslc_hash = GetHash(awslc_output_str); + openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(awslc_hash, openssl_hash); + + RemoveFile(input_file.c_str()); + RemoveFile(input_file2.c_str()); +} + + +TEST_F(DgstComparisonTest, HMAC_default_stdin) { + std::string tool_command = "echo hmac_this_string | " + + std::string(awslc_executable_path) + + " dgst -hmac key > " + out_path_awslc; + std::string openssl_command = "echo hmac_this_string | " + + std::string(openssl_executable_path) + + " dgst -hmac key > " + out_path_openssl; + + RunCommandsAndCompareOutput(tool_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + std::string tool_hash = GetHash(awslc_output_str); + std::string openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(tool_hash, openssl_hash); +} + +TEST_F(DgstComparisonTest, MD5_files) { + std::string input_file = std::string(in_path); + std::ofstream ofs(input_file); + ofs << "AWS_LC_TEST_STRING_INPUT"; + ofs.close(); + + // Input file as pipe (stdin) + std::string tool_command = std::string(awslc_executable_path) + " md5 < " + + input_file + " > " + out_path_awslc; + std::string openssl_command = std::string(openssl_executable_path) + + " md5 < " + input_file + " > " + + out_path_openssl; + + RunCommandsAndCompareOutput(tool_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + std::string tool_hash = GetHash(awslc_output_str); + std::string openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(tool_hash, openssl_hash); + + // Input file as regular command line option. + tool_command = std::string(awslc_executable_path) + " md5 " + input_file + + " > " + out_path_awslc; + openssl_command = std::string(openssl_executable_path) + " md5 " + + input_file + " > " + out_path_openssl; + + RunCommandsAndCompareOutput(tool_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + tool_hash = GetHash(awslc_output_str); + openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(tool_hash, openssl_hash); + + RemoveFile(input_file.c_str()); +} + +// Test against OpenSSL output with stdin. +TEST_F(DgstComparisonTest, MD5_stdin) { + std::string tool_command = "echo hash_this_string | " + + std::string(awslc_executable_path) + " md5 > " + + out_path_awslc; + std::string openssl_command = "echo hash_this_string | " + + std::string(openssl_executable_path) + + " md5 > " + out_path_openssl; + + RunCommandsAndCompareOutput(tool_command, openssl_command, out_path_awslc, + out_path_openssl, awslc_output_str, + openssl_output_str); + + std::string tool_hash = GetHash(awslc_output_str); + std::string openssl_hash = GetHash(openssl_output_str); + + EXPECT_EQ(tool_hash, openssl_hash); +} diff --git a/tool-openssl/internal.h b/tool-openssl/internal.h index 153c805f9d..3d4e48c8ce 100644 --- a/tool-openssl/internal.h +++ b/tool-openssl/internal.h @@ -8,10 +8,17 @@ #include #include - +#if !defined(O_BINARY) +#define O_BINARY 0 +#endif typedef bool (*tool_func_t)(const std::vector &args); +struct Tool { + const char *name; + tool_func_t func; +}; + bool IsNumeric(const std::string& str); X509* CreateAndSignX509Certificate(); @@ -23,8 +30,9 @@ bool LoadPrivateKeyAndSignCertificate(X509 *x509, const std::string &signkey_pat tool_func_t FindTool(const std::string &name); tool_func_t FindTool(int argc, char **argv, int &starting_arg); -bool X509Tool(const args_list_t &args); -bool rsaTool(const args_list_t &args); +bool dgstTool(const args_list_t &args); bool md5Tool(const args_list_t &args); +bool rsaTool(const args_list_t &args); +bool X509Tool(const args_list_t &args); #endif //INTERNAL_H diff --git a/tool-openssl/md5.cc b/tool-openssl/md5.cc deleted file mode 100644 index 74333f7144..0000000000 --- a/tool-openssl/md5.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC - -#include -#include -#include "internal.h" - -// MD5 command currently only supports stdin -static const argument_t kArguments[] = { - { "-help", kBooleanArgument, "Display option summary" }, - { "", kOptionalArgument, "" } -}; - -// Map arguments using tool/args.cc -bool md5Tool(const args_list_t &args) { - args_map_t parsed_args; - if (!ParseKeyValueArguments(&parsed_args, args, kArguments)) { - PrintUsage(kArguments); - return false; - } - - bool help = false; - GetBoolArgument(&help, "-help", parsed_args); - - if (help) { - PrintUsage(kArguments); - return false; - } - - // Read input from stdin - std::string input; - std::getline(std::cin, input); - - if (input.empty()) { - fprintf(stderr, "Error: no input provided\n"); - return false; - } - - unsigned char md5_digest[MD5_DIGEST_LENGTH]; - MD5(reinterpret_cast(input.c_str()), input.length(), md5_digest); - - printf("(stdin)= "); - for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { - printf("%02x", md5_digest[i]); - } - printf("\n"); - - return true; -} - diff --git a/tool-openssl/md5_test.cc b/tool-openssl/md5_test.cc deleted file mode 100644 index 061fb3a8cc..0000000000 --- a/tool-openssl/md5_test.cc +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 OR ISC - -#include -#include -#include "internal.h" -#include "test_util.h" -#include - - -#ifdef _WIN32 -#include -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif -#else -#include -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif -#endif - -size_t createTempFILEpath(char buffer[PATH_MAX]); - -std::string GetHash(const std::string& str); - - -// -------------------- MD5 OpenSSL Comparison Test --------------------------- - -// Comparison tests cannot run without set up of environment variables: -// AWSLC_TOOL_PATH and OPENSSL_TOOL_PATH. - -class MD5ComparisonTest : public ::testing::Test { -protected: - void SetUp() override { - - // Skip gtests if env variables not set - tool_executable_path = getenv("AWSLC_TOOL_PATH"); - openssl_executable_path = getenv("OPENSSL_TOOL_PATH"); - if (tool_executable_path == nullptr || openssl_executable_path == nullptr) { - GTEST_SKIP() << "Skipping test: AWSLC_TOOL_PATH and/or OPENSSL_TOOL_PATH environment variables are not set"; - } - ASSERT_GT(createTempFILEpath(in_path), 0u); - ASSERT_GT(createTempFILEpath(out_path_tool), 0u); - ASSERT_GT(createTempFILEpath(out_path_openssl), 0u); - } - void TearDown() override { - if (tool_executable_path != nullptr && openssl_executable_path != nullptr) { - RemoveFile(in_path); - RemoveFile(out_path_tool); - RemoveFile(out_path_openssl); - } - } - char in_path[PATH_MAX]; - char out_path_tool[PATH_MAX]; - char out_path_openssl[PATH_MAX]; - bssl::UniquePtr rsa; - const char* tool_executable_path; - const char* openssl_executable_path; - std::string tool_output_str; - std::string openssl_output_str; -}; - -// OpenSSL versions 3.1.0 and later change from "(stdin)= " to "MD5(stdin) =" -std::string GetHash(const std::string& str) { - size_t pos = str.find('='); - if (pos == std::string::npos) { - return ""; - } - return str.substr(pos + 1); -} - -// Test against OpenSSL output -TEST_F(MD5ComparisonTest, MD5ToolCompareOpenSSL) { - std::string input_file = std::string(in_path); - std::ofstream ofs(input_file); - ofs << "AWS_LC_TEST_STRING_INPUT"; - ofs.close(); - - std::string tool_command = std::string(tool_executable_path) + " md5 < " + input_file + " > " + out_path_tool; - std::string openssl_command = std::string(openssl_executable_path) + " md5 < " + input_file + " > " + out_path_openssl; - - RunCommandsAndCompareOutput(tool_command, openssl_command, out_path_tool, out_path_openssl, tool_output_str, openssl_output_str); - - std::string tool_hash = GetHash(tool_output_str); - std::string openssl_hash = GetHash(openssl_output_str); - tool_hash = trim(tool_hash); - openssl_hash = trim(openssl_hash); - - ASSERT_EQ(tool_hash, openssl_hash); - - RemoveFile(input_file.c_str()); -} diff --git a/tool-openssl/rsa_test.cc b/tool-openssl/rsa_test.cc index 10fba1e09f..986821d07a 100644 --- a/tool-openssl/rsa_test.cc +++ b/tool-openssl/rsa_test.cc @@ -6,22 +6,7 @@ #include #include "internal.h" #include "test_util.h" -#include - - -#ifdef _WIN32 -#include -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif -#else -#include -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif -#endif - -size_t createTempFILEpath(char buffer[PATH_MAX]); +#include "../crypto/test/test_util.h" bool CheckBoundaries(const std::string &content, const std::string &begin1, const std::string &end1, const std::string &begin2, const std::string &end2); diff --git a/tool-openssl/test_util.h b/tool-openssl/test_util.h index 0792f4ca0c..7c9036b29e 100644 --- a/tool-openssl/test_util.h +++ b/tool-openssl/test_util.h @@ -64,4 +64,7 @@ inline void RemoveFile(const char* path) { } } +// OpenSSL versions 3.1.0 and later change from "(stdin)= " to "MD5(stdin) =" +std::string GetHash(const std::string& str); + #endif //TEST_UTIL_H diff --git a/tool-openssl/tool.cc b/tool-openssl/tool.cc index 983f43fe55..469f1ea473 100644 --- a/tool-openssl/tool.cc +++ b/tool-openssl/tool.cc @@ -1,9 +1,9 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC +#include #include #include -#include #if defined(OPENSSL_WINDOWS) #include @@ -15,24 +15,18 @@ #include "./internal.h" -typedef bool (*tool_func_t)(const std::vector &args); - -struct Tool { - const char *name; - tool_func_t func; -}; - -static const std::array kTools = {{ -{ "x509", X509Tool }, -{"rsa", rsaTool}, -{"md5", md5Tool}, +static const std::array kTools = {{ + {"dgst", dgstTool}, + {"md5", md5Tool}, + {"rsa", rsaTool}, + {"x509", X509Tool}, }}; static void usage(const std::string &name) { std::cout << "Usage: " << name << " COMMAND\n\n"; std::cout << "Available commands:\n"; - for (const auto& tool : kTools) { + for (const auto &tool : kTools) { if (tool.func == nullptr) { break; } @@ -67,7 +61,7 @@ static void initialize() { } tool_func_t FindTool(const std::string &name) { - for (const auto& tool : kTools) { + for (const auto &tool : kTools) { if (tool.name == name) { return tool.func; } @@ -96,6 +90,7 @@ int main(int argc, char **argv) { int starting_arg = 1; tool_func_t tool = FindTool(argc, argv, starting_arg); + // Print help option menu. if (tool == nullptr) { usage(argv[0]); return 1; diff --git a/tool-openssl/x509_test.cc b/tool-openssl/x509_test.cc index 9c1ae0ce95..a50383044a 100644 --- a/tool-openssl/x509_test.cc +++ b/tool-openssl/x509_test.cc @@ -6,23 +6,10 @@ #include #include "internal.h" #include "test_util.h" +#include "../crypto/test/test_util.h" #include -#ifdef _WIN32 -#include -#ifndef PATH_MAX -#define PATH_MAX MAX_PATH -#endif -#else -#include -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif -#endif - -size_t createTempFILEpath(char buffer[PATH_MAX]); - X509* CreateAndSignX509Certificate() { bssl::UniquePtr x509(X509_new()); if (!x509) return nullptr; diff --git a/tool/speed.cc b/tool/speed.cc index fde748495f..3e8ef0b636 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -82,6 +82,11 @@ static inline void *align_pointer(void *ptr, size_t alignment) { } #endif +#if defined(OPENSSL_IS_AWSLC) && defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS) && \ + defined(MAKE_DIT_AVAILABLE) +#define DIT_OPTION +#endif + static inline void *BM_memset(void *dst, int c, size_t n) { if (n == 0) { return dst; @@ -93,6 +98,11 @@ static inline void *BM_memset(void *dst, int c, size_t n) { // g_print_json is true if printed output is JSON formatted. static bool g_print_json = false; +#if defined(DIT_OPTION) +// g_dit is true if the DIT macro is to be enabled before benchmarking +static bool g_dit = false; +#endif + static std::string ChunkLenSuffix(size_t chunk_len) { char buf[32]; snprintf(buf, sizeof(buf), " (%zu byte%s)", chunk_len, @@ -2531,6 +2541,14 @@ static const argument_t kArguments[] = { "there is no information about the bytes per call for an operation, " "the JSON field for bytesPerCall will be omitted.", }, +#if defined(DIT_OPTION) + { + "-dit", + kBooleanArgument, + "If this flag is set, the DIT flag is enabled before benchmarking and" + "disabled at the end." + }, +#endif { "", kOptionalArgument, @@ -2606,6 +2624,12 @@ bool Speed(const std::vector &args) { } } +#if defined(DIT_OPTION) + if (args_map.count("-dit") != 0) { + g_dit = true; + } +#endif + if (args_map.count("-json") != 0) { g_print_json = true; } @@ -2657,6 +2681,13 @@ bool Speed(const std::vector &args) { return false; } } +#if defined(DIT_OPTION) + uint64_t original_dit = 0; + if (g_dit) + { + original_dit = armv8_enable_dit(); + } +#endif // kTLSADLen is the number of bytes of additional data that TLS passes to // AEADs. @@ -2806,5 +2837,11 @@ bool Speed(const std::vector &args) { puts("\n]"); } +#if defined(DIT_OPTION ) + if (g_dit) + { + armv8_restore_dit(&original_dit); + } +#endif return true; }